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}