regs.c (3517B)
1 /* x86-64 register name table - DWARF index <-> assembler name. */ 2 3 #include "arch/x64/regs.h" 4 5 #include "core/slice.h" 6 7 typedef struct X64Reg { 8 uint32_t dwarf_idx; 9 const char* name; 10 } X64Reg; 11 12 static const X64Reg X64_REGS[] = { 13 {0, "rax"}, {1, "rdx"}, {2, "rcx"}, {3, "rbx"}, {4, "rsi"}, 14 {5, "rdi"}, {6, "rbp"}, {7, "rsp"}, {8, "r8"}, {9, "r9"}, 15 {10, "r10"}, {11, "r11"}, {12, "r12"}, {13, "r13"}, {14, "r14"}, 16 {15, "r15"}, {16, "rip"}, {17, "xmm0"}, {18, "xmm1"}, {19, "xmm2"}, 17 {20, "xmm3"}, {21, "xmm4"}, {22, "xmm5"}, {23, "xmm6"}, {24, "xmm7"}, 18 {25, "xmm8"}, {26, "xmm9"}, {27, "xmm10"}, {28, "xmm11"}, {29, "xmm12"}, 19 {30, "xmm13"}, {31, "xmm14"}, {32, "xmm15"}, 20 }; 21 22 static const uint32_t X64_REGS_N = 23 (uint32_t)(sizeof X64_REGS / sizeof X64_REGS[0]); 24 25 /* x86-64 hardware GPR index (ModR/M/REX encoding) -> System V DWARF number. 26 * Single source of truth for both name lookup and CFI register emission. */ 27 static const uint32_t X64_HW_TO_DWARF[16] = { 28 0, 2, 1, 3, 7, 6, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 29 }; 30 31 uint32_t x64_dwarf_from_hw_gpr(uint32_t hw) { 32 return (hw < 16u) ? X64_HW_TO_DWARF[hw] : hw; 33 } 34 35 static int gpr_alias_index(const char* name, const uint32_t* map, 36 uint32_t* idx_out) { 37 static const char* aliases[16][5] = { 38 {"rax", "eax", "ax", "al", NULL}, 39 {"rcx", "ecx", "cx", "cl", NULL}, 40 {"rdx", "edx", "dx", "dl", NULL}, 41 {"rbx", "ebx", "bx", "bl", NULL}, 42 {"rsp", "esp", "sp", "spl", NULL}, 43 {"rbp", "ebp", "bp", "bpl", NULL}, 44 {"rsi", "esi", "si", "sil", NULL}, 45 {"rdi", "edi", "di", "dil", NULL}, 46 {"r8", "r8d", "r8w", "r8b", NULL}, 47 {"r9", "r9d", "r9w", "r9b", NULL}, 48 {"r10", "r10d", "r10w", "r10b", NULL}, 49 {"r11", "r11d", "r11w", "r11b", NULL}, 50 {"r12", "r12d", "r12w", "r12b", NULL}, 51 {"r13", "r13d", "r13w", "r13b", NULL}, 52 {"r14", "r14d", "r14w", "r14b", NULL}, 53 {"r15", "r15d", "r15w", "r15b", NULL}, 54 }; 55 uint32_t i; 56 Slice q; 57 if (!name) return 1; 58 q = slice_from_cstr(name); 59 for (i = 0; i < 16u; ++i) { 60 uint32_t j; 61 for (j = 0; aliases[i][j]; ++j) { 62 if (slice_eq_cstr(q, aliases[i][j])) { 63 if (idx_out) *idx_out = map[i]; 64 return 0; 65 } 66 } 67 } 68 return 1; 69 } 70 71 const char* x64_register_name(uint32_t dwarf_idx) { 72 uint32_t i; 73 for (i = 0; i < X64_REGS_N; ++i) { 74 if (X64_REGS[i].dwarf_idx == dwarf_idx) return X64_REGS[i].name; 75 } 76 return NULL; 77 } 78 79 int x64_register_index(const char* name, uint32_t* idx_out) { 80 uint32_t i; 81 if (!name) return 1; 82 if (name[0] == '%') ++name; 83 { 84 Slice q = slice_from_cstr(name); 85 for (i = 0; i < X64_REGS_N; ++i) { 86 if (slice_eq_cstr(q, X64_REGS[i].name)) { 87 if (idx_out) *idx_out = X64_REGS[i].dwarf_idx; 88 return 0; 89 } 90 } 91 } 92 return gpr_alias_index(name, X64_HW_TO_DWARF, idx_out); 93 } 94 95 int x64_register_hw_index(const char* name, uint32_t* idx_out) { 96 static const uint32_t hw[16] = { 97 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 98 }; 99 if (!name) return 1; 100 if (name[0] == '%') ++name; 101 return gpr_alias_index(name, hw, idx_out); 102 } 103 104 uint32_t x64_register_iter_size(void) { return X64_REGS_N; } 105 106 int x64_register_iter_get(uint32_t i, uint32_t* dwarf_out, 107 const char** name_out) { 108 if (i >= X64_REGS_N) return 1; 109 if (dwarf_out) *dwarf_out = X64_REGS[i].dwarf_idx; 110 if (name_out) *name_out = X64_REGS[i].name; 111 return 0; 112 }