Home | History | Annotate | Line # | Download | only in libunwind
Registers.hpp revision 1.5
      1 //===----------------------------- Registers.hpp --------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //
      9 //  Models register sets for supported processors.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 #ifndef __REGISTERS_HPP__
     13 #define __REGISTERS_HPP__
     14 
     15 #include <cassert>
     16 #include <cstdint>
     17 
     18 namespace _Unwind {
     19 
     20 enum {
     21   REGNO_X86_EAX = 0,
     22   REGNO_X86_ECX = 1,
     23   REGNO_X86_EDX = 2,
     24   REGNO_X86_EBX = 3,
     25   REGNO_X86_ESP = 4,
     26   REGNO_X86_EBP = 5,
     27   REGNO_X86_ESI = 6,
     28   REGNO_X86_EDI = 7,
     29   REGNO_X86_EIP = 8,
     30 };
     31 
     32 class Registers_x86 {
     33 public:
     34   enum {
     35     LAST_REGISTER = REGNO_X86_EIP,
     36     LAST_RESTORE_REG = REGNO_X86_EIP,
     37     RETURN_REG = REGNO_X86_EIP,
     38   };
     39 
     40   __dso_hidden Registers_x86();
     41 
     42   static int dwarf2regno(int num) { return num; }
     43 
     44   bool validRegister(int num) const {
     45     return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
     46   }
     47 
     48   uint32_t getRegister(int num) const {
     49     assert(validRegister(num));
     50     return reg[num];
     51   }
     52 
     53   void setRegister(int num, uint32_t value) {
     54     assert(validRegister(num));
     55     reg[num] = value;
     56   }
     57 
     58   uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
     59 
     60   void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
     61 
     62   uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
     63 
     64   void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
     65 
     66   bool validFloatVectorRegister(int num) const { return false; }
     67 
     68   void copyFloatVectorRegister(int num, uint32_t addr) {
     69   }
     70 
     71   __dso_hidden void jumpto() const __dead;
     72 
     73 private:
     74   uint32_t reg[REGNO_X86_EIP + 1];
     75 };
     76 
     77 enum {
     78   REGNO_X86_64_RAX = 0,
     79   REGNO_X86_64_RDX = 1,
     80   REGNO_X86_64_RCX = 2,
     81   REGNO_X86_64_RBX = 3,
     82   REGNO_X86_64_RSI = 4,
     83   REGNO_X86_64_RDI = 5,
     84   REGNO_X86_64_RBP = 6,
     85   REGNO_X86_64_RSP = 7,
     86   REGNO_X86_64_R8 = 8,
     87   REGNO_X86_64_R9 = 9,
     88   REGNO_X86_64_R10 = 10,
     89   REGNO_X86_64_R11 = 11,
     90   REGNO_X86_64_R12 = 12,
     91   REGNO_X86_64_R13 = 13,
     92   REGNO_X86_64_R14 = 14,
     93   REGNO_X86_64_R15 = 15,
     94   REGNO_X86_64_RIP = 16,
     95 };
     96 
     97 class Registers_x86_64 {
     98 public:
     99   enum {
    100     LAST_REGISTER = REGNO_X86_64_RIP,
    101     LAST_RESTORE_REG = REGNO_X86_64_RIP,
    102     RETURN_REG = REGNO_X86_64_RIP,
    103   };
    104 
    105   __dso_hidden Registers_x86_64();
    106 
    107   static int dwarf2regno(int num) { return num; }
    108 
    109   bool validRegister(int num) const {
    110     return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
    111   }
    112 
    113   uint64_t getRegister(int num) const {
    114     assert(validRegister(num));
    115     return reg[num];
    116   }
    117 
    118   void setRegister(int num, uint64_t value) {
    119     assert(validRegister(num));
    120     reg[num] = value;
    121   }
    122 
    123   uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
    124 
    125   void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
    126 
    127   uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
    128 
    129   void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
    130 
    131   bool validFloatVectorRegister(int num) const { return false; }
    132 
    133   void copyFloatVectorRegister(int num, uint64_t addr) {
    134   }
    135 
    136   __dso_hidden void jumpto() const __dead;
    137 
    138 private:
    139   uint64_t reg[REGNO_X86_64_RIP + 1];
    140 };
    141 
    142 enum {
    143   DWARF_PPC32_R0 = 0,
    144   DWARF_PPC32_R31 = 31,
    145   DWARF_PPC32_F0 = 32,
    146   DWARF_PPC32_F31 = 63,
    147   DWARF_PPC32_LR = 65,
    148   DWARF_PPC32_CR = 70,
    149   DWARF_PPC32_V0 = 77,
    150   DWARF_PPC32_V31 = 108,
    151 
    152   REGNO_PPC32_R0 = 0,
    153   REGNO_PPC32_R1 = 1,
    154   REGNO_PPC32_R31 = 31,
    155   REGNO_PPC32_LR = 32,
    156   REGNO_PPC32_CR = 33,
    157   REGNO_PPC32_SRR0 = 34,
    158 
    159   REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
    160   REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
    161   REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
    162   REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
    163 };
    164 
    165 class Registers_ppc32 {
    166 public:
    167   enum {
    168     LAST_REGISTER = REGNO_PPC32_V31,
    169     LAST_RESTORE_REG = REGNO_PPC32_V31,
    170     RETURN_REG = REGNO_PPC32_LR,
    171   };
    172 
    173   __dso_hidden Registers_ppc32();
    174 
    175   static int dwarf2regno(int num) {
    176     if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
    177       return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
    178     if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
    179       return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
    180     if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
    181       return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
    182     switch (num) {
    183     case DWARF_PPC32_LR:
    184       return REGNO_PPC32_LR;
    185     case DWARF_PPC32_CR:
    186       return REGNO_PPC32_CR;
    187     default:
    188       return LAST_REGISTER + 1;
    189     }
    190   }
    191 
    192   bool validRegister(int num) const {
    193     return num >= 0 && num <= LAST_RESTORE_REG;
    194   }
    195 
    196   uint64_t getRegister(int num) const {
    197     assert(validRegister(num));
    198     return reg[num];
    199   }
    200 
    201   void setRegister(int num, uint64_t value) {
    202     assert(validRegister(num));
    203     reg[num] = value;
    204   }
    205 
    206   uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
    207 
    208   void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
    209 
    210   uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
    211 
    212   void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
    213 
    214   bool validFloatVectorRegister(int num) const {
    215     return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
    216            (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
    217   }
    218 
    219   void copyFloatVectorRegister(int num, uint64_t addr_) {
    220     const void *addr = reinterpret_cast<const void *>(addr_);
    221     if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
    222       memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
    223     else
    224       memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
    225   }
    226 
    227   __dso_hidden void jumpto() const __dead;
    228 
    229 private:
    230   struct vecreg_t {
    231     uint64_t low, high;
    232   };
    233   uint32_t reg[REGNO_PPC32_SRR0 + 1];
    234   uint32_t dummy;
    235   uint64_t fpreg[32];
    236   vecreg_t vecreg[64];
    237 };
    238 
    239 enum {
    240   DWARF_ARM32_R0 = 0,
    241   DWARF_ARM32_R15 = 15,
    242   DWARF_ARM32_SPSR = 128,
    243   DWARF_ARM32_D0 = 256,		// VFP-v3/Neon
    244   DWARF_ARM32_D31 = 287,
    245   REGNO_ARM32_R0 = 0,
    246   REGNO_ARM32_SP = 13,
    247   REGNO_ARM32_R15 = 15,
    248   REGNO_ARM32_SPSR = 16,
    249   REGNO_ARM32_D0 = 0,
    250   REGNO_ARM32_D31 = 31,
    251 };
    252 
    253 class Registers_arm32 {
    254 public:
    255   enum {
    256     LAST_REGISTER = REGNO_ARM32_D31,
    257     LAST_RESTORE_REG = REGNO_ARM32_SPSR,
    258     RETURN_REG = REGNO_ARM32_SPSR,
    259   };
    260 
    261   __dso_hidden Registers_arm32();
    262 
    263   static int dwarf2regno(int num) {
    264     if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
    265       return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
    266     if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
    267       return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
    268     if (num == DWARF_ARM32_SPSR)
    269       return REGNO_ARM32_SPSR;
    270     return LAST_REGISTER + 1;
    271   }
    272 
    273   bool validRegister(int num) const {
    274     return num >= 0 && num <= LAST_RESTORE_REG;
    275   }
    276 
    277   uint64_t getRegister(int num) const {
    278     assert(validRegister(num));
    279     return reg[num];
    280   }
    281 
    282   void setRegister(int num, uint64_t value) {
    283     assert(validRegister(num));
    284     reg[num] = value;
    285   }
    286 
    287   uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
    288 
    289   void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
    290 
    291   uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
    292 
    293   void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
    294 
    295   bool validFloatVectorRegister(int num) const {
    296     return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31);
    297   }
    298 
    299   void copyFloatVectorRegister(int num, uint64_t addr_) {
    300     const void *addr = reinterpret_cast<const void *>(addr_);
    301     memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
    302   }
    303 
    304   __dso_hidden void jumpto() const __dead;
    305 
    306 private:
    307   uint32_t reg[REGNO_ARM32_SPSR + 1];
    308   uint64_t fpreg[32];
    309 };
    310 
    311 enum {
    312   DWARF_VAX_R0 = 0,
    313   DWARF_VAX_R15 = 15,
    314   DWARF_VAX_PSW = 16,
    315 
    316   REGNO_VAX_R0 = 0,
    317   REGNO_VAX_R14 = 14,
    318   REGNO_VAX_R15 = 15,
    319   REGNO_VAX_PSW = 16,
    320 };
    321 
    322 class Registers_vax {
    323 public:
    324   enum {
    325     LAST_REGISTER = REGNO_VAX_PSW,
    326     LAST_RESTORE_REG = REGNO_VAX_PSW,
    327     RETURN_REG = REGNO_VAX_R15,
    328   };
    329 
    330   __dso_hidden Registers_vax();
    331 
    332   static int dwarf2regno(int num) {
    333     if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
    334       return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
    335     if (num == DWARF_VAX_PSW)
    336       return REGNO_VAX_PSW;
    337     return LAST_REGISTER + 1;
    338   }
    339 
    340   bool validRegister(int num) const {
    341     return num >= 0 && num <= LAST_RESTORE_REG;
    342   }
    343 
    344   uint64_t getRegister(int num) const {
    345     assert(validRegister(num));
    346     return reg[num];
    347   }
    348 
    349   void setRegister(int num, uint64_t value) {
    350     assert(validRegister(num));
    351     reg[num] = value;
    352   }
    353 
    354   uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
    355 
    356   void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
    357 
    358   uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
    359 
    360   void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
    361 
    362   bool validFloatVectorRegister(int num) const {
    363     return false;
    364   }
    365 
    366   void copyFloatVectorRegister(int num, uint64_t addr_) {
    367   }
    368 
    369   __dso_hidden void jumpto() const __dead;
    370 
    371 private:
    372   uint32_t reg[REGNO_VAX_PSW + 1];
    373 };
    374 
    375 } // namespace _Unwind
    376 
    377 #endif // __REGISTERS_HPP__
    378