Skip to main content

asmkit/x86/features/
ADX.rs

1use super::super::opcodes::*;
2use crate::core::emitter::*;
3use crate::core::operand::*;
4use crate::x86::assembler::*;
5use crate::x86::operands::*;
6
7/// A dummy operand that represents no register. Here just for simplicity.
8const NOREG: Operand = Operand::new();
9
10/// `ADCX`.
11///
12/// Supported operand variants:
13///
14/// ```text
15/// +---+----------+
16/// | # | Operands |
17/// +---+----------+
18/// | 1 | Gpd, Gpd |
19/// | 2 | Gpd, Mem |
20/// | 3 | Gpq, Gpq |
21/// | 4 | Gpq, Mem |
22/// +---+----------+
23/// ```
24pub trait AdcxEmitter<A, B> {
25    fn adcx(&mut self, op0: A, op1: B);
26}
27
28impl<'a> AdcxEmitter<Gpd, Gpd> for Assembler<'a> {
29    fn adcx(&mut self, op0: Gpd, op1: Gpd) {
30        self.emit(ADCX32RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
31    }
32}
33
34impl<'a> AdcxEmitter<Gpd, Mem> for Assembler<'a> {
35    fn adcx(&mut self, op0: Gpd, op1: Mem) {
36        self.emit(ADCX32RM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
37    }
38}
39
40impl<'a> AdcxEmitter<Gpq, Gpq> for Assembler<'a> {
41    fn adcx(&mut self, op0: Gpq, op1: Gpq) {
42        self.emit(ADCX64RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
43    }
44}
45
46impl<'a> AdcxEmitter<Gpq, Mem> for Assembler<'a> {
47    fn adcx(&mut self, op0: Gpq, op1: Mem) {
48        self.emit(ADCX64RM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
49    }
50}
51
52/// `ADOX`.
53///
54/// Supported operand variants:
55///
56/// ```text
57/// +---+----------+
58/// | # | Operands |
59/// +---+----------+
60/// | 1 | Gpd, Gpd |
61/// | 2 | Gpd, Mem |
62/// | 3 | Gpq, Gpq |
63/// | 4 | Gpq, Mem |
64/// +---+----------+
65/// ```
66pub trait AdoxEmitter<A, B> {
67    fn adox(&mut self, op0: A, op1: B);
68}
69
70impl<'a> AdoxEmitter<Gpd, Gpd> for Assembler<'a> {
71    fn adox(&mut self, op0: Gpd, op1: Gpd) {
72        self.emit(ADOX32RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
73    }
74}
75
76impl<'a> AdoxEmitter<Gpd, Mem> for Assembler<'a> {
77    fn adox(&mut self, op0: Gpd, op1: Mem) {
78        self.emit(ADOX32RM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
79    }
80}
81
82impl<'a> AdoxEmitter<Gpq, Gpq> for Assembler<'a> {
83    fn adox(&mut self, op0: Gpq, op1: Gpq) {
84        self.emit(ADOX64RR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
85    }
86}
87
88impl<'a> AdoxEmitter<Gpq, Mem> for Assembler<'a> {
89    fn adox(&mut self, op0: Gpq, op1: Mem) {
90        self.emit(ADOX64RM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
91    }
92}
93
94impl<'a> Assembler<'a> {
95    /// `ADCX`.
96    ///
97    /// Supported operand variants:
98    ///
99    /// ```text
100    /// +---+----------+
101    /// | # | Operands |
102    /// +---+----------+
103    /// | 1 | Gpd, Gpd |
104    /// | 2 | Gpd, Mem |
105    /// | 3 | Gpq, Gpq |
106    /// | 4 | Gpq, Mem |
107    /// +---+----------+
108    /// ```
109    #[inline]
110    pub fn adcx<A, B>(&mut self, op0: A, op1: B)
111    where
112        Assembler<'a>: AdcxEmitter<A, B>,
113    {
114        <Self as AdcxEmitter<A, B>>::adcx(self, op0, op1);
115    }
116    /// `ADOX`.
117    ///
118    /// Supported operand variants:
119    ///
120    /// ```text
121    /// +---+----------+
122    /// | # | Operands |
123    /// +---+----------+
124    /// | 1 | Gpd, Gpd |
125    /// | 2 | Gpd, Mem |
126    /// | 3 | Gpq, Gpq |
127    /// | 4 | Gpq, Mem |
128    /// +---+----------+
129    /// ```
130    #[inline]
131    pub fn adox<A, B>(&mut self, op0: A, op1: B)
132    where
133        Assembler<'a>: AdoxEmitter<A, B>,
134    {
135        <Self as AdoxEmitter<A, B>>::adox(self, op0, op1);
136    }
137}