regs.c (3006B)
1 /* RV64 register name table -- DWARF index <-> psABI assembler name. 2 * 3 * RISC-V DWARF numbering uses 0..31 for x-registers and 32..63 for 4 * f-registers. Canonical names use psABI spellings; xN/fN aliases are 5 * accepted by lookup. */ 6 7 #include "arch/rv64/regs.h" 8 9 #include <stdint.h> 10 11 #include "core/core.h" 12 #include "core/slice.h" 13 14 typedef struct Rv64Reg { 15 uint32_t dwarf_idx; 16 const char* name; 17 } Rv64Reg; 18 19 static const Rv64Reg RV64_REGS[] = { 20 {0, "zero"}, {1, "ra"}, {2, "sp"}, {3, "gp"}, {4, "tp"}, 21 {5, "t0"}, {6, "t1"}, {7, "t2"}, {8, "s0"}, {9, "s1"}, 22 {10, "a0"}, {11, "a1"}, {12, "a2"}, {13, "a3"}, {14, "a4"}, 23 {15, "a5"}, {16, "a6"}, {17, "a7"}, {18, "s2"}, {19, "s3"}, 24 {20, "s4"}, {21, "s5"}, {22, "s6"}, {23, "s7"}, {24, "s8"}, 25 {25, "s9"}, {26, "s10"}, {27, "s11"}, {28, "t3"}, {29, "t4"}, 26 {30, "t5"}, {31, "t6"}, 27 28 {32, "ft0"}, {33, "ft1"}, {34, "ft2"}, {35, "ft3"}, {36, "ft4"}, 29 {37, "ft5"}, {38, "ft6"}, {39, "ft7"}, {40, "fs0"}, {41, "fs1"}, 30 {42, "fa0"}, {43, "fa1"}, {44, "fa2"}, {45, "fa3"}, {46, "fa4"}, 31 {47, "fa5"}, {48, "fa6"}, {49, "fa7"}, {50, "fs2"}, {51, "fs3"}, 32 {52, "fs4"}, {53, "fs5"}, {54, "fs6"}, {55, "fs7"}, {56, "fs8"}, 33 {57, "fs9"}, {58, "fs10"}, {59, "fs11"}, {60, "ft8"}, {61, "ft9"}, 34 {62, "ft10"}, {63, "ft11"}, 35 }; 36 37 static const uint32_t RV64_REGS_N = 38 (uint32_t)(sizeof RV64_REGS / sizeof RV64_REGS[0]); 39 40 static int parse_num_suffix(const char* name, char prefix, uint32_t max, 41 uint32_t* out) { 42 uint32_t v = 0; 43 const char* p; 44 if (!name || name[0] != prefix || name[1] == '\0') return 1; 45 p = name + 1; 46 while (*p) { 47 if (*p < '0' || *p > '9') return 1; 48 v = v * 10u + (uint32_t)(*p - '0'); 49 if (v > max) return 1; 50 ++p; 51 } 52 if (out) *out = v; 53 return 0; 54 } 55 56 const char* rv64_register_name(uint32_t dwarf_idx) { 57 uint32_t i; 58 for (i = 0; i < RV64_REGS_N; ++i) { 59 if (RV64_REGS[i].dwarf_idx == dwarf_idx) return RV64_REGS[i].name; 60 } 61 return NULL; 62 } 63 64 int rv64_register_index(const char* name, uint32_t* idx_out) { 65 uint32_t i; 66 uint32_t n; 67 Slice q; 68 if (!name) return 1; 69 q = slice_from_cstr(name); 70 for (i = 0; i < RV64_REGS_N; ++i) { 71 if (slice_eq_cstr(q, RV64_REGS[i].name)) { 72 if (idx_out) *idx_out = RV64_REGS[i].dwarf_idx; 73 return 0; 74 } 75 } 76 if (!parse_num_suffix(name, 'x', 31, &n)) { 77 if (idx_out) *idx_out = n; 78 return 0; 79 } 80 if (!parse_num_suffix(name, 'f', 31, &n)) { 81 if (idx_out) *idx_out = 32u + n; 82 return 0; 83 } 84 if (slice_eq_cstr(q, "fp")) { 85 if (idx_out) *idx_out = 8u; 86 return 0; 87 } 88 return 1; 89 } 90 91 uint32_t rv64_register_iter_size(void) { return RV64_REGS_N; } 92 93 int rv64_register_iter_get(uint32_t i, uint32_t* dwarf_out, 94 const char** name_out) { 95 if (i >= RV64_REGS_N) return 1; 96 if (dwarf_out) *dwarf_out = RV64_REGS[i].dwarf_idx; 97 if (name_out) *name_out = RV64_REGS[i].name; 98 return 0; 99 }