Skip to main content

asmkit/x86/features/
586.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/// `CMPXCHG16BM`.
11///
12/// Supported operand variants:
13///
14/// ```text
15/// +---+----------+
16/// | # | Operands |
17/// +---+----------+
18/// | 1 | Mem      |
19/// +---+----------+
20/// ```
21pub trait Cmpxchg16bmEmitter<A> {
22    fn cmpxchg16bm(&mut self, op0: A);
23}
24
25impl<'a> Cmpxchg16bmEmitter<Mem> for Assembler<'a> {
26    fn cmpxchg16bm(&mut self, op0: Mem) {
27        self.emit(CMPXCHG16BM, op0.as_operand(), &NOREG, &NOREG, &NOREG);
28    }
29}
30
31/// `CMPXCHG8BM`.
32///
33/// Supported operand variants:
34///
35/// ```text
36/// +---+----------+
37/// | # | Operands |
38/// +---+----------+
39/// | 1 | Mem      |
40/// +---+----------+
41/// ```
42pub trait Cmpxchg8bmEmitter<A> {
43    fn cmpxchg8bm(&mut self, op0: A);
44}
45
46impl<'a> Cmpxchg8bmEmitter<Mem> for Assembler<'a> {
47    fn cmpxchg8bm(&mut self, op0: Mem) {
48        self.emit(CMPXCHG8BM, op0.as_operand(), &NOREG, &NOREG, &NOREG);
49    }
50}
51
52/// `CMPXCHGD`.
53///
54/// Supported operand variants:
55///
56/// ```text
57/// +---+----------+
58/// | # | Operands |
59/// +---+----------+
60/// | 1 | Mem      |
61/// +---+----------+
62/// ```
63pub trait CmpxchgdEmitter<A> {
64    fn cmpxchgd(&mut self, op0: A);
65}
66
67impl<'a> CmpxchgdEmitter<Mem> for Assembler<'a> {
68    fn cmpxchgd(&mut self, op0: Mem) {
69        self.emit(CMPXCHGD32M, op0.as_operand(), &NOREG, &NOREG, &NOREG);
70    }
71}
72
73/// `CPUID` (CPUID). 
74/// The ID flag (bit 21) in the EFLAGS register indicates support for the CPUID instruction. If a software procedure can set and clear this flag, the processor executing the procedure supports the CPUID instruction. This instruction operates the same in non-64-bit modes and 64-bit mode.
75///
76///
77/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/CPUID.html).
78///
79/// Supported operand variants:
80///
81/// ```text
82/// +---+----------+
83/// | # | Operands |
84/// +---+----------+
85/// | 1 | (none)   |
86/// +---+----------+
87/// ```
88pub trait CpuidEmitter {
89    fn cpuid(&mut self);
90}
91
92impl<'a> CpuidEmitter for Assembler<'a> {
93    fn cpuid(&mut self) {
94        self.emit(CPUID, &NOREG, &NOREG, &NOREG, &NOREG);
95    }
96}
97
98/// `RDMSR`.
99///
100/// Supported operand variants:
101///
102/// ```text
103/// +---+----------+
104/// | # | Operands |
105/// +---+----------+
106/// | 1 | (none)   |
107/// +---+----------+
108/// ```
109pub trait RdmsrEmitter {
110    fn rdmsr(&mut self);
111}
112
113impl<'a> RdmsrEmitter for Assembler<'a> {
114    fn rdmsr(&mut self) {
115        self.emit(RDMSR, &NOREG, &NOREG, &NOREG, &NOREG);
116    }
117}
118
119/// `RDTSC` (RDTSC). 
120/// Reads the current value of the processor’s time-stamp counter (a 64-bit MSR) into the EDX:EAX registers. The EDX register is loaded with the high-order 32 bits of the MSR and the EAX register is loaded with the low-order 32 bits. (On processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are cleared.)
121///
122///
123/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/RDTSC.html).
124///
125/// Supported operand variants:
126///
127/// ```text
128/// +---+----------+
129/// | # | Operands |
130/// +---+----------+
131/// | 1 | (none)   |
132/// +---+----------+
133/// ```
134pub trait RdtscEmitter {
135    fn rdtsc(&mut self);
136}
137
138impl<'a> RdtscEmitter for Assembler<'a> {
139    fn rdtsc(&mut self) {
140        self.emit(RDTSC, &NOREG, &NOREG, &NOREG, &NOREG);
141    }
142}
143
144/// `RSM` (RSM). 
145/// Returns program control from system management mode (SMM) to the application program or operating-system procedure that was interrupted when the processor received an SMM interrupt. The processor’s state is restored from the dump created upon entering SMM. If the processor detects invalid state information during state restoration, it enters the shutdown state. The following invalid information can cause a shutdown
146///
147///
148/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/RSM.html).
149///
150/// Supported operand variants:
151///
152/// ```text
153/// +---+----------+
154/// | # | Operands |
155/// +---+----------+
156/// | 1 | (none)   |
157/// +---+----------+
158/// ```
159pub trait RsmEmitter {
160    fn rsm(&mut self);
161}
162
163impl<'a> RsmEmitter for Assembler<'a> {
164    fn rsm(&mut self) {
165        self.emit(RSM, &NOREG, &NOREG, &NOREG, &NOREG);
166    }
167}
168
169/// `WRMSR` (WRMSR). 
170/// Writes the contents of registers EDX:EAX into the 64-bit model specific register (MSR) specified in the ECX register. (On processors that support the Intel 64 architecture, the high-order 32 bits of RCX are ignored.) The contents of the EDX register are copied to high-order 32 bits of the selected MSR and the contents of the EAX register are copied to low-order 32 bits of the MSR. (On processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are ignored.) Undefined or reserved bits in an MSR should be set to values previously read.
171///
172///
173/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/WRMSR.html).
174///
175/// Supported operand variants:
176///
177/// ```text
178/// +---+----------+
179/// | # | Operands |
180/// +---+----------+
181/// | 1 | (none)   |
182/// +---+----------+
183/// ```
184pub trait WrmsrEmitter {
185    fn wrmsr(&mut self);
186}
187
188impl<'a> WrmsrEmitter for Assembler<'a> {
189    fn wrmsr(&mut self) {
190        self.emit(WRMSR, &NOREG, &NOREG, &NOREG, &NOREG);
191    }
192}
193
194
195impl<'a> Assembler<'a> {
196    /// `CMPXCHG16BM`.
197    ///
198    /// Supported operand variants:
199    ///
200    /// ```text
201    /// +---+----------+
202    /// | # | Operands |
203    /// +---+----------+
204    /// | 1 | Mem      |
205    /// +---+----------+
206    /// ```
207    #[inline]
208    pub fn cmpxchg16bm<A>(&mut self, op0: A)
209    where Assembler<'a>: Cmpxchg16bmEmitter<A> {
210        <Self as Cmpxchg16bmEmitter<A>>::cmpxchg16bm(self, op0);
211    }
212    /// `CMPXCHG8BM`.
213    ///
214    /// Supported operand variants:
215    ///
216    /// ```text
217    /// +---+----------+
218    /// | # | Operands |
219    /// +---+----------+
220    /// | 1 | Mem      |
221    /// +---+----------+
222    /// ```
223    #[inline]
224    pub fn cmpxchg8bm<A>(&mut self, op0: A)
225    where Assembler<'a>: Cmpxchg8bmEmitter<A> {
226        <Self as Cmpxchg8bmEmitter<A>>::cmpxchg8bm(self, op0);
227    }
228    /// `CMPXCHGD`.
229    ///
230    /// Supported operand variants:
231    ///
232    /// ```text
233    /// +---+----------+
234    /// | # | Operands |
235    /// +---+----------+
236    /// | 1 | Mem      |
237    /// +---+----------+
238    /// ```
239    #[inline]
240    pub fn cmpxchgd<A>(&mut self, op0: A)
241    where Assembler<'a>: CmpxchgdEmitter<A> {
242        <Self as CmpxchgdEmitter<A>>::cmpxchgd(self, op0);
243    }
244    /// `CPUID` (CPUID). 
245    /// The ID flag (bit 21) in the EFLAGS register indicates support for the CPUID instruction. If a software procedure can set and clear this flag, the processor executing the procedure supports the CPUID instruction. This instruction operates the same in non-64-bit modes and 64-bit mode.
246    ///
247    ///
248    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/CPUID.html).
249    ///
250    /// Supported operand variants:
251    ///
252    /// ```text
253    /// +---+----------+
254    /// | # | Operands |
255    /// +---+----------+
256    /// | 1 | (none)   |
257    /// +---+----------+
258    /// ```
259    #[inline]
260    pub fn cpuid(&mut self)
261    where Assembler<'a>: CpuidEmitter {
262        <Self as CpuidEmitter>::cpuid(self);
263    }
264    /// `RDMSR`.
265    ///
266    /// Supported operand variants:
267    ///
268    /// ```text
269    /// +---+----------+
270    /// | # | Operands |
271    /// +---+----------+
272    /// | 1 | (none)   |
273    /// +---+----------+
274    /// ```
275    #[inline]
276    pub fn rdmsr(&mut self)
277    where Assembler<'a>: RdmsrEmitter {
278        <Self as RdmsrEmitter>::rdmsr(self);
279    }
280    /// `RDTSC` (RDTSC). 
281    /// Reads the current value of the processor’s time-stamp counter (a 64-bit MSR) into the EDX:EAX registers. The EDX register is loaded with the high-order 32 bits of the MSR and the EAX register is loaded with the low-order 32 bits. (On processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are cleared.)
282    ///
283    ///
284    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/RDTSC.html).
285    ///
286    /// Supported operand variants:
287    ///
288    /// ```text
289    /// +---+----------+
290    /// | # | Operands |
291    /// +---+----------+
292    /// | 1 | (none)   |
293    /// +---+----------+
294    /// ```
295    #[inline]
296    pub fn rdtsc(&mut self)
297    where Assembler<'a>: RdtscEmitter {
298        <Self as RdtscEmitter>::rdtsc(self);
299    }
300    /// `RSM` (RSM). 
301    /// Returns program control from system management mode (SMM) to the application program or operating-system procedure that was interrupted when the processor received an SMM interrupt. The processor’s state is restored from the dump created upon entering SMM. If the processor detects invalid state information during state restoration, it enters the shutdown state. The following invalid information can cause a shutdown
302    ///
303    ///
304    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/RSM.html).
305    ///
306    /// Supported operand variants:
307    ///
308    /// ```text
309    /// +---+----------+
310    /// | # | Operands |
311    /// +---+----------+
312    /// | 1 | (none)   |
313    /// +---+----------+
314    /// ```
315    #[inline]
316    pub fn rsm(&mut self)
317    where Assembler<'a>: RsmEmitter {
318        <Self as RsmEmitter>::rsm(self);
319    }
320    /// `WRMSR` (WRMSR). 
321    /// Writes the contents of registers EDX:EAX into the 64-bit model specific register (MSR) specified in the ECX register. (On processors that support the Intel 64 architecture, the high-order 32 bits of RCX are ignored.) The contents of the EDX register are copied to high-order 32 bits of the selected MSR and the contents of the EAX register are copied to low-order 32 bits of the MSR. (On processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are ignored.) Undefined or reserved bits in an MSR should be set to values previously read.
322    ///
323    ///
324    /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/WRMSR.html).
325    ///
326    /// Supported operand variants:
327    ///
328    /// ```text
329    /// +---+----------+
330    /// | # | Operands |
331    /// +---+----------+
332    /// | 1 | (none)   |
333    /// +---+----------+
334    /// ```
335    #[inline]
336    pub fn wrmsr(&mut self)
337    where Assembler<'a>: WrmsrEmitter {
338        <Self as WrmsrEmitter>::wrmsr(self);
339    }
340}