asmkit/x86/features/HLERTM.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/// `XABORT` (XABORT).
11/// XABORT forces an RTM abort. Following an RTM abort, the logical processor resumes execution at the fallback address computed through the outermost XBEGIN instruction. The EAX register is updated to reflect an XABORT instruction caused the abort, and the imm8 argument will be provided in bits 31:24 of EAX.
12///
13///
14/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/XABORT.html).
15///
16/// Supported operand variants:
17///
18/// ```text
19/// +---+----------+
20/// | # | Operands |
21/// +---+----------+
22/// | 1 | Imm |
23/// +---+----------+
24/// ```
25pub trait XabortEmitter<A> {
26 fn xabort(&mut self, op0: A);
27}
28
29impl<'a> XabortEmitter<Imm> for Assembler<'a> {
30 fn xabort(&mut self, op0: Imm) {
31 self.emit(XABORTI, op0.as_operand(), &NOREG, &NOREG, &NOREG);
32 }
33}
34
35/// `XBEGIN` (XBEGIN).
36/// The XBEGIN instruction specifies the start of an RTM code region. If the logical processor was not already in transactional execution, then the XBEGIN instruction causes the logical processor to transition into transactional execution. The XBEGIN instruction that transitions the logical processor into transactional execution is referred to as the outermost XBEGIN instruction. The instruction also specifies a relative offset to compute the address of the fallback code path following a transactional abort. (Use of the 16-bit operand size does not cause this address to be truncated to 16 bits, unlike a near jump to a relative offset.)
37///
38///
39/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/XBEGIN.html).
40///
41/// Supported operand variants:
42///
43/// ```text
44/// +---+----------+
45/// | # | Operands |
46/// +---+----------+
47/// | 1 | Imm |
48/// | 2 | Label |
49/// | 3 | Sym |
50/// +---+----------+
51/// ```
52pub trait XbeginEmitter<A> {
53 fn xbegin(&mut self, op0: A);
54}
55
56impl<'a> XbeginEmitter<Imm> for Assembler<'a> {
57 fn xbegin(&mut self, op0: Imm) {
58 self.emit(XBEGIN, op0.as_operand(), &NOREG, &NOREG, &NOREG);
59 }
60}
61
62impl<'a> XbeginEmitter<Sym> for Assembler<'a> {
63 fn xbegin(&mut self, op0: Sym) {
64 self.emit(XBEGIN, op0.as_operand(), &NOREG, &NOREG, &NOREG);
65 }
66}
67
68impl<'a> XbeginEmitter<Label> for Assembler<'a> {
69 fn xbegin(&mut self, op0: Label) {
70 self.emit(XBEGIN, op0.as_operand(), &NOREG, &NOREG, &NOREG);
71 }
72}
73
74/// `XEND` (XEND).
75/// The instruction marks the end of an RTM code region. If this corresponds to the outermost scope (that is, including this XEND instruction, the number of XBEGIN instructions is the same as number of XEND instructions), the logical processor will attempt to commit the logical processor state atomically. If the commit fails, the logical processor will rollback all architectural register and memory updates performed during the RTM execution. The logical processor will resume execution at the fallback address computed from the outermost XBEGIN instruction. The EAX register is updated to reflect RTM abort information.
76///
77///
78/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/XEND.html).
79///
80/// Supported operand variants:
81///
82/// ```text
83/// +---+----------+
84/// | # | Operands |
85/// +---+----------+
86/// | 1 | (none) |
87/// +---+----------+
88/// ```
89pub trait XendEmitter {
90 fn xend(&mut self);
91}
92
93impl<'a> XendEmitter for Assembler<'a> {
94 fn xend(&mut self) {
95 self.emit(XEND, &NOREG, &NOREG, &NOREG, &NOREG);
96 }
97}
98
99/// `XTEST` (XTEST).
100/// The XTEST instruction queries the transactional execution status. If the instruction executes inside a transactionally executing RTM region or a transactionally executing HLE region, then the ZF flag is cleared, else it is set.
101///
102///
103/// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/XTEST.html).
104///
105/// Supported operand variants:
106///
107/// ```text
108/// +---+----------+
109/// | # | Operands |
110/// +---+----------+
111/// | 1 | (none) |
112/// +---+----------+
113/// ```
114pub trait XtestEmitter {
115 fn xtest(&mut self);
116}
117
118impl<'a> XtestEmitter for Assembler<'a> {
119 fn xtest(&mut self) {
120 self.emit(XTEST, &NOREG, &NOREG, &NOREG, &NOREG);
121 }
122}
123
124
125impl<'a> Assembler<'a> {
126 /// `XABORT` (XABORT).
127 /// XABORT forces an RTM abort. Following an RTM abort, the logical processor resumes execution at the fallback address computed through the outermost XBEGIN instruction. The EAX register is updated to reflect an XABORT instruction caused the abort, and the imm8 argument will be provided in bits 31:24 of EAX.
128 ///
129 ///
130 /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/XABORT.html).
131 ///
132 /// Supported operand variants:
133 ///
134 /// ```text
135 /// +---+----------+
136 /// | # | Operands |
137 /// +---+----------+
138 /// | 1 | Imm |
139 /// +---+----------+
140 /// ```
141 #[inline]
142 pub fn xabort<A>(&mut self, op0: A)
143 where Assembler<'a>: XabortEmitter<A> {
144 <Self as XabortEmitter<A>>::xabort(self, op0);
145 }
146 /// `XBEGIN` (XBEGIN).
147 /// The XBEGIN instruction specifies the start of an RTM code region. If the logical processor was not already in transactional execution, then the XBEGIN instruction causes the logical processor to transition into transactional execution. The XBEGIN instruction that transitions the logical processor into transactional execution is referred to as the outermost XBEGIN instruction. The instruction also specifies a relative offset to compute the address of the fallback code path following a transactional abort. (Use of the 16-bit operand size does not cause this address to be truncated to 16 bits, unlike a near jump to a relative offset.)
148 ///
149 ///
150 /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/XBEGIN.html).
151 ///
152 /// Supported operand variants:
153 ///
154 /// ```text
155 /// +---+----------+
156 /// | # | Operands |
157 /// +---+----------+
158 /// | 1 | Imm |
159 /// | 2 | Label |
160 /// | 3 | Sym |
161 /// +---+----------+
162 /// ```
163 #[inline]
164 pub fn xbegin<A>(&mut self, op0: A)
165 where Assembler<'a>: XbeginEmitter<A> {
166 <Self as XbeginEmitter<A>>::xbegin(self, op0);
167 }
168 /// `XEND` (XEND).
169 /// The instruction marks the end of an RTM code region. If this corresponds to the outermost scope (that is, including this XEND instruction, the number of XBEGIN instructions is the same as number of XEND instructions), the logical processor will attempt to commit the logical processor state atomically. If the commit fails, the logical processor will rollback all architectural register and memory updates performed during the RTM execution. The logical processor will resume execution at the fallback address computed from the outermost XBEGIN instruction. The EAX register is updated to reflect RTM abort information.
170 ///
171 ///
172 /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/XEND.html).
173 ///
174 /// Supported operand variants:
175 ///
176 /// ```text
177 /// +---+----------+
178 /// | # | Operands |
179 /// +---+----------+
180 /// | 1 | (none) |
181 /// +---+----------+
182 /// ```
183 #[inline]
184 pub fn xend(&mut self)
185 where Assembler<'a>: XendEmitter {
186 <Self as XendEmitter>::xend(self);
187 }
188 /// `XTEST` (XTEST).
189 /// The XTEST instruction queries the transactional execution status. If the instruction executes inside a transactionally executing RTM region or a transactionally executing HLE region, then the ZF flag is cleared, else it is set.
190 ///
191 ///
192 /// For more details, see the [Intel manual](https://www.felixcloutier.com/x86/XTEST.html).
193 ///
194 /// Supported operand variants:
195 ///
196 /// ```text
197 /// +---+----------+
198 /// | # | Operands |
199 /// +---+----------+
200 /// | 1 | (none) |
201 /// +---+----------+
202 /// ```
203 #[inline]
204 pub fn xtest(&mut self)
205 where Assembler<'a>: XtestEmitter {
206 <Self as XtestEmitter>::xtest(self);
207 }
208}