| ... | ... | @@ -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"), |