// SPDX-License-Identifier: MIT
// Copyright (C) 2018-present iced project and contributors

// ⚠️This file was generated by GENERATOR!🦹‍♂️

use crate::code_asm::op_state::CodeAsmOpState;
use crate::Register;

/// All 8-bit general purpose registers.
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::gpr8::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
#[repr(transparent)]
pub struct AsmRegister8 {
	register: Register,
}

#[rustfmt::skip]
impl AsmRegister8 {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}
}

#[rustfmt::skip]
impl From<AsmRegister8> for Register {
	#[inline]
	fn from(reg: AsmRegister8) -> Self {
		reg.register
	}
}

/// All 16-bit general purpose registers.
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::gpr16::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
#[repr(transparent)]
pub struct AsmRegister16 {
	register: Register,
}

#[rustfmt::skip]
impl AsmRegister16 {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}
}

#[rustfmt::skip]
impl From<AsmRegister16> for Register {
	#[inline]
	fn from(reg: AsmRegister16) -> Self {
		reg.register
	}
}

/// All 32-bit general purpose registers.
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::gpr32::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
pub struct AsmRegister32 {
	register: Register,
	state: CodeAsmOpState,
}

#[rustfmt::skip]
impl AsmRegister32 {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register, state: CodeAsmOpState::new() }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}

	#[must_use]
	#[inline]
	pub(crate) fn state(&self) -> CodeAsmOpState {
		self.state
	}

	/// Adds a `{k1}` opmask register
	#[must_use]
	#[inline]
	pub fn k1(mut self) -> Self {
		self.state.set_k1();
		self
	}

	/// Adds a `{k2}` opmask register
	#[must_use]
	#[inline]
	pub fn k2(mut self) -> Self {
		self.state.set_k2();
		self
	}

	/// Adds a `{k3}` opmask register
	#[must_use]
	#[inline]
	pub fn k3(mut self) -> Self {
		self.state.set_k3();
		self
	}

	/// Adds a `{k4}` opmask register
	#[must_use]
	#[inline]
	pub fn k4(mut self) -> Self {
		self.state.set_k4();
		self
	}

	/// Adds a `{k5}` opmask register
	#[must_use]
	#[inline]
	pub fn k5(mut self) -> Self {
		self.state.set_k5();
		self
	}

	/// Adds a `{k6}` opmask register
	#[must_use]
	#[inline]
	pub fn k6(mut self) -> Self {
		self.state.set_k6();
		self
	}

	/// Adds a `{k7}` opmask register
	#[must_use]
	#[inline]
	pub fn k7(mut self) -> Self {
		self.state.set_k7();
		self
	}

	/// Enables zeroing masking `{z}`
	#[must_use]
	#[inline]
	pub fn z(mut self) -> Self {
		self.state.set_zeroing_masking();
		self
	}

	/// Enables suppress all exceptions `{sae}`
	#[must_use]
	#[inline]
	pub fn sae(mut self) -> Self {
		self.state.set_suppress_all_exceptions();
		self
	}

	/// Round to nearest (even)
	#[must_use]
	#[inline]
	pub fn rn_sae(mut self) -> Self {
		self.state.rn_sae();
		self
	}

	/// Round down (toward -inf)
	#[must_use]
	#[inline]
	pub fn rd_sae(mut self) -> Self {
		self.state.rd_sae();
		self
	}

	/// Round up (toward +inf)
	#[must_use]
	#[inline]
	pub fn ru_sae(mut self) -> Self {
		self.state.ru_sae();
		self
	}

	/// Round toward zero (truncate)
	#[must_use]
	#[inline]
	pub fn rz_sae(mut self) -> Self {
		self.state.rz_sae();
		self
	}
}

#[rustfmt::skip]
impl From<AsmRegister32> for Register {
	#[inline]
	fn from(reg: AsmRegister32) -> Self {
		reg.register
	}
}

/// All 64-bit general purpose registers.
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::gpr64::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
pub struct AsmRegister64 {
	register: Register,
	state: CodeAsmOpState,
}

