Skip to main content

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}