asmkit/x86/features/VMX.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/// `INVEPT`.
11///
12/// Supported operand variants:
13///
14/// ```text
15/// +---+----------+
16/// | # | Operands |
17/// +---+----------+
18/// | 1 | Gpq, Mem |
19/// +---+----------+
20/// ```
21pub trait InveptEmitter<A, B> {
22 fn invept(&mut self, op0: A, op1: B);
23}
24
25impl<'a> InveptEmitter<Gpq, Mem> for Assembler<'a> {
26 fn invept(&mut self, op0: Gpq, op1: Mem) {
27 self.emit(INVEPTRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
28 }
29}
30
31/// `INVVPID`.
32///
33/// Supported operand variants:
34///
35/// ```text
36/// +---+----------+
37/// | # | Operands |
38/// +---+----------+
39/// | 1 | Gpq, Mem |
40/// +---+----------+
41/// ```
42pub trait InvvpidEmitter<A, B> {
43 fn invvpid(&mut self, op0: A, op1: B);
44}
45
46impl<'a> InvvpidEmitter<Gpq, Mem> for Assembler<'a> {
47 fn invvpid(&mut self, op0: Gpq, op1: Mem) {
48 self.emit(INVVPIDRM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
49 }
50}
51
52/// `VMCALL`.
53///
54/// Supported operand variants:
55///
56/// ```text
57/// +---+----------+
58/// | # | Operands |
59/// +---+----------+
60/// | 1 | (none) |
61/// +---+----------+
62/// ```
63pub trait VmcallEmitter {
64 fn vmcall(&mut self);
65}
66
67impl<'a> VmcallEmitter for Assembler<'a> {
68 fn vmcall(&mut self) {
69 self.emit(VMCALL, &NOREG, &NOREG, &NOREG, &NOREG);
70 }
71}
72
73/// `VMCLEAR`.
74///
75/// Supported operand variants:
76///
77/// ```text
78/// +---+----------+
79/// | # | Operands |
80/// +---+----------+
81/// | 1 | Mem |
82/// +---+----------+
83/// ```
84pub trait VmclearEmitter<A> {
85 fn vmclear(&mut self, op0: A);
86}
87
88impl<'a> VmclearEmitter<Mem> for Assembler<'a> {
89 fn vmclear(&mut self, op0: Mem) {
90 self.emit(VMCLEARM, op0.as_operand(), &NOREG, &NOREG, &NOREG);
91 }
92}
93
94/// `VMFUNC`.
95///
96/// Supported operand variants:
97///
98/// ```text
99/// +---+----------+
100/// | # | Operands |
101/// +---+----------+
102/// | 1 | (none) |
103/// +---+----------+
104/// ```
105pub trait VmfuncEmitter {
106 fn vmfunc(&mut self);
107}
108
109impl<'a> VmfuncEmitter for Assembler<'a> {
110 fn vmfunc(&mut self) {
111 self.emit(VMFUNC, &NOREG, &NOREG, &NOREG, &NOREG);
112 }
113}
114
115/// `VMLAUNCH`.
116///
117/// Supported operand variants:
118///
119/// ```text
120/// +---+----------+
121/// | # | Operands |
122/// +---+----------+
123/// | 1 | (none) |
124/// +---+----------+
125/// ```
126pub trait VmlaunchEmitter {
127 fn vmlaunch(&mut self);
128}
129
130impl<'a> VmlaunchEmitter for Assembler<'a> {
131 fn vmlaunch(&mut self) {
132 self.emit(VMLAUNCH, &NOREG, &NOREG, &NOREG, &NOREG);
133 }
134}
135
136/// `VMPTRLD`.
137///
138/// Supported operand variants:
139///
140/// ```text
141/// +---+----------+
142/// | # | Operands |
143/// +---+----------+
144/// | 1 | Mem |
145/// +---+----------+
146/// ```
147pub trait VmptrldEmitter<A> {
148 fn vmptrld(&mut self, op0: A);
149}
150
151impl<'a> VmptrldEmitter<Mem> for Assembler<'a> {
152 fn vmptrld(&mut self, op0: Mem) {
153 self.emit(VMPTRLDM, op0.as_operand(), &NOREG, &NOREG, &NOREG);
154 }
155}
156
157/// `VMPTRST`.
158///
159/// Supported operand variants:
160///
161/// ```text
162/// +---+----------+
163/// | # | Operands |
164/// +---+----------+
165/// | 1 | Mem |
166/// +---+----------+
167/// ```
168pub trait VmptrstEmitter<A> {
169 fn vmptrst(&mut self, op0: A);
170}
171
172impl<'a> VmptrstEmitter<Mem> for Assembler<'a> {
173 fn vmptrst(&mut self, op0: Mem) {
174 self.emit(VMPTRSTM, op0.as_operand(), &NOREG, &NOREG, &NOREG);
175 }
176}
177
178/// `VMREAD`.
179///
180/// Supported operand variants:
181///
182/// ```text
183/// +---+----------+
184/// | # | Operands |
185/// +---+----------+
186/// | 1 | Gpq, Gpq |
187/// | 2 | Mem, Gpq |
188/// +---+----------+
189/// ```
190pub trait VmreadEmitter<A, B> {
191 fn vmread(&mut self, op0: A, op1: B);
192}
193
194impl<'a> VmreadEmitter<Gpq, Gpq> for Assembler<'a> {
195 fn vmread(&mut self, op0: Gpq, op1: Gpq) {
196 self.emit(VMREADRR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
197 }
198}
199
200impl<'a> VmreadEmitter<Mem, Gpq> for Assembler<'a> {
201 fn vmread(&mut self, op0: Mem, op1: Gpq) {
202 self.emit(VMREADMR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
203 }
204}
205
206/// `VMRESUME`.
207///
208/// Supported operand variants:
209///
210/// ```text
211/// +---+----------+
212/// | # | Operands |
213/// +---+----------+
214/// | 1 | (none) |
215/// +---+----------+
216/// ```
217pub trait VmresumeEmitter {
218 fn vmresume(&mut self);
219}
220
221impl<'a> VmresumeEmitter for Assembler<'a> {
222 fn vmresume(&mut self) {
223 self.emit(VMRESUME, &NOREG, &NOREG, &NOREG, &NOREG);
224 }
225}
226
227/// `VMWRITE`.
228///
229/// Supported operand variants:
230///
231/// ```text
232/// +---+----------+
233/// | # | Operands |
234/// +---+----------+
235/// | 1 | Gpq, Gpq |
236/// | 2 | Gpq, Mem |
237/// +---+----------+
238/// ```
239pub trait VmwriteEmitter<A, B> {
240 fn vmwrite(&mut self, op0: A, op1: B);
241}
242
243impl<'a> VmwriteEmitter<Gpq, Gpq> for Assembler<'a> {
244 fn vmwrite(&mut self, op0: Gpq, op1: Gpq) {
245 self.emit(VMWRITERR, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
246 }
247}
248
249impl<'a> VmwriteEmitter<Gpq, Mem> for Assembler<'a> {
250 fn vmwrite(&mut self, op0: Gpq, op1: Mem) {
251 self.emit(VMWRITERM, op0.as_operand(), op1.as_operand(), &NOREG, &NOREG);
252 }
253}
254
255/// `VMXOFF`.
256///
257/// Supported operand variants:
258///
259/// ```text
260/// +---+----------+
261/// | # | Operands |
262/// +---+----------+
263/// | 1 | (none) |
264/// +---+----------+
265/// ```
266pub trait VmxoffEmitter {
267 fn vmxoff(&mut self);
268}
269
270impl<'a> VmxoffEmitter for Assembler<'a> {
271 fn vmxoff(&mut self) {
272 self.emit(VMXOFF, &NOREG, &NOREG, &NOREG, &NOREG);
273 }
274}
275
276/// `VMXON`.
277///
278/// Supported operand variants:
279///
280/// ```text
281/// +---+----------+
282/// | # | Operands |
283/// +---+----------+
284/// | 1 | Mem |
285/// +---+----------+
286/// ```
287pub trait VmxonEmitter<A> {
288 fn vmxon(&mut self, op0: A);
289}
290
291impl<'a> VmxonEmitter<Mem> for Assembler<'a> {
292 fn vmxon(&mut self, op0: Mem) {
293 self.emit(VMXONM, op0.as_operand(), &NOREG, &NOREG, &NOREG);
294 }
295}
296
297
298impl<'a> Assembler<'a> {
299 /// `INVEPT`.
300 ///
301 /// Supported operand variants:
302 ///
303 /// ```text
304 /// +---+----------+
305 /// | # | Operands |
306 /// +---+----------+
307 /// | 1 | Gpq, Mem |
308 /// +---+----------+
309 /// ```
310 #[inline]
311 pub fn invept<A, B>(&mut self, op0: A, op1: B)
312 where Assembler<'a>: InveptEmitter<A, B> {
313 <Self as InveptEmitter<A, B>>::invept(self, op0, op1);
314 }
315 /// `INVVPID`.
316 ///
317 /// Supported operand variants:
318 ///
319 /// ```text
320 /// +---+----------+
321 /// | # | Operands |
322 /// +---+----------+
323 /// | 1 | Gpq, Mem |
324 /// +---+----------+
325 /// ```
326 #[inline]
327 pub fn invvpid<A, B>(&mut self, op0: A, op1: B)
328 where Assembler<'a>: InvvpidEmitter<A, B> {
329 <Self as InvvpidEmitter<A, B>>::invvpid(self, op0, op1);
330 }
331 /// `VMCALL`.
332 ///
333 /// Supported operand variants:
334 ///
335 /// ```text
336 /// +---+----------+
337 /// | # | Operands |
338 /// +---+----------+
339 /// | 1 | (none) |
340 /// +---+----------+
341 /// ```
342 #[inline]
343 pub fn vmcall(&mut self)
344 where Assembler<'a>: VmcallEmitter {
345 <Self as VmcallEmitter>::vmcall(self);
346 }
347 /// `VMCLEAR`.
348 ///
349 /// Supported operand variants:
350 ///
351 /// ```text
352 /// +---+----------+
353 /// | # | Operands |
354 /// +---+----------+
355 /// | 1 | Mem |
356 /// +---+----------+
357 /// ```
358 #[inline]
359 pub fn vmclear<A>(&mut self, op0: A)
360 where Assembler<'a>: VmclearEmitter<A> {
361 <Self as VmclearEmitter<A>>::vmclear(self, op0);
362 }
363 /// `VMFUNC`.
364 ///
365 /// Supported operand variants:
366 ///
367 /// ```text
368 /// +---+----------+
369 /// | # | Operands |
370 /// +---+----------+
371 /// | 1 | (none) |
372 /// +---+----------+
373 /// ```
374 #[inline]
375 pub fn vmfunc(&mut self)
376 where Assembler<'a>: VmfuncEmitter {
377 <Self as VmfuncEmitter>::vmfunc(self);
378 }
379 /// `VMLAUNCH`.
380 ///
381 /// Supported operand variants:
382 ///
383 /// ```text
384 /// +---+----------+
385 /// | # | Operands |
386 /// +---+----------+
387 /// | 1 | (none) |
388 /// +---+----------+
389 /// ```
390 #[inline]
391 pub fn vmlaunch(&mut self)
392 where Assembler<'a>: VmlaunchEmitter {
393 <Self as VmlaunchEmitter>::vmlaunch(self);
394 }
395 /// `VMPTRLD`.
396 ///
397 /// Supported operand variants:
398 ///
399 /// ```text
400 /// +---+----------+
401 /// | # | Operands |
402 /// +---+----------+
403 /// | 1 | Mem |
404 /// +---+----------+
405 /// ```
406 #[inline]
407 pub fn vmptrld<A>(&mut self, op0: A)
408 where Assembler<'a>: VmptrldEmitter<A> {
409 <Self as VmptrldEmitter<A>>::vmptrld(self, op0);
410 }
411 /// `VMPTRST`.
412 ///
413 /// Supported operand variants:
414 ///
415 /// ```text
416 /// +---+----------+
417 /// | # | Operands |
418 /// +---+----------+
419 /// | 1 | Mem |
420 /// +---+----------+
421 /// ```
422 #[inline]
423 pub fn vmptrst<A>(&mut self, op0: A)
424 where Assembler<'a>: VmptrstEmitter<A> {
425 <Self as VmptrstEmitter<A>>::vmptrst(self, op0);
426 }
427 /// `VMREAD`.
428 ///
429 /// Supported operand variants:
430 ///
431 /// ```text
432 /// +---+----------+
433 /// | # | Operands |
434 /// +---+----------+
435 /// | 1 | Gpq, Gpq |
436 /// | 2 | Mem, Gpq |
437 /// +---+----------+
438 /// ```
439 #[inline]
440 pub fn vmread<A, B>(&mut self, op0: A, op1: B)
441 where Assembler<'a>: VmreadEmitter<A, B> {
442 <Self as VmreadEmitter<A, B>>::vmread(self, op0, op1);
443 }
444 /// `VMRESUME`.
445 ///
446 /// Supported operand variants:
447 ///
448 /// ```text
449 /// +---+----------+
450 /// | # | Operands |
451 /// +---+----------+
452 /// | 1 | (none) |
453 /// +---+----------+
454 /// ```
455 #[inline]
456 pub fn vmresume(&mut self)
457 where Assembler<'a>: VmresumeEmitter {
458 <Self as VmresumeEmitter>::vmresume(self);
459 }
460 /// `VMWRITE`.
461 ///
462 /// Supported operand variants:
463 ///
464 /// ```text
465 /// +---+----------+
466 /// | # | Operands |
467 /// +---+----------+
468 /// | 1 | Gpq, Gpq |
469 /// | 2 | Gpq, Mem |
470 /// +---+----------+
471 /// ```
472 #[inline]
473 pub fn vmwrite<A, B>(&mut self, op0: A, op1: B)
474 where Assembler<'a>: VmwriteEmitter<A, B> {
475 <Self as VmwriteEmitter<A, B>>::vmwrite(self, op0, op1);
476 }
477 /// `VMXOFF`.
478 ///
479 /// Supported operand variants:
480 ///
481 /// ```text
482 /// +---+----------+
483 /// | # | Operands |
484 /// +---+----------+
485 /// | 1 | (none) |
486 /// +---+----------+
487 /// ```
488 #[inline]
489 pub fn vmxoff(&mut self)
490 where Assembler<'a>: VmxoffEmitter {
491 <Self as VmxoffEmitter>::vmxoff(self);
492 }
493 /// `VMXON`.
494 ///
495 /// Supported operand variants:
496 ///
497 /// ```text
498 /// +---+----------+
499 /// | # | Operands |
500 /// +---+----------+
501 /// | 1 | Mem |
502 /// +---+----------+
503 /// ```
504 #[inline]
505 pub fn vmxon<A>(&mut self, op0: A)
506 where Assembler<'a>: VmxonEmitter<A> {
507 <Self as VmxonEmitter<A>>::vmxon(self, op0);
508 }
509}