#[rustfmt::skip]
impl AsmRegister64 {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register, state: CodeAsmOpState::new() }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}

	#[must_use]
	#[inline]
	pub(crate) fn state(&self) -> CodeAsmOpState {
		self.state
	}

	/// Adds a `{k1}` opmask register
	#[must_use]
	#[inline]
	pub fn k1(mut self) -> Self {
		self.state.set_k1();
		self
	}

	/// Adds a `{k2}` opmask register
	#[must_use]
	#[inline]
	pub fn k2(mut self) -> Self {
		self.state.set_k2();
		self
	}

	/// Adds a `{k3}` opmask register
	#[must_use]
	#[inline]
	pub fn k3(mut self) -> Self {
		self.state.set_k3();
		self
	}

	/// Adds a `{k4}` opmask register
	#[must_use]
	#[inline]
	pub fn k4(mut self) -> Self {
		self.state.set_k4();
		self
	}

	/// Adds a `{k5}` opmask register
	#[must_use]
	#[inline]
	pub fn k5(mut self) -> Self {
		self.state.set_k5();
		self
	}

	/// Adds a `{k6}` opmask register
	#[must_use]
	#[inline]
	pub fn k6(mut self) -> Self {
		self.state.set_k6();
		self
	}

	/// Adds a `{k7}` opmask register
	#[must_use]
	#[inline]
	pub fn k7(mut self) -> Self {
		self.state.set_k7();
		self
	}

	/// Enables zeroing masking `{z}`
	#[must_use]
	#[inline]
	pub fn z(mut self) -> Self {
		self.state.set_zeroing_masking();
		self
	}

	/// Enables suppress all exceptions `{sae}`
	#[must_use]
	#[inline]
	pub fn sae(mut self) -> Self {
		self.state.set_suppress_all_exceptions();
		self
	}

	/// Round to nearest (even)
	#[must_use]
	#[inline]
	pub fn rn_sae(mut self) -> Self {
		self.state.rn_sae();
		self
	}

	/// Round down (toward -inf)
	#[must_use]
	#[inline]
	pub fn rd_sae(mut self) -> Self {
		self.state.rd_sae();
		self
	}

	/// Round up (toward +inf)
	#[must_use]
	#[inline]
	pub fn ru_sae(mut self) -> Self {
		self.state.ru_sae();
		self
	}

	/// Round toward zero (truncate)
	#[must_use]
	#[inline]
	pub fn rz_sae(mut self) -> Self {
		self.state.rz_sae();
		self
	}
}

#[rustfmt::skip]
impl From<AsmRegister64> for Register {
	#[inline]
	fn from(reg: AsmRegister64) -> Self {
		reg.register
	}
}

/// All segment registers.
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::segment::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
#[repr(transparent)]
pub struct AsmRegisterSegment {
	register: Register,
}

#[rustfmt::skip]
impl AsmRegisterSegment {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}
}

#[rustfmt::skip]
impl From<AsmRegisterSegment> for Register {
	#[inline]
	fn from(reg: AsmRegisterSegment) -> Self {
		reg.register
	}
}

/// All control registers.
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::cr::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
#[repr(transparent)]
pub struct AsmRegisterCr {
	register: Register,
}

#[rustfmt::skip]
impl AsmRegisterCr {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}
}

#[rustfmt::skip]
impl From<AsmRegisterCr> for Register {
	#[inline]
	fn from(reg: AsmRegisterCr) -> Self {
		reg.register
	}
}

/// All debug registers.
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::dr::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
#[repr(transparent)]
pub struct AsmRegisterDr {
	register: Register,
}

#[rustfmt::skip]
impl AsmRegisterDr {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}
}

#[rustfmt::skip]
impl From<AsmRegisterDr> for Register {
	#[inline]
	fn from(reg: AsmRegisterDr) -> Self {
		reg.register
	}
}

/// All test registers.
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::tr::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
#[repr(transparent)]
pub struct AsmRegisterTr {
	register: Register,
}

#[rustfmt::skip]
impl AsmRegisterTr {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}
}

#[rustfmt::skip]
impl From<AsmRegisterTr> for Register {
	#[inline]
	fn from(reg: AsmRegisterTr) -> Self {
		reg.register
	}
}

/// All FPU registers.
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::st::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
#[repr(transparent)]
pub struct AsmRegisterSt {
	register: Register,
}

#[rustfmt::skip]
impl AsmRegisterSt {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}
}

#[rustfmt::skip]
impl From<AsmRegisterSt> for Register {
	#[inline]
	fn from(reg: AsmRegisterSt) -> Self {
		reg.register
	}
}

/// All MMX registers.
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::mm::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
#[repr(transparent)]
pub struct AsmRegisterMm {
	register: Register,
}

