Home | History | Annotate | Line # | Download | only in libunwind
Registers.hpp revision 1.3
      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_V0 = 1124,
    148   DWARF_PPC32_V31 = 1155,
    149   DWARF_PPC32_LR = 65,
    150   DWARF_PPC32_CTR = 66,
    151   DWARF_PPC32_XER = 76,
    152   REGNO_PPC32_R0 = 0,
    153   REGNO_PPC32_R1 = 0,
    154   REGNO_PPC32_R31 = 31,
    155   REGNO_PPC32_CR = 32,
    156   REGNO_PPC32_LR = 33,
    157   REGNO_PPC32_CTR = 34,
    158   REGNO_PPC32_XER = 35,
    159   REGNO_PPC32_SRR0 = 36,
    160   REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
    161   REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
    162   REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
    163   REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
    164 };
    165 
    166 class Registers_ppc32 {
    167 public:
    168   enum {
    169     LAST_REGISTER = REGNO_PPC32_V31,
    170     LAST_RESTORE_REG = REGNO_PPC32_V31,
    171     RETURN_REG = REGNO_PPC32_LR,
    172   };
    173 
    174   __dso_hidden Registers_ppc32();
    175 
    176   static int dwarf2regno(int num) {
    177     if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
    178       return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
    179     if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
    180       return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
    181     if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
    182       return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
    183     return LAST_REGISTER + 1;
    184   }
    185 
    186   bool validRegister(int num) const {
    187     return num >= 0 && num <= LAST_RESTORE_REG;
    188   }
    189 
    190   uint64_t getRegister(int num) const {
    191     assert(validRegister(num));
    192     return reg[num];
    193   }
    194 
    195   void setRegister(int num, uint64_t value) {
    196     assert(validRegister(num));
    197     reg[num] = value;
    198   }
    199 
    200   uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
    201 
    202   void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
    203 
    204   uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
    205 
    206   void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
    207 
    208   bool validFloatVectorRegister(int num) const {
    209     return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
    210            (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
    211   }
    212 
    213   void copyFloatVectorRegister(int num, uint64_t addr_) {
    214     const void *addr = reinterpret_cast<const void *>(addr_);
    215     if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
    216       memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
    217     else
    218       memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
    219   }
    220 
    221   __dso_hidden void jumpto() const __dead;
    222 
    223 private:
    224   struct vecreg_t {
    225     uint64_t low, high;
    226   };
    227   uint32_t reg[REGNO_PPC32_SRR0 + 1];
    228   uint64_t fpreg[32];
    229   vecreg_t vecreg[64];
    230 };
    231 
    232 enum {
    233   DWARF_ARM32_R0 = 0,
    234   DWARF_ARM32_R15 = 15,
    235   DWARF_ARM32_SPSR = 128,
    236   DWARF_ARM32_D0 = 256,		// VFP-v3/Neon
    237   DWARF_ARM32_D31 = 287,
    238   REGNO_ARM32_R0 = 0,
    239   REGNO_ARM32_SP = 13,
    240   REGNO_ARM32_R15 = 15,
    241   REGNO_ARM32_SPSR = 16,
    242   REGNO_ARM32_D0 = 0,
    243   REGNO_ARM32_D31 = 31,
    244 };
    245 
    246 class Registers_arm32 {
    247 public:
    248   enum {
    249     LAST_REGISTER = REGNO_ARM32_D31,
    250     LAST_RESTORE_REG = REGNO_ARM32_SPSR,
    251     RETURN_REG = REGNO_ARM32_SPSR,
    252   };
    253 
    254   __dso_hidden Registers_arm32();
    255 
    256   static int dwarf2regno(int num) {
    257     if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
    258       return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
    259     if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
    260       return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
    261     if (num == DWARF_ARM32_SPSR)
    262       return REGNO_ARM32_SPSR;
    263     return LAST_REGISTER + 1;
    264   }
    265 
    266   bool validRegister(int num) const {
    267     return num >= 0 && num <= LAST_RESTORE_REG;
    268   }
    269 
    270   uint64_t getRegister(int num) const {
    271     assert(validRegister(num));
    272     return reg[num];
    273   }
    274 
    275   void setRegister(int num, uint64_t value) {
    276     assert(validRegister(num));
    277     reg[num] = value;
    278   }
    279 
    280   uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
    281 
    282   void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
    283 
    284   uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
    285 
    286   void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
    287 
    288   bool validFloatVectorRegister(int num) const {
    289     return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31);
    290   }
    291 
    292   void copyFloatVectorRegister(int num, uint64_t addr_) {
    293     const void *addr = reinterpret_cast<const void *>(addr_);
    294     memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
    295   }
    296 
    297   __dso_hidden void jumpto() const __dead;
    298 
    299 private:
    300   uint32_t reg[REGNO_ARM32_SPSR + 1];
    301   uint64_t fpreg[32];
    302 };
    303 
    304 } // namespace _Unwind
    305 
    306 #endif // __REGISTERS_HPP__
    307