| ... | @@ -1,100 +0,0 @@ |
| 1 | const std = @import("std"); |
| 2 | |
| 3 | // zig fmt: off |
| 4 | pub const Register = enum(u8) { |
| 5 | // 0 through 7, 32-bit registers. id is int value |
| 6 | eax, ecx, edx, ebx, esp, ebp, esi, edi, |
| 7 | |
| 8 | // 8-15, 16-bit registers. id is int value - 8. |
| 9 | ax, cx, dx, bx, sp, bp, si, di, |
| 10 | |
| 11 | // 16-23, 8-bit registers. id is int value - 16. |
| 12 | al, cl, dl, bl, ah, ch, dh, bh, |
| 13 | |
| 14 | /// Returns the bit-width of the register. |
| 15 | pub fn size(self: Register) u7 { |
| 16 | return switch (@intFromEnum(self)) { |
| 17 | 0...7 => 32, |
| 18 | 8...15 => 16, |
| 19 | 16...23 => 8, |
| 20 | else => unreachable, |
| 21 | }; |
| 22 | } |
| 23 | |
| 24 | /// Returns the register's id. This is used in practically every opcode the |
| 25 | /// x86 has. It is embedded in some instructions, such as the `B8 +rd` move |
| 26 | /// instruction, and is used in the R/M byte. |
| 27 | pub fn id(self: Register) u3 { |
| 28 | return @truncate(@intFromEnum(self)); |
| 29 | } |
| 30 | |
| 31 | /// Convert from any register to its 32 bit alias. |
| 32 | pub fn to32(self: Register) Register { |
| 33 | return @enumFromInt(@as(u8, self.id())); |
| 34 | } |
| 35 | |
| 36 | /// Convert from any register to its 16 bit alias. |
| 37 | pub fn to16(self: Register) Register { |
| 38 | return @enumFromInt(@as(u8, self.id()) + 8); |
| 39 | } |
| 40 | |
| 41 | /// Convert from any register to its 8 bit alias. |
| 42 | pub fn to8(self: Register) Register { |
| 43 | return @enumFromInt(@as(u8, self.id()) + 16); |
| 44 | } |
| 45 | |
| 46 | pub fn dwarfNum(reg: Register) u8 { |
| 47 | return @intFromEnum(reg.to32()); |
| 48 | } |
| 49 | }; |
| 50 | |
| 51 | // zig fmt: on |
| 52 | |
| 53 | /// TODO this set is actually a set of caller-saved registers. |
| 54 | pub const callee_preserved_regs = [_]Register{ .eax, .ecx, .edx, .esi, .edi }; |
| 55 | |
| 56 | // TODO add these to Register enum and corresponding dwarfNum |
| 57 | // // Return Address register. This is stored in `0(%esp, "")` and is not a physical register. |
| 58 | // RA = (8, "RA"), |
| 59 | // |
| 60 | // ST0 = (11, "st0"), |
| 61 | // ST1 = (12, "st1"), |
| 62 | // ST2 = (13, "st2"), |
| 63 | // ST3 = (14, "st3"), |
| 64 | // ST4 = (15, "st4"), |
| 65 | // ST5 = (16, "st5"), |
| 66 | // ST6 = (17, "st6"), |
| 67 | // ST7 = (18, "st7"), |
| 68 | // |
| 69 | // XMM0 = (21, "xmm0"), |
| 70 | // XMM1 = (22, "xmm1"), |
| 71 | // XMM2 = (23, "xmm2"), |
| 72 | // XMM3 = (24, "xmm3"), |
| 73 | // XMM4 = (25, "xmm4"), |
| 74 | // XMM5 = (26, "xmm5"), |
| 75 | // XMM6 = (27, "xmm6"), |
| 76 | // XMM7 = (28, "xmm7"), |
| 77 | // |
| 78 | // MM0 = (29, "mm0"), |
| 79 | // MM1 = (30, "mm1"), |
| 80 | // MM2 = (31, "mm2"), |
| 81 | // MM3 = (32, "mm3"), |
| 82 | // MM4 = (33, "mm4"), |
| 83 | // MM5 = (34, "mm5"), |
| 84 | // MM6 = (35, "mm6"), |
| 85 | // MM7 = (36, "mm7"), |
| 86 | // |
| 87 | // MXCSR = (39, "mxcsr"), |
| 88 | // |
| 89 | // ES = (40, "es"), |
| 90 | // CS = (41, "cs"), |
| 91 | // SS = (42, "ss"), |
| 92 | // DS = (43, "ds"), |
| 93 | // FS = (44, "fs"), |
| 94 | // GS = (45, "gs"), |
| 95 | // |
| 96 | // TR = (48, "tr"), |
| 97 | // LDTR = (49, "ldtr"), |
| 98 | // |
| 99 | // FS_BASE = (93, "fs.base"), |
| 100 | // GS_BASE = (94, "gs.base"), |