#[rustfmt::skip]
impl AsmRegisterMm {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}
}

#[rustfmt::skip]
impl From<AsmRegisterMm> for Register {
	#[inline]
	fn from(reg: AsmRegisterMm) -> Self {
		reg.register
	}
}

/// All 128-bit vector registers (XMM).
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::xmm::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
pub struct AsmRegisterXmm {
	register: Register,
	state: CodeAsmOpState,
}

#[rustfmt::skip]
impl AsmRegisterXmm {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register, state: CodeAsmOpState::new() }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}

	#[must_use]
	#[inline]
	pub(crate) fn state(&self) -> CodeAsmOpState {
		self.state
	}

	/// Adds a `{k1}` opmask register
	#[must_use]
	#[inline]
	pub fn k1(mut self) -> Self {
		self.state.set_k1();
		self
	}

	/// Adds a `{k2}` opmask register
	#[must_use]
	#[inline]
	pub fn k2(mut self) -> Self {
		self.state.set_k2();
		self
	}

	/// Adds a `{k3}` opmask register
	#[must_use]
	#[inline]
	pub fn k3(mut self) -> Self {
		self.state.set_k3();
		self
	}

	/// Adds a `{k4}` opmask register
	#[must_use]
	#[inline]
	pub fn k4(mut self) -> Self {
		self.state.set_k4();
		self
	}

	/// Adds a `{k5}` opmask register
	#[must_use]
	#[inline]
	pub fn k5(mut self) -> Self {
		self.state.set_k5();
		self
	}

	/// Adds a `{k6}` opmask register
	#[must_use]
	#[inline]
	pub fn k6(mut self) -> Self {
		self.state.set_k6();
		self
	}

	/// Adds a `{k7}` opmask register
	#[must_use]
	#[inline]
	pub fn k7(mut self) -> Self {
		self.state.set_k7();
		self
	}

	/// Enables zeroing masking `{z}`
	#[must_use]
	#[inline]
	pub fn z(mut self) -> Self {
		self.state.set_zeroing_masking();
		self
	}

	/// Enables suppress all exceptions `{sae}`
	#[must_use]
	#[inline]
	pub fn sae(mut self) -> Self {
		self.state.set_suppress_all_exceptions();
		self
	}

	/// Round to nearest (even)
	#[must_use]
	#[inline]
	pub fn rn_sae(mut self) -> Self {
		self.state.rn_sae();
		self
	}

	/// Round down (toward -inf)
	#[must_use]
	#[inline]
	pub fn rd_sae(mut self) -> Self {
		self.state.rd_sae();
		self
	}

	/// Round up (toward +inf)
	#[must_use]
	#[inline]
	pub fn ru_sae(mut self) -> Self {
		self.state.ru_sae();
		self
	}

	/// Round toward zero (truncate)
	#[must_use]
	#[inline]
	pub fn rz_sae(mut self) -> Self {
		self.state.rz_sae();
		self
	}
}

#[rustfmt::skip]
impl From<AsmRegisterXmm> for Register {
	#[inline]
	fn from(reg: AsmRegisterXmm) -> Self {
		reg.register
	}
}

/// All 256-bit vector registers (YMM).
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::ymm::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
pub struct AsmRegisterYmm {
	register: Register,
	state: CodeAsmOpState,
}

