kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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 }