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}