#[rustfmt::skip]
impl AsmRegisterYmm {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register, state: CodeAsmOpState::new() }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}

	#[must_use]
	#[inline]
	pub(crate) fn state(&self) -> CodeAsmOpState {
		self.state
	}

	/// Adds a `{k1}` opmask register
	#[must_use]
	#[inline]
	pub fn k1(mut self) -> Self {
		self.state.set_k1();
		self
	}

	/// Adds a `{k2}` opmask register
	#[must_use]
	#[inline]
	pub fn k2(mut self) -> Self {
		self.state.set_k2();
		self
	}

	/// Adds a `{k3}` opmask register
	#[must_use]
	#[inline]
	pub fn k3(mut self) -> Self {
		self.state.set_k3();
		self
	}

	/// Adds a `{k4}` opmask register
	#[must_use]
	#[inline]
	pub fn k4(mut self) -> Self {
		self.state.set_k4();
		self
	}

	/// Adds a `{k5}` opmask register
	#[must_use]
	#[inline]
	pub fn k5(mut self) -> Self {
		self.state.set_k5();
		self
	}

	/// Adds a `{k6}` opmask register
	#[must_use]
	#[inline]
	pub fn k6(mut self) -> Self {
		self.state.set_k6();
		self
	}

	/// Adds a `{k7}` opmask register
	#[must_use]
	#[inline]
	pub fn k7(mut self) -> Self {
		self.state.set_k7();
		self
	}

	/// Enables zeroing masking `{z}`
	#[must_use]
	#[inline]
	pub fn z(mut self) -> Self {
		self.state.set_zeroing_masking();
		self
	}

	/// Enables suppress all exceptions `{sae}`
	#[must_use]
	#[inline]
	pub fn sae(mut self) -> Self {
		self.state.set_suppress_all_exceptions();
		self
	}

	/// Round to nearest (even)
	#[must_use]
	#[inline]
	pub fn rn_sae(mut self) -> Self {
		self.state.rn_sae();
		self
	}

	/// Round down (toward -inf)
	#[must_use]
	#[inline]
	pub fn rd_sae(mut self) -> Self {
		self.state.rd_sae();
		self
	}

	/// Round up (toward +inf)
	#[must_use]
	#[inline]
	pub fn ru_sae(mut self) -> Self {
		self.state.ru_sae();
		self
	}

	/// Round toward zero (truncate)
	#[must_use]
	#[inline]
	pub fn rz_sae(mut self) -> Self {
		self.state.rz_sae();
		self
	}
}

#[rustfmt::skip]
impl From<AsmRegisterYmm> for Register {
	#[inline]
	fn from(reg: AsmRegisterYmm) -> Self {
		reg.register
	}
}

/// All 512-bit vector registers (ZMM).
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::zmm::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
pub struct AsmRegisterZmm {
	register: Register,
	state: CodeAsmOpState,
}

#[rustfmt::skip]
impl AsmRegisterZmm {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register, state: CodeAsmOpState::new() }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}

	#[must_use]
	#[inline]
	pub(crate) fn state(&self) -> CodeAsmOpState {
		self.state
	}

	/// Adds a `{k1}` opmask register
	#[must_use]
	#[inline]
	pub fn k1(mut self) -> Self {
		self.state.set_k1();
		self
	}

	/// Adds a `{k2}` opmask register
	#[must_use]
	#[inline]
	pub fn k2(mut self) -> Self {
		self.state.set_k2();
		self
	}

	/// Adds a `{k3}` opmask register
	#[must_use]
	#[inline]
	pub fn k3(mut self) -> Self {
		self.state.set_k3();
		self
	}

	/// Adds a `{k4}` opmask register
	#[must_use]
	#[inline]
	pub fn k4(mut self) -> Self {
		self.state.set_k4();
		self
	}

	/// Adds a `{k5}` opmask register
	#[must_use]
	#[inline]
	pub fn k5(mut self) -> Self {
		self.state.set_k5();
		self
	}

	/// Adds a `{k6}` opmask register
	#[must_use]
	#[inline]
	pub fn k6(mut self) -> Self {
		self.state.set_k6();
		self
	}

	/// Adds a `{k7}` opmask register
	#[must_use]
	#[inline]
	pub fn k7(mut self) -> Self {
		self.state.set_k7();
		self
	}

	/// Enables zeroing masking `{z}`
	#[must_use]
	#[inline]
	pub fn z(mut self) -> Self {
		self.state.set_zeroing_masking();
		self
	}

	/// Enables suppress all exceptions `{sae}`
	#[must_use]
	#[inline]
	pub fn sae(mut self) -> Self {
		self.state.set_suppress_all_exceptions();
		self
	}

	/// Round to nearest (even)
	#[must_use]
	#[inline]
	pub fn rn_sae(mut self) -> Self {
		self.state.rn_sae();
		self
	}

	/// Round down (toward -inf)
	#[must_use]
	#[inline]
	pub fn rd_sae(mut self) -> Self {
		self.state.rd_sae();
		self
	}

	/// Round up (toward +inf)
	#[must_use]
	#[inline]
	pub fn ru_sae(mut self) -> Self {
		self.state.ru_sae();
		self
	}

	/// Round toward zero (truncate)
	#[must_use]
	#[inline]
	pub fn rz_sae(mut self) -> Self {
		self.state.rz_sae();
		self
	}
}

