osom_encoders_x86_64/models/
gpr.rs1use core::mem::transmute;
2
3use super::{GPRKind, Size};
4
5#[repr(u8)]
7#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
8#[must_use]
9pub enum GPR {
10 RAX = 1, RBX = 2,
12 RCX = 3,
13 RDX = 4,
14 RSI = 5,
15 RDI = 6,
16 RBP = 7,
17 RSP = 8,
18 R8 = 9,
19 R9 = 10,
20 R10 = 11,
21 R11 = 12,
22 R12 = 13,
23 R13 = 14,
24 R14 = 15,
25 R15 = 16,
26
27 EAX = 17,
28 EBX = 18,
29 ECX = 19,
30 EDX = 20,
31 ESI = 21,
32 EDI = 22,
33 EBP = 23,
34 ESP = 24,
35 R8D = 25,
36 R9D = 26,
37 R10D = 27,
38 R11D = 28,
39 R12D = 29,
40 R13D = 30,
41 R14D = 31,
42 R15D = 32,
43
44 AX = 33,
45 BX = 34,
46 CX = 35,
47 DX = 36,
48 SI = 37,
49 DI = 38,
50 BP = 39,
51 SP = 40,
52 R8W = 41,
53 R9W = 42,
54 R10W = 43,
55 R11W = 44,
56 R12W = 45,
57 R13W = 46,
58 R14W = 47,
59 R15W = 48,
60
61 AL = 49,
62 BL = 50,
63 CL = 51,
64 DL = 52,
65 SIL = 53,
66 DIL = 54,
67 BPL = 55,
68 SPL = 56,
69 R8B = 57,
70 R9B = 58,
71 R10B = 59,
72 R11B = 60,
73 R12B = 61,
74 R13B = 62,
75 R14B = 63,
76 R15B = 64,
77
78 AH = 65,
79 BH = 66,
80 CH = 67,
81 DH = 68,
82}
83
84impl GPR {
85 #[inline(always)]
87 #[must_use]
88 pub const fn equals(self, other: Self) -> bool {
89 self.as_u8() == other.as_u8()
90 }
91
92 pub const fn kind(self) -> GPRKind {
94 match self {
95 Self::AH | Self::BH | Self::CH | Self::DH => GPRKind::Bit8High,
96 Self::AL
97 | Self::CL
98 | Self::DL
99 | Self::BL
100 | Self::SPL
101 | Self::BPL
102 | Self::SIL
103 | Self::DIL
104 | Self::R8B
105 | Self::R9B
106 | Self::R10B
107 | Self::R11B
108 | Self::R12B
109 | Self::R13B
110 | Self::R14B
111 | Self::R15B => GPRKind::Bit8,
112 Self::AX
113 | Self::CX
114 | Self::DX
115 | Self::BX
116 | Self::SP
117 | Self::BP
118 | Self::SI
119 | Self::DI
120 | Self::R8W
121 | Self::R9W
122 | Self::R10W
123 | Self::R11W
124 | Self::R12W
125 | Self::R13W
126 | Self::R14W
127 | Self::R15W => GPRKind::Bit16,
128 Self::EAX
129 | Self::ECX
130 | Self::EDX
131 | Self::EBX
132 | Self::ESP
133 | Self::EBP
134 | Self::ESI
135 | Self::EDI
136 | Self::R8D
137 | Self::R9D
138 | Self::R10D
139 | Self::R11D
140 | Self::R12D
141 | Self::R13D
142 | Self::R14D
143 | Self::R15D => GPRKind::Bit32,
144 Self::RAX
145 | Self::RCX
146 | Self::RDX
147 | Self::RBX
148 | Self::RSP
149 | Self::RBP
150 | Self::RSI
151 | Self::RDI
152 | Self::R8
153 | Self::R9
154 | Self::R10
155 | Self::R11
156 | Self::R12
157 | Self::R13
158 | Self::R14
159 | Self::R15 => GPRKind::Bit64,
160 }
161 }
162
163 pub const fn size(self) -> Size {
165 match self {
166 Self::AH
167 | Self::BH
168 | Self::CH
169 | Self::DH
170 | Self::AL
171 | Self::CL
172 | Self::DL
173 | Self::BL
174 | Self::SPL
175 | Self::BPL
176 | Self::SIL
177 | Self::DIL
178 | Self::R8B
179 | Self::R9B
180 | Self::R10B
181 | Self::R11B
182 | Self::R12B
183 | Self::R13B
184 | Self::R14B
185 | Self::R15B => Size::Bit8,
186 Self::AX
187 | Self::CX
188 | Self::DX
189 | Self::BX
190 | Self::SP
191 | Self::BP
192 | Self::SI
193 | Self::DI
194 | Self::R8W
195 | Self::R9W
196 | Self::R10W
197 | Self::R11W
198 | Self::R12W
199 | Self::R13W
200 | Self::R14W
201 | Self::R15W => Size::Bit16,
202 Self::EAX
203 | Self::ECX
204 | Self::EDX
205 | Self::EBX
206 | Self::ESP
207 | Self::EBP
208 | Self::ESI
209 | Self::EDI
210 | Self::R8D
211 | Self::R9D
212 | Self::R10D
213 | Self::R11D
214 | Self::R12D
215 | Self::R13D
216 | Self::R14D
217 | Self::R15D => Size::Bit32,
218 Self::RAX
219 | Self::RCX
220 | Self::RDX
221 | Self::RBX
222 | Self::RSP
223 | Self::RBP
224 | Self::RSI
225 | Self::RDI
226 | Self::R8
227 | Self::R9
228 | Self::R10
229 | Self::R11
230 | Self::R12
231 | Self::R13
232 | Self::R14
233 | Self::R15 => Size::Bit64,
234 }
235 }
236
237 #[must_use]
240 pub(crate) const fn index(self) -> u8 {
241 match self {
242 Self::RAX | Self::EAX | Self::AX | Self::AL => 0,
243 Self::RCX | Self::ECX | Self::CX | Self::CL => 1,
244 Self::RDX | Self::EDX | Self::DX | Self::DL => 2,
245 Self::RBX | Self::EBX | Self::BX | Self::BL => 3,
246 Self::RSP | Self::ESP | Self::SP | Self::SPL | Self::AH => 4,
247 Self::RBP | Self::EBP | Self::BP | Self::BPL | Self::CH => 5,
248 Self::RSI | Self::ESI | Self::SI | Self::SIL | Self::DH => 6,
249 Self::RDI | Self::EDI | Self::DI | Self::DIL | Self::BH => 7,
250 Self::R8 | Self::R8D | Self::R8W | Self::R8B => 8,
251 Self::R9 | Self::R9D | Self::R9W | Self::R9B => 9,
252 Self::R10 | Self::R10D | Self::R10W | Self::R10B => 10,
253 Self::R11 | Self::R11D | Self::R11W | Self::R11B => 11,
254 Self::R12 | Self::R12D | Self::R12W | Self::R12B => 12,
255 Self::R13 | Self::R13D | Self::R13W | Self::R13B => 13,
256 Self::R14 | Self::R14D | Self::R14W | Self::R14B => 14,
257 Self::R15 | Self::R15D | Self::R15W | Self::R15B => 15,
258 }
259 }
260
261 #[inline(always)]
264 #[must_use]
265 pub(crate) const fn is_extended(self) -> bool {
266 self.index() > 0b111
267 }
268
269 #[inline(always)]
271 #[must_use]
272 pub(crate) const fn lower_3_bits_index(self) -> u8 {
273 self.index() & 0b111
274 }
275
276 #[inline(always)]
283 #[must_use]
284 pub(crate) const fn index_matches_bit8_high(self) -> bool {
285 let idx = self.index();
286 idx >= 4 && idx <= 7
287 }
288
289 #[inline(always)]
290 #[must_use]
291 pub(crate) const fn as_u8(self) -> u8 {
292 unsafe {
293 let result = transmute::<Self, u8>(self);
294 core::hint::assert_unchecked(result > 0);
295 core::hint::assert_unchecked(result <= 68);
296 result
297 }
298 }
299
300 #[inline]
301 #[allow(dead_code)]
302 pub(crate) const fn from_u8(value: u8) -> Self {
303 debug_assert!(value > 0 && value <= 68, "Invalid GPR value");
304 unsafe { transmute(value) }
305 }
306}