arch_ops/
x86.rs

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    // r8
56    Al,
57    Cl,
58    Dl,
59    Bl,
60
61    // r8 high (no REX prefix)
62    Ah,
63    Ch,
64    Dh,
65    Bh,
66    // r8 high (any REX prefix)
67    Spl,
68    Bpl,
69    Sil,
70    Dil,
71
72    // r8 (REX.B/REX.R)
73    R8b,
74    R9b,
75    R10b,
76    R11b,
77    R12b,
78    R13b,
79    R14b,
80    R15b,
81
82    // r16
83    Ax,
84    Cx,
85    Dx,
86    Bx,
87    Sp,
88    Bp,
89    Si,
90    Di,
91
92    // r16 high (REX.B/REX.R)
93    R8w,
94    R9w,
95    R10w,
96    R11w,
97    R12w,
98    R13w,
99    R14w,
100    R15w,
101
102    // r32
103    Eax,
104    Ecx,
105    Edx,
106    Ebx,
107    Esp,
108    Ebp,
109    Esi,
110    Edi,
111
112    // r32 high (REX.B/REX.R)
113    R8d,
114    R9d,
115    R10d,
116    R11d,
117    R12d,
118    R13d,
119    R14d,
120    R15d,
121
122    // r64
123    Rax,
124    Rcx,
125    Rdx,
126    Rbx,
127    Rsp,
128    Rbp,
129    Rsi,
130    Rdi,
131
132    // r64 high (REX.B/REX.R)
133    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;