asmkit/x86/features/UINTR.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/// `CLUI` (CLUI).
11/// CLUI clears the user interrupt flag (UIF). Its effect takes place immediately: a user interrupt cannot be delivered on the instruction boundary following CLUI.
12///
13///
14/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/CLUI.html).
15///
16/// Supported operand variants:
17///
18/// ```text
19/// +---+----------+
20/// | # | Operands |
21/// +---+----------+
22/// | 1 | (none) |
23/// +---+----------+
24/// ```
25pub trait CluiEmitter {
26 fn clui(&mut self);
27}
28
29impl<'a> CluiEmitter for Assembler<'a> {
30 fn clui(&mut self) {
31 self.emit(CLUI, &NOREG, &NOREG, &NOREG, &NOREG);
32 }
33}
34
35/// `SENDUIPI` (SENDUIPI).
36/// The SENDUIPI instruction sends the user interprocessor interrupt (IPI) indicated by its register operand. (The operand always has 64 bits; operand-size overrides such as the prefix 66 are ignored.)
37///
38///
39/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/SENDUIPI.html).
40///
41/// Supported operand variants:
42///
43/// ```text
44/// +---+----------+
45/// | # | Operands |
46/// +---+----------+
47/// | 1 | Gpq |
48/// +---+----------+
49/// ```
50pub trait SenduipiEmitter<A> {
51 fn senduipi(&mut self, op0: A);
52}
53
54impl<'a> SenduipiEmitter<Gpq> for Assembler<'a> {
55 fn senduipi(&mut self, op0: Gpq) {
56 self.emit(SENDUIPIR, op0.as_operand(), &NOREG, &NOREG, &NOREG);
57 }
58}
59
60/// `STUI` (STUI).
61/// STUI sets the user interrupt flag (UIF). Its effect takes place immediately; a user interrupt may be delivered on the instruction boundary following STUI. (This is in contrast with STI, whose effect is delayed by one instruction).
62///
63///
64/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/STUI.html).
65///
66/// Supported operand variants:
67///
68/// ```text
69/// +---+----------+
70/// | # | Operands |
71/// +---+----------+
72/// | 1 | (none) |
73/// +---+----------+
74/// ```
75pub trait StuiEmitter {
76 fn stui(&mut self);
77}
78
79impl<'a> StuiEmitter for Assembler<'a> {
80 fn stui(&mut self) {
81 self.emit(STUI, &NOREG, &NOREG, &NOREG, &NOREG);
82 }
83}
84
85/// `TESTUI`.
86///
87/// Supported operand variants:
88///
89/// ```text
90/// +---+----------+
91/// | # | Operands |
92/// +---+----------+
93/// | 1 | (none) |
94/// +---+----------+
95/// ```
96pub trait TestuiEmitter {
97 fn testui(&mut self);
98}
99
100impl<'a> TestuiEmitter for Assembler<'a> {
101 fn testui(&mut self) {
102 self.emit(TESTUI, &NOREG, &NOREG, &NOREG, &NOREG);
103 }
104}
105
106/// `UIRET` (UIRET).
107/// UIRET returns from the handling of a user interrupt. It can be executed regardless of CPL.
108///
109///
110/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/UIRET.html).
111///
112/// Supported operand variants:
113///
114/// ```text
115/// +---+----------+
116/// | # | Operands |
117/// +---+----------+
118/// | 1 | (none) |
119/// +---+----------+
120/// ```
121pub trait UiretEmitter {
122 fn uiret(&mut self);
123}
124
125impl<'a> UiretEmitter for Assembler<'a> {
126 fn uiret(&mut self) {
127 self.emit(UIRET, &NOREG, &NOREG, &NOREG, &NOREG);
128 }
129}
130
131
132impl<'a> Assembler<'a> {
133 /// `CLUI` (CLUI).
134 /// CLUI clears the user interrupt flag (UIF). Its effect takes place immediately: a user interrupt cannot be delivered on the instruction boundary following CLUI.
135 ///
136 ///
137 /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/CLUI.html).
138 ///
139 /// Supported operand variants:
140 ///
141 /// ```text
142 /// +---+----------+
143 /// | # | Operands |
144 /// +---+----------+
145 /// | 1 | (none) |
146 /// +---+----------+
147 /// ```
148 #[inline]
149 pub fn clui(&mut self)
150 where Assembler<'a>: CluiEmitter {
151 <Self as CluiEmitter>::clui(self);
152 }
153 /// `SENDUIPI` (SENDUIPI).
154 /// The SENDUIPI instruction sends the user interprocessor interrupt (IPI) indicated by its register operand. (The operand always has 64 bits; operand-size overrides such as the prefix 66 are ignored.)
155 ///
156 ///
157 /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/SENDUIPI.html).
158 ///
159 /// Supported operand variants:
160 ///
161 /// ```text
162 /// +---+----------+
163 /// | # | Operands |
164 /// +---+----------+
165 /// | 1 | Gpq |
166 /// +---+----------+
167 /// ```
168 #[inline]
169 pub fn senduipi<A>(&mut self, op0: A)
170 where Assembler<'a>: SenduipiEmitter<A> {
171 <Self as SenduipiEmitter<A>>::senduipi(self, op0);
172 }
173 /// `STUI` (STUI).
174 /// STUI sets the user interrupt flag (UIF). Its effect takes place immediately; a user interrupt may be delivered on the instruction boundary following STUI. (This is in contrast with STI, whose effect is delayed by one instruction).
175 ///
176 ///
177 /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/STUI.html).
178 ///
179 /// Supported operand variants:
180 ///
181 /// ```text
182 /// +---+----------+
183 /// | # | Operands |
184 /// +---+----------+
185 /// | 1 | (none) |
186 /// +---+----------+
187 /// ```
188 #[inline]
189 pub fn stui(&mut self)
190 where Assembler<'a>: StuiEmitter {
191 <Self as StuiEmitter>::stui(self);
192 }
193 /// `TESTUI`.
194 ///
195 /// Supported operand variants:
196 ///
197 /// ```text
198 /// +---+----------+
199 /// | # | Operands |
200 /// +---+----------+
201 /// | 1 | (none) |
202 /// +---+----------+
203 /// ```
204 #[inline]
205 pub fn testui(&mut self)
206 where Assembler<'a>: TestuiEmitter {
207 <Self as TestuiEmitter>::testui(self);
208 }
209 /// `UIRET` (UIRET).
210 /// UIRET returns from the handling of a user interrupt. It can be executed regardless of CPL.
211 ///
212 ///
213 /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/UIRET.html).
214 ///
215 /// Supported operand variants:
216 ///
217 /// ```text
218 /// +---+----------+
219 /// | # | Operands |
220 /// +---+----------+
221 /// | 1 | (none) |
222 /// +---+----------+
223 /// ```
224 #[inline]
225 pub fn uiret(&mut self)
226 where Assembler<'a>: UiretEmitter {
227 <Self as UiretEmitter>::uiret(self);
228 }
229}