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