#[rustfmt::skip]
impl From<AsmRegisterZmm> for Register {
	#[inline]
	fn from(reg: AsmRegisterZmm) -> Self {
		reg.register
	}
}

/// All tile registers.
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::tmm::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
#[repr(transparent)]
pub struct AsmRegisterTmm {
	register: Register,
}

#[rustfmt::skip]
impl AsmRegisterTmm {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}
}

#[rustfmt::skip]
impl From<AsmRegisterTmm> for Register {
	#[inline]
	fn from(reg: AsmRegisterTmm) -> Self {
		reg.register
	}
}

/// All opmask registers.
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::k::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
pub struct AsmRegisterK {
	register: Register,
	state: CodeAsmOpState,
}

#[rustfmt::skip]
impl AsmRegisterK {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register, state: CodeAsmOpState::new() }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}

	#[must_use]
	#[inline]
	pub(crate) fn state(&self) -> CodeAsmOpState {
		self.state
	}

	/// Adds a `{k1}` opmask register
	#[must_use]
	#[inline]
	pub fn k1(mut self) -> Self {
		self.state.set_k1();
		self
	}

	/// Adds a `{k2}` opmask register
	#[must_use]
	#[inline]
	pub fn k2(mut self) -> Self {
		self.state.set_k2();
		self
	}

	/// Adds a `{k3}` opmask register
	#[must_use]
	#[inline]
	pub fn k3(mut self) -> Self {
		self.state.set_k3();
		self
	}

	/// Adds a `{k4}` opmask register
	#[must_use]
	#[inline]
	pub fn k4(mut self) -> Self {
		self.state.set_k4();
		self
	}

	/// Adds a `{k5}` opmask register
	#[must_use]
	#[inline]
	pub fn k5(mut self) -> Self {
		self.state.set_k5();
		self
	}

	/// Adds a `{k6}` opmask register
	#[must_use]
	#[inline]
	pub fn k6(mut self) -> Self {
		self.state.set_k6();
		self
	}

	/// Adds a `{k7}` opmask register
	#[must_use]
	#[inline]
	pub fn k7(mut self) -> Self {
		self.state.set_k7();
		self
	}

	/// Enables zeroing masking `{z}`
	#[must_use]
	#[inline]
	pub fn z(mut self) -> Self {
		self.state.set_zeroing_masking();
		self
	}

	/// Enables suppress all exceptions `{sae}`
	#[must_use]
	#[inline]
	pub fn sae(mut self) -> Self {
		self.state.set_suppress_all_exceptions();
		self
	}

	/// Round to nearest (even)
	#[must_use]
	#[inline]
	pub fn rn_sae(mut self) -> Self {
		self.state.rn_sae();
		self
	}

	/// Round down (toward -inf)
	#[must_use]
	#[inline]
	pub fn rd_sae(mut self) -> Self {
		self.state.rd_sae();
		self
	}

	/// Round up (toward +inf)
	#[must_use]
	#[inline]
	pub fn ru_sae(mut self) -> Self {
		self.state.ru_sae();
		self
	}

	/// Round toward zero (truncate)
	#[must_use]
	#[inline]
	pub fn rz_sae(mut self) -> Self {
		self.state.rz_sae();
		self
	}
}

#[rustfmt::skip]
impl From<AsmRegisterK> for Register {
	#[inline]
	fn from(reg: AsmRegisterK) -> Self {
		reg.register
	}
}

/// All bound registers.
///
/// This type is *not* part of the public API! It's an implementation detail.
/// The register identifiers, however, *are* part of the public API.
///
/// To use the registers, you must import everything from the module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::*;
/// ```
///
/// or import them from this module:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::*;
/// ```
///
/// or import only these registers:
///
/// ```
/// # #![allow(unused_imports)]
/// use iced_x86::code_asm::registers::bnd::*;
/// ```
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[rustfmt::skip]
#[repr(transparent)]
pub struct AsmRegisterBnd {
	register: Register,
}

#[rustfmt::skip]
impl AsmRegisterBnd {
	#[must_use]
	#[inline]
	pub(crate) const fn new(register: Register) -> Self {
		Self { register }
	}

	#[must_use]
	#[inline]
	pub(crate) fn register(&self) -> Register {
		self.register
	}
}

#[rustfmt::skip]
impl From<AsmRegisterBnd> for Register {
	#[inline]
	fn from(reg: AsmRegisterBnd) -> Self {
		reg.register
	}
}
