1#[derive(Debug, Hash, PartialEq, Eq, Copy, Clone)]
2#[non_exhaustive]
3pub enum X86RegisterClass {
4 Byte,
5 ByteRex,
6 Word,
7 Double,
8 Quad,
9 Mmx,
10 Xmm,
11 Ymm,
12 Zmm,
13 Tmm,
14 Sreg,
15 Cr,
16 Dr,
17 Tr,
18 St,
19 AvxMask,
20}
21
22impl X86RegisterClass {
23 pub fn size(&self, mode: X86Mode) -> usize {
24 match self {
25 Self::Byte | Self::ByteRex => 1,
26 Self::Word | Self::Sreg => 2,
27 Self::Double | Self::Tr | Self::Dr => 4,
28 Self::Quad | Self::Mmx => 8,
29 Self::Xmm => 16,
30 Self::Ymm => 32,
31 Self::Zmm => 64,
32 Self::Tmm => 1024,
33 Self::Cr if mode == X86Mode::Long => 8,
34 Self::Cr => 4,
35 Self::St => 10,
36 Self::AvxMask => 8,
37 }
38 }
39
40 pub fn gpr_size(size: usize, mode: X86Mode) -> Option<X86RegisterClass> {
41 match size {
42 1 if mode == X86Mode::Long => Some(X86RegisterClass::ByteRex),
43 1 => Some(X86RegisterClass::Byte),
44 2 => Some(X86RegisterClass::Word),
45 4 => Some(X86RegisterClass::Double),
46 8 => Some(X86RegisterClass::Quad),
47 _ => None,
48 }
49 }
50}
51
52#[derive(Debug, Hash, PartialEq, Eq, Copy, Clone)]
53#[non_exhaustive]
54pub enum X86Register {
55 Al,
57 Cl,
58 Dl,
59 Bl,
60
61 Ah,
63 Ch,
64 Dh,
65 Bh,
66 Spl,
68 Bpl,
69 Sil,
70 Dil,
71
72 R8b,
74 R9b,
75 R10b,
76 R11b,
77 R12b,
78 R13b,
79 R14b,
80 R15b,
81
82 Ax,
84 Cx,
85 Dx,
86 Bx,
87 Sp,
88 Bp,
89 Si,
90 Di,
91
92 R8w,
94 R9w,
95 R10w,
96 R11w,
97 R12w,
98 R13w,
99 R14w,
100 R15w,
101
102 Eax,
104 Ecx,
105 Edx,
106 Ebx,
107 Esp,
108 Ebp,
109 Esi,
110 Edi,
111
112 R8d,
114 R9d,
115 R10d,
116 R11d,
117 R12d,
118 R13d,
119 R14d,
120 R15d,
121
122 Rax,
124 Rcx,
125 Rdx,
126 Rbx,
127 Rsp,
128 Rbp,
129 Rsi,
130 Rdi,
131
132 R8,
134 R9,
135 R10,
136 R11,
137 R12,
138 R13,
139 R14,
140 R15,
141
142 Mmx(u8),
143
144 Xmm(u8),
145 Ymm(u8),
146 Zmm(u8),
147 Tmm(u8),
148
149 Cr(u8),
150 Dr(u8),
151 Tr(u8),
152
153 Fp(u8),
154
155 K(u8),
156
157 Es,
158 Cs,
159 Ss,
160 Ds,
161 Fs,
162 Gs,
163 UndefSeg,
164}
165
166use std::{collections::HashMap, fmt::Display};
167
168macro_rules! define_x86_registers{
169 {
170 $(regs [$($regs:expr),*]: $class:ident ;)*
171 } => {
172 lazy_static::lazy_static!{
173 static ref X86REGISTERS: HashMap<X86RegisterClass,&'static [X86Register]> = {
174 let mut map = HashMap::<X86RegisterClass,&'static [X86Register]>::new();
175 $({
176 map.insert(X86RegisterClass:: $class, &[$($regs),*]);
177 })*
178
179 map
180 };
181 }
182 }
183}
184
185use X86Register::*;
186
187use self::insn::X86Mode;
188
189define_x86_registers! {
190 regs [Al, Cl, Dl, Bl, Ah, Ch, Dh, Bh]: Byte;
191 regs [Al, Cl, Dl, Bl, Spl, Bpl, Sil, Dil, R8b, R9b, R10b, R11b, R12b, R13b, R14b, R15b]: ByteRex;
192 regs [Ax, Cx, Dx, Bx, Sp, Bp, Si, Di, R8w, R9w, R10w, R11w, R12w, R13w, R14w, R15w]: Word;
193 regs [Eax, Ecx, Edx, Ebx, Esp, Ebp, Esi, Edi, R8d, R9d, R10d, R11d, R12d, R13d, R14d, R15d]: Double;
194 regs [Rax, Rcx, Rdx, Rbx, Rsp, Rbp, Rsi, Rdi, R8, R9, R10, R11, R12, R13, R14, R15]: Quad;
195 regs [Mmx(0), Mmx(1), Mmx(2), Mmx(3), Mmx(4), Mmx(5), Mmx(6), Mmx(7), Mmx(0), Mmx(1), Mmx(2), Mmx(3), Mmx(4), Mmx(5), Mmx(6), Mmx(7)]: Mmx;
196 regs [Xmm(0), Xmm(1), Xmm(2), Xmm(3), Xmm(4), Xmm(5), Xmm(6), Xmm(7), Xmm(8), Xmm(9), Xmm(10), Xmm(11), Xmm(12), Xmm(13), Xmm(14), Xmm(15),
197 Xmm(16), Xmm(17), Xmm(18), Xmm(19), Xmm(20), Xmm(21), Xmm(22), Xmm(23), Xmm(24), Xmm(25), Xmm(26), Xmm(27), Xmm(28), Xmm(29), Xmm(30), Xmm(31)]: Xmm;
198 regs [Ymm(0), Ymm(1), Ymm(2), Ymm(3), Ymm(4), Ymm(5), Ymm(6), Ymm(7), Ymm(8), Ymm(9), Ymm(10), Ymm(11), Ymm(12), Ymm(13), Ymm(14), Ymm(15),
199 Ymm(16), Ymm(17), Ymm(18), Ymm(19), Ymm(20), Ymm(21), Ymm(22), Ymm(23), Ymm(24), Ymm(25), Ymm(26), Ymm(27), Ymm(28), Ymm(29), Ymm(30), Ymm(31)]: Ymm;
200 regs [Zmm(0), Zmm(1), Zmm(2), Zmm(3), Zmm(4), Zmm(5), Zmm(6), Zmm(7), Zmm(8), Zmm(9), Zmm(10), Zmm(11), Zmm(12), Zmm(13), Zmm(14), Zmm(15),
201 Zmm(16), Zmm(17), Zmm(18), Zmm(19), Zmm(20), Zmm(21), Zmm(22), Zmm(23), Zmm(24), Zmm(25), Zmm(26), Zmm(27), Zmm(28), Zmm(29), Zmm(30), Zmm(31)]: Zmm;
202 regs [Tmm(0), Tmm(1), Tmm(2), Tmm(3), Tmm(4), Tmm(5), Tmm(6), Tmm(7)]: Tmm;
203 regs [Es, Cs, Ss, Ds, Fs, Gs, UndefSeg, UndefSeg, Es, Cs, Ss, Ds, Fs, Gs, UndefSeg, UndefSeg]: Sreg;
204 regs [Cr(0), Cr(1), Cr(2), Cr(3), Cr(4), Cr(5), Cr(6), Cr(7), Cr(8), Cr(9), Cr(10), Cr(11), Cr(12), Cr(13), Cr(14), Cr(15)]: Cr;
205 regs [Dr(0), Dr(1), Dr(2), Dr(3), Dr(4), Dr(5), Dr(6), Dr(7), Dr(8), Dr(9), Dr(10), Dr(11), Dr(12), Dr(13), Dr(14), Dr(15)]: Dr;
206 regs [Tr(0), Tr(1), Tr(2), Tr(3), Tr(4), Tr(5), Tr(6), Tr(7)]: Tr;
207 regs [Fp(0), Fp(1), Fp(2), Fp(3), Fp(4), Fp(5), Fp(6), Fp(7),Fp(0), Fp(1), Fp(2), Fp(3), Fp(4), Fp(5), Fp(6), Fp(7)]: St;
208 regs [K(0), K(1), K(2), K(3), K(4), K(5), K(6), K(7)]: AvxMask;
209}
210
211impl X86Register {
212 pub fn from_class(rclass: X86RegisterClass, rnum: u8) -> Option<X86Register> {
213 X86REGISTERS[&rclass].get(rnum as usize).copied()
214 }
215
216 pub fn regnum(self) -> u8 {
217 match self {
218 Al => 0,
219 Cl => 1,
220 Dl => 2,
221 Bl => 3,
222 Ah => 4,
223 Ch => 5,
224 Dh => 6,
225 Bh => 7,
226 Spl => 4,
227 Bpl => 5,
228 Sil => 6,
229 Dil => 7,
230 R8b => 8,
231 R9b => 9,
232 R10b => 10,
233 R11b => 11,
234 R12b => 12,
235 R13b => 13,
236 R14b => 14,
237 R15b => 15,
238 Ax => 0,
239 Cx => 1,
240 Dx => 2,
241 Bx => 3,
242 Sp => 4,
243 Bp => 5,
244 Si => 6,
245 Di => 7,
246 R8w => 8,
247 R9w => 9,
248 R10w => 10,
249 R11w => 11,
250 R12w => 12,
251 R13w => 13,
252 R14w => 14,
253 R15w => 15,
254 Eax => 0,
255 Ecx => 1,
256 Edx => 2,
257 Ebx => 3,
258 Esp => 4,
259 Ebp => 5,
260 Esi => 6,
261 Edi => 7,
262 R8d => 8,
263 R9d => 9,
264 R10d => 10,
265 R11d => 11,
266 R12d => 12,
267 R13d => 13,
268 R14d => 14,
269 R15d => 15,
270 Rax => 0,
271 Rcx => 1,
272 Rdx => 2,
273 Rbx => 3,
274 Rsp => 4,
275 Rbp => 5,
276 Rsi => 6,
277 Rdi => 7,
278 R8 => 8,
279 R9 => 9,
280 R10 => 10,
281 R11 => 11,
282 R12 => 12,
283 R13 => 13,
284 R14 => 14,
285 R15 => 15,
286 Mmx(m) => m,
287 Xmm(m) => m,
288 Ymm(m) => m,
289 Zmm(m) => m,
290 Tmm(m) => m,
291 Cr(m) => m,
292 Dr(m) => m,
293 Tr(m) => m,
294 Fp(m) => m,
295 K(m) => m,
296 Es => 0,
297 Cs => 1,
298 Ss => 2,
299 Ds => 3,
300 Fs => 4,
301 Gs => 5,
302 UndefSeg => 255,
303 }
304 }
305
306 pub fn class(&self) -> X86RegisterClass {
307 match self {
308 Al => X86RegisterClass::Byte,
309 Cl => X86RegisterClass::Byte,
310 Dl => X86RegisterClass::Byte,
311 Bl => X86RegisterClass::Byte,
312 Ah => X86RegisterClass::Byte,
313 Ch => X86RegisterClass::Byte,
314 Dh => X86RegisterClass::Byte,
315 Bh => X86RegisterClass::Byte,
316 Spl => X86RegisterClass::ByteRex,
317 Bpl => X86RegisterClass::ByteRex,
318 Sil => X86RegisterClass::ByteRex,
319 Dil => X86RegisterClass::ByteRex,
320 R8b => X86RegisterClass::ByteRex,
321 R9b => X86RegisterClass::ByteRex,
322 R10b => X86RegisterClass::ByteRex,
323 R11b => X86RegisterClass::ByteRex,
324 R12b => X86RegisterClass::ByteRex,
325 R13b => X86RegisterClass::ByteRex,
326 R14b => X86RegisterClass::ByteRex,
327 R15b => X86RegisterClass::ByteRex,
328 Ax => X86RegisterClass::Word,
329 Cx => X86RegisterClass::Word,
330 Dx => X86RegisterClass::Word,
331 Bx => X86RegisterClass::Word,
332 Sp => X86RegisterClass::Word,
333 Bp => X86RegisterClass::Word,
334 Si => X86RegisterClass::Word,
335 Di => X86RegisterClass::Word,
336 R8w => X86RegisterClass::Word,
337 R9w => X86RegisterClass::Word,
338 R10w => X86RegisterClass::Word,
339 R11w => X86RegisterClass::Word,
340 R12w => X86RegisterClass::Word,
341 R13w => X86RegisterClass::Word,
342 R14w => X86RegisterClass::Word,
343 R15w => X86RegisterClass::Word,
344 Eax => X86RegisterClass::Double,
345 Ecx => X86RegisterClass::Double,
346 Edx => X86RegisterClass::Double,
347 Ebx => X86RegisterClass::Double,
348 Esp => X86RegisterClass::Double,
349 Ebp => X86RegisterClass::Double,
350 Esi => X86RegisterClass::Double,
351 Edi => X86RegisterClass::Double,
352 R8d => X86RegisterClass::Double,
353 R9d => X86RegisterClass::Double,
354 R10d => X86RegisterClass::Double,
355 R11d => X86RegisterClass::Double,
356 R12d => X86RegisterClass::Double,
357 R13d => X86RegisterClass::Double,
358 R14d => X86RegisterClass::Double,
359 R15d => X86RegisterClass::Double,
360 Rax => X86RegisterClass::Quad,
361 Rcx => X86RegisterClass::Quad,
362 Rdx => X86RegisterClass::Quad,
363 Rbx => X86RegisterClass::Quad,
364 Rsp => X86RegisterClass::Quad,
365 Rbp => X86RegisterClass::Quad,
366 Rsi => X86RegisterClass::Quad,
367 Rdi => X86RegisterClass::Quad,
368 R8 => X86RegisterClass::Quad,
369 R9 => X86RegisterClass::Quad,
370 R10 => X86RegisterClass::Quad,
371 R11 => X86RegisterClass::Quad,
372 R12 => X86RegisterClass::Quad,
373 R13 => X86RegisterClass::Quad,
374 R14 => X86RegisterClass::Quad,
375 R15 => X86RegisterClass::Quad,
376 Mmx(_) => X86RegisterClass::Mmx,
377 Xmm(_) => X86RegisterClass::Xmm,
378 Ymm(_) => X86RegisterClass::Ymm,
379 Zmm(_) => X86RegisterClass::Zmm,
380 Tmm(_) => X86RegisterClass::Tmm,
381 Cr(_) => X86RegisterClass::Cr,
382 Dr(_) => X86RegisterClass::Dr,
383 Tr(_) => X86RegisterClass::Tr,
384 Fp(_) => X86RegisterClass::St,
385 K(_) => X86RegisterClass::AvxMask,
386 Es => X86RegisterClass::Sreg,
387 Cs => X86RegisterClass::Sreg,
388 Ss => X86RegisterClass::Sreg,
389 Ds => X86RegisterClass::Sreg,
390 Fs => X86RegisterClass::Sreg,
391 Gs => X86RegisterClass::Sreg,
392 UndefSeg => X86RegisterClass::Sreg,
393 }
394 }
395}
396
397impl Display for X86Register {
398 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
399 match self {
400 Al => f.write_str("al"),
401 Cl => f.write_str("cl"),
402 Dl => f.write_str("dl"),
403 Bl => f.write_str("bl"),
404 Ah => f.write_str("ah"),
405 Ch => f.write_str("ch"),
406 Dh => f.write_str("dh"),
407 Bh => f.write_str("bh"),
408 Spl => f.write_str("spl"),
409 Bpl => f.write_str("bpl"),
410 Sil => f.write_str("sil"),
411 Dil => f.write_str("dil"),
412 R8b => f.write_str("r8b"),
413 R9b => f.write_str("r9b"),
414 R10b => f.write_str("r10b"),
415 R11b => f.write_str("r11b"),
416 R12b => f.write_str("r12b"),
417 R13b => f.write_str("r13b"),
418 R14b => f.write_str("r14b"),
419 R15b => f.write_str("r15b"),
420 Ax => f.write_str("ax"),
421 Cx => f.write_str("cx"),
422 Dx => f.write_str("dx"),
423 Bx => f.write_str("bx"),
424 Sp => f.write_str("sp"),
425 Bp => f.write_str("bp"),
426 Si => f.write_str("si"),
427 Di => f.write_str("di"),
428 R8w => f.write_str("r8w"),
429 R9w => f.write_str("r9w"),
430 R10w => f.write_str("r10w"),
431 R11w => f.write_str("r11w"),
432 R12w => f.write_str("r12w"),
433 R13w => f.write_str("r13w"),
434 R14w => f.write_str("r14w"),
435 R15w => f.write_str("r15w"),
436 Eax => f.write_str("eax"),
437 Ecx => f.write_str("ecx"),
438 Edx => f.write_str("edx"),
439 Ebx => f.write_str("ebx"),
440 Esp => f.write_str("esp"),
441 Ebp => f.write_str("ebp"),
442 Esi => f.write_str("esi"),
443 Edi => f.write_str("edi"),
444 R8d => f.write_str("r8d"),
445 R9d => f.write_str("r9d"),
446 R10d => f.write_str("r10d"),
447 R11d => f.write_str("r11d"),
448 R12d => f.write_str("r12d"),
449 R13d => f.write_str("r13d"),
450 R14d => f.write_str("r14d"),
451 R15d => f.write_str("r15d"),
452 Rax => f.write_str("rax"),
453 Rcx => f.write_str("rcx"),
454 Rdx => f.write_str("rdx"),
455 Rbx => f.write_str("rbx"),
456 Rsp => f.write_str("rsp"),
457 Rbp => f.write_str("rbp"),
458 Rsi => f.write_str("rsi"),
459 Rdi => f.write_str("rdi"),
460 R8 => f.write_str("r8"),
461 R9 => f.write_str("r9"),
462 R10 => f.write_str("r10"),
463 R11 => f.write_str("r11"),
464 R12 => f.write_str("r12"),
465 R13 => f.write_str("r13"),
466 R14 => f.write_str("r14"),
467 R15 => f.write_str("r15"),
468 Mmx(n) => f.write_fmt(format_args!("mm{}", n)),
469 Xmm(n) => f.write_fmt(format_args!("xmm{}", n)),
470 Ymm(n) => f.write_fmt(format_args!("ymm{}", n)),
471 Zmm(n) => f.write_fmt(format_args!("zmm{}", n)),
472 Tmm(n) => f.write_fmt(format_args!("tmm{}", n)),
473 Cr(n) => f.write_fmt(format_args!("cr{}", n)),
474 Dr(n) => f.write_fmt(format_args!("dr{}", n)),
475 Tr(n) => f.write_fmt(format_args!("tr{}", n)),
476 Fp(n) => f.write_fmt(format_args!("st{}", n)),
477 K(n) => f.write_fmt(format_args!("k{}", n)),
478 Es => f.write_str("es"),
479 Cs => f.write_str("cs"),
480 Ss => f.write_str("ss"),
481 Ds => f.write_str("ds"),
482 Fs => f.write_str("fs"),
483 Gs => f.write_str("gs"),
484 UndefSeg => f.write_str("undef"),
485 }
486 }
487}
488
489pub mod cpu;
490pub mod features;
491
492pub mod insn;
493pub mod printer;