Skip to main content

asmkit/x86/features/
AESNI.rs

1use crate::x86::assembler::*;
2use crate::x86::operands::*;
3use super::super::opcodes::*;
4use crate::core::emitter::*;
5use crate::core::operand::*;
6
7/// A dummy operand that represents no register. Here just for simplicity.
8const NOREG: Operand = Operand::new();
9
10/// `AESDEC` (AESDEC). 
11/// This instruction performs a single round of the AES decryption flow using the Equivalent Inverse Cipher, using one/two/four (depending on vector length) 128-bit data (state) from the first source operand with one/two/four (depending on vector length) round key(s) from the second source operand, and stores the result in the destination operand.
12///
13///
14/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/AESDEC.html).
15///
16/// Supported operand variants:
17///
18/// ```text
19/// +---+----------+
20/// | # | Operands |
21/// +---+----------+
22/// | 1 | Xmm, Mem |
23/// | 2 | Xmm, Xmm |
24/// +---+----------+
25/// ```
26pub trait AesdecEmitter<A, B> {
27    fn aesdec(&mut self, op0: A, op1: B);
28}
29
30impl<'a> AesdecEmitter<Xmm, Xmm> for Assembler<'a> {
31    fn aesdec(&mut self, op0: Xmm, op1: Xmm) {
32        self.emit(AESDECRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
33    }
34}
35
36impl<'a> AesdecEmitter<Xmm, Mem> for Assembler<'a> {
37    fn aesdec(&mut self, op0: Xmm, op1: Mem) {
38        self.emit(AESDECRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
39    }
40}
41
42/// `AESDECLAST` (AESDECLAST). 
43/// This instruction performs the last round of the AES decryption flow using the Equivalent Inverse Cipher, using one/two/four (depending on vector length) 128-bit data (state) from the first source operand with one/two/four (depending on vector length) round key(s) from the second source operand, and stores the result in the destination operand.
44///
45///
46/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/AESDECLAST.html).
47///
48/// Supported operand variants:
49///
50/// ```text
51/// +---+----------+
52/// | # | Operands |
53/// +---+----------+
54/// | 1 | Xmm, Mem |
55/// | 2 | Xmm, Xmm |
56/// +---+----------+
57/// ```
58pub trait AesdeclastEmitter<A, B> {
59    fn aesdeclast(&mut self, op0: A, op1: B);
60}
61
62impl<'a> AesdeclastEmitter<Xmm, Xmm> for Assembler<'a> {
63    fn aesdeclast(&mut self, op0: Xmm, op1: Xmm) {
64        self.emit(AESDECLASTRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
65    }
66}
67
68impl<'a> AesdeclastEmitter<Xmm, Mem> for Assembler<'a> {
69    fn aesdeclast(&mut self, op0: Xmm, op1: Mem) {
70        self.emit(AESDECLASTRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
71    }
72}
73
74/// `AESENC` (AESENC). 
75/// This instruction performs a single round of an AES encryption flow using one/two/four (depending on vector length) 128-bit data (state) from the first source operand with one/two/four (depending on vector length) round key(s) from the second source operand, and stores the result in the destination operand.
76///
77///
78/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/AESENC.html).
79///
80/// Supported operand variants:
81///
82/// ```text
83/// +---+----------+
84/// | # | Operands |
85/// +---+----------+
86/// | 1 | Xmm, Mem |
87/// | 2 | Xmm, Xmm |
88/// +---+----------+
89/// ```
90pub trait AesencEmitter<A, B> {
91    fn aesenc(&mut self, op0: A, op1: B);
92}
93
94impl<'a> AesencEmitter<Xmm, Xmm> for Assembler<'a> {
95    fn aesenc(&mut self, op0: Xmm, op1: Xmm) {
96        self.emit(AESENCRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
97    }
98}
99
100impl<'a> AesencEmitter<Xmm, Mem> for Assembler<'a> {
101    fn aesenc(&mut self, op0: Xmm, op1: Mem) {
102        self.emit(AESENCRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
103    }
104}
105
106/// `AESENCLAST` (AESENCLAST). 
107/// This instruction performs the last round of an AES encryption flow using one/two/four (depending on vector length) 128-bit data (state) from the first source operand with one/two/four (depending on vector length) round key(s) from the second source operand, and stores the result in the destination operand.
108///
109///
110/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/AESENCLAST.html).
111///
112/// Supported operand variants:
113///
114/// ```text
115/// +---+----------+
116/// | # | Operands |
117/// +---+----------+
118/// | 1 | Xmm, Mem |
119/// | 2 | Xmm, Xmm |
120/// +---+----------+
121/// ```
122pub trait AesenclastEmitter<A, B> {
123    fn aesenclast(&mut self, op0: A, op1: B);
124}
125
126impl<'a> AesenclastEmitter<Xmm, Xmm> for Assembler<'a> {
127    fn aesenclast(&mut self, op0: Xmm, op1: Xmm) {
128        self.emit(AESENCLASTRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
129    }
130}
131
132impl<'a> AesenclastEmitter<Xmm, Mem> for Assembler<'a> {
133    fn aesenclast(&mut self, op0: Xmm, op1: Mem) {
134        self.emit(AESENCLASTRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
135    }
136}
137
138/// `AESIMC` (AESIMC). 
139/// Perform the InvMixColumns transformation on the source operand and store the result in the destination operand. The destination operand is an XMM register. The source operand can be an XMM register or a 128-bit memory location.
140///
141///
142/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/AESIMC.html).
143///
144/// Supported operand variants:
145///
146/// ```text
147/// +---+----------+
148/// | # | Operands |
149/// +---+----------+
150/// | 1 | Xmm, Mem |
151/// | 2 | Xmm, Xmm |
152/// +---+----------+
153/// ```
154pub trait AesimcEmitter<A, B> {
155    fn aesimc(&mut self, op0: A, op1: B);
156}
157
158impl<'a> AesimcEmitter<Xmm, Xmm> for Assembler<'a> {
159    fn aesimc(&mut self, op0: Xmm, op1: Xmm) {
160        self.emit(AESIMCRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
161    }
162}
163
164impl<'a> AesimcEmitter<Xmm, Mem> for Assembler<'a> {
165    fn aesimc(&mut self, op0: Xmm, op1: Mem) {
166        self.emit(AESIMCRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
167    }
168}
169
170/// `AESKEYGENASSIST` (AESKEYGENASSIST). 
171/// Assist in expanding the AES cipher key, by computing steps towards generating a round key for encryption, using 128-bit data specified in the source operand and an 8-bit round constant specified as an immediate, store the result in the destination operand.
172///
173///
174/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/AESKEYGENASSIST.html).
175///
176/// Supported operand variants:
177///
178/// ```text
179/// +---+---------------+
180/// | # | Operands      |
181/// +---+---------------+
182/// | 1 | Xmm, Mem, Imm |
183/// | 2 | Xmm, Xmm, Imm |
184/// +---+---------------+
185/// ```
186pub trait AeskeygenassistEmitter<A, B, C> {
187    fn aeskeygenassist(&mut self, op0: A, op1: B, op2: C);
188}
189
190impl<'a> AeskeygenassistEmitter<Xmm, Xmm, Imm> for Assembler<'a> {
191    fn aeskeygenassist(&mut self, op0: Xmm, op1: Xmm, op2: Imm) {
192        self.emit(AESKEYGENASSISTRRI, op0.as_operand(), op1.as_operand(), op2.as_operand(), &NOREG);
193    }
194}
195
196impl<'a> AeskeygenassistEmitter<Xmm, Mem, Imm> for Assembler<'a> {
197    fn aeskeygenassist(&mut self, op0: Xmm, op1: Mem, op2: Imm) {
198        self.emit(AESKEYGENASSISTRMI, op0.as_operand(), op1.as_operand(), op2.as_operand(), &NOREG);
199    }
200}
201
202
203impl<'a> Assembler<'a> {
204    /// `AESDEC` (AESDEC). 
205    /// This instruction performs a single round of the AES decryption flow using the Equivalent Inverse Cipher, using one/two/four (depending on vector length) 128-bit data (state) from the first source operand with one/two/four (depending on vector length) round key(s) from the second source operand, and stores the result in the destination operand.
206    ///
207    ///
208    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/AESDEC.html).
209    ///
210    /// Supported operand variants:
211    ///
212    /// ```text
213    /// +---+----------+
214    /// | # | Operands |
215    /// +---+----------+
216    /// | 1 | Xmm, Mem |
217    /// | 2 | Xmm, Xmm |
218    /// +---+----------+
219    /// ```
220    #[inline]
221    pub fn aesdec<A, B>(&mut self, op0: A, op1: B)
222    where Assembler<'a>: AesdecEmitter<A, B> {
223        <Self as AesdecEmitter<A, B>>::aesdec(self, op0, op1);
224    }
225    /// `AESDECLAST` (AESDECLAST). 
226    /// This instruction performs the last round of the AES decryption flow using the Equivalent Inverse Cipher, using one/two/four (depending on vector length) 128-bit data (state) from the first source operand with one/two/four (depending on vector length) round key(s) from the second source operand, and stores the result in the destination operand.
227    ///
228    ///
229    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/AESDECLAST.html).
230    ///
231    /// Supported operand variants:
232    ///
233    /// ```text
234    /// +---+----------+
235    /// | # | Operands |
236    /// +---+----------+
237    /// | 1 | Xmm, Mem |
238    /// | 2 | Xmm, Xmm |
239    /// +---+----------+
240    /// ```
241    #[inline]
242    pub fn aesdeclast<A, B>(&mut self, op0: A, op1: B)
243    where Assembler<'a>: AesdeclastEmitter<A, B> {
244        <Self as AesdeclastEmitter<A, B>>::aesdeclast(self, op0, op1);
245    }
246    /// `AESENC` (AESENC). 
247    /// This instruction performs a single round of an AES encryption flow using one/two/four (depending on vector length) 128-bit data (state) from the first source operand with one/two/four (depending on vector length) round key(s) from the second source operand, and stores the result in the destination operand.
248    ///
249    ///
250    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/AESENC.html).
251    ///
252    /// Supported operand variants:
253    ///
254    /// ```text
255    /// +---+----------+
256    /// | # | Operands |
257    /// +---+----------+
258    /// | 1 | Xmm, Mem |
259    /// | 2 | Xmm, Xmm |
260    /// +---+----------+
261    /// ```
262    #[inline]
263    pub fn aesenc<A, B>(&mut self, op0: A, op1: B)
264    where Assembler<'a>: AesencEmitter<A, B> {
265        <Self as AesencEmitter<A, B>>::aesenc(self, op0, op1);
266    }
267    /// `AESENCLAST` (AESENCLAST). 
268    /// This instruction performs the last round of an AES encryption flow using one/two/four (depending on vector length) 128-bit data (state) from the first source operand with one/two/four (depending on vector length) round key(s) from the second source operand, and stores the result in the destination operand.
269    ///
270    ///
271    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/AESENCLAST.html).
272    ///
273    /// Supported operand variants:
274    ///
275    /// ```text
276    /// +---+----------+
277    /// | # | Operands |
278    /// +---+----------+
279    /// | 1 | Xmm, Mem |
280    /// | 2 | Xmm, Xmm |
281    /// +---+----------+
282    /// ```
283    #[inline]
284    pub fn aesenclast<A, B>(&mut self, op0: A, op1: B)
285    where Assembler<'a>: AesenclastEmitter<A, B> {
286        <Self as AesenclastEmitter<A, B>>::aesenclast(self, op0, op1);
287    }
288    /// `AESIMC` (AESIMC). 
289    /// Perform the InvMixColumns transformation on the source operand and store the result in the destination operand. The destination operand is an XMM register. The source operand can be an XMM register or a 128-bit memory location.
290    ///
291    ///
292    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/AESIMC.html).
293    ///
294    /// Supported operand variants:
295    ///
296    /// ```text
297    /// +---+----------+
298    /// | # | Operands |
299    /// +---+----------+
300    /// | 1 | Xmm, Mem |
301    /// | 2 | Xmm, Xmm |
302    /// +---+----------+
303    /// ```
304    #[inline]
305    pub fn aesimc<A, B>(&mut self, op0: A, op1: B)
306    where Assembler<'a>: AesimcEmitter<A, B> {
307        <Self as AesimcEmitter<A, B>>::aesimc(self, op0, op1);
308    }
309    /// `AESKEYGENASSIST` (AESKEYGENASSIST). 
310    /// Assist in expanding the AES cipher key, by computing steps towards generating a round key for encryption, using 128-bit data specified in the source operand and an 8-bit round constant specified as an immediate, store the result in the destination operand.
311    ///
312    ///
313    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/AESKEYGENASSIST.html).
314    ///
315    /// Supported operand variants:
316    ///
317    /// ```text
318    /// +---+---------------+
319    /// | # | Operands      |
320    /// +---+---------------+
321    /// | 1 | Xmm, Mem, Imm |
322    /// | 2 | Xmm, Xmm, Imm |
323    /// +---+---------------+
324    /// ```
325    #[inline]
326    pub fn aeskeygenassist<A, B, C>(&mut self, op0: A, op1: B, op2: C)
327    where Assembler<'a>: AeskeygenassistEmitter<A, B, C> {
328        <Self as AeskeygenassistEmitter<A, B, C>>::aeskeygenassist(self, op0, op1, op2);
329    }
330}