regs.c (3025B)
1 /* AArch64 register name table — DWARF index ↔ assembler name. 2 * 3 * DWARF register numbering for AArch64 (per the AAPCS64 ABI supplement): 4 * 0..30 X0..X30 (also W0..W30; same DWARF index) 5 * 31 SP (X31 / WSP) 6 * 32 PC 7 * 33 ELR (mode dependent; unused here) 8 * 64..95 V0..V31 (also B/H/S/D forms; same index) 9 * 10 * The canonical assembler spelling for v1 is the 64-bit form (Xn / Vn); 11 * disassembler output picks W/B/H/S/D based on instruction width 12 * separately. */ 13 14 #include "arch/aa64/regs.h" 15 16 #include <stdint.h> 17 #include <string.h> 18 19 #include "core/core.h" 20 #include "core/slice.h" 21 22 typedef struct AA64Reg { 23 uint32_t dwarf_idx; 24 const char* name; 25 } AA64Reg; 26 27 static const AA64Reg AA64_REGS[] = { 28 {0, "x0"}, {1, "x1"}, {2, "x2"}, {3, "x3"}, {4, "x4"}, 29 {5, "x5"}, {6, "x6"}, {7, "x7"}, {8, "x8"}, {9, "x9"}, 30 {10, "x10"}, {11, "x11"}, {12, "x12"}, {13, "x13"}, {14, "x14"}, 31 {15, "x15"}, {16, "x16"}, {17, "x17"}, {18, "x18"}, {19, "x19"}, 32 {20, "x20"}, {21, "x21"}, {22, "x22"}, {23, "x23"}, {24, "x24"}, 33 {25, "x25"}, {26, "x26"}, {27, "x27"}, {28, "x28"}, {29, "x29"}, 34 {30, "x30"}, {31, "sp"}, {32, "pc"}, {64, "v0"}, {65, "v1"}, 35 {66, "v2"}, {67, "v3"}, {68, "v4"}, {69, "v5"}, {70, "v6"}, 36 {71, "v7"}, {72, "v8"}, {73, "v9"}, {74, "v10"}, {75, "v11"}, 37 {76, "v12"}, {77, "v13"}, {78, "v14"}, {79, "v15"}, {80, "v16"}, 38 {81, "v17"}, {82, "v18"}, {83, "v19"}, {84, "v20"}, {85, "v21"}, 39 {86, "v22"}, {87, "v23"}, {88, "v24"}, {89, "v25"}, {90, "v26"}, 40 {91, "v27"}, {92, "v28"}, {93, "v29"}, {94, "v30"}, {95, "v31"}, 41 }; 42 43 static const uint32_t AA64_REGS_N = 44 (uint32_t)(sizeof AA64_REGS / sizeof AA64_REGS[0]); 45 46 const char* aa64_register_name(uint32_t dwarf_idx) { 47 uint32_t i; 48 for (i = 0; i < AA64_REGS_N; ++i) { 49 if (AA64_REGS[i].dwarf_idx == dwarf_idx) return AA64_REGS[i].name; 50 } 51 return NULL; 52 } 53 54 int aa64_register_index(const char* name, uint32_t* idx_out) { 55 uint32_t i; 56 Slice q; 57 if (!name) return 1; 58 q = slice_from_cstr(name); 59 for (i = 0; i < AA64_REGS_N; ++i) { 60 if (slice_eq_cstr(q, AA64_REGS[i].name)) { 61 if (idx_out) *idx_out = AA64_REGS[i].dwarf_idx; 62 return 0; 63 } 64 } 65 /* Accept Wn alias for Xn (same DWARF index). */ 66 if (name[0] == 'w' && name[1] != '\0') { 67 char buf[8]; 68 size_t n = q.len; 69 if (n < sizeof buf) { 70 buf[0] = 'x'; 71 memcpy(buf + 1, name + 1, n); 72 return aa64_register_index(buf, idx_out); 73 } 74 } 75 /* wzr / xzr aliases. */ 76 if (slice_eq_cstr(q, "wzr") || slice_eq_cstr(q, "xzr")) { 77 if (idx_out) *idx_out = 31u; /* shares SP encoding slot; v1 picks SP */ 78 return 0; 79 } 80 return 1; 81 } 82 83 uint32_t aa64_register_iter_size(void) { return AA64_REGS_N; } 84 85 int aa64_register_iter_get(uint32_t i, uint32_t* dwarf_out, 86 const char** name_out) { 87 if (i >= AA64_REGS_N) return 1; 88 if (dwarf_out) *dwarf_out = AA64_REGS[i].dwarf_idx; 89 if (name_out) *name_out = AA64_REGS[i].name; 90 return 0; 91 }