Home | History | Annotate | Line # | Download | only in libunwind
Registers.hpp revision 1.15
      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_OFFSET = 0,
     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_OFFSET = 0,
    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_OFFSET = 0,
    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_OFFSET = 0,
    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_OFFSET = 0,
    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 enum {
    376   DWARF_M68K_A0 = 0,
    377   DWARF_M68K_A7 = 7,
    378   DWARF_M68K_D0 = 8,
    379   DWARF_M68K_D7 = 15,
    380   DWARF_M68K_FP0 = 16,
    381   DWARF_M68K_FP7 = 23,
    382   DWARF_M68K_PC = 24,
    383 
    384   REGNO_M68K_A0 = 0,
    385   REGNO_M68K_A7 = 7,
    386   REGNO_M68K_D0 = 8,
    387   REGNO_M68K_D7 = 15,
    388   REGNO_M68K_PC = 16,
    389   REGNO_M68K_FP0 = 17,
    390   REGNO_M68K_FP7 = 24,
    391 };
    392 
    393 class Registers_M68K {
    394 public:
    395   enum {
    396     LAST_REGISTER = REGNO_M68K_FP7,
    397     LAST_RESTORE_REG = REGNO_M68K_FP7,
    398     RETURN_OFFSET = 0,
    399   };
    400 
    401   __dso_hidden Registers_M68K();
    402 
    403   static int dwarf2regno(int num) {
    404     if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
    405       return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
    406     if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
    407       return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
    408     if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
    409       return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
    410     if (num == DWARF_M68K_PC)
    411       return REGNO_M68K_PC;
    412     return LAST_REGISTER + 1;
    413   }
    414 
    415   bool validRegister(int num) const {
    416     return num >= 0 && num <= REGNO_M68K_PC;
    417   }
    418 
    419   uint64_t getRegister(int num) const {
    420     assert(validRegister(num));
    421     return reg[num];
    422   }
    423 
    424   void setRegister(int num, uint64_t value) {
    425     assert(validRegister(num));
    426     reg[num] = value;
    427   }
    428 
    429   uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
    430 
    431   void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
    432 
    433   uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
    434 
    435   void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
    436 
    437   bool validFloatVectorRegister(int num) const {
    438     return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
    439   }
    440 
    441   void copyFloatVectorRegister(int num, uint64_t addr_) {
    442     assert(validFloatVectorRegister(num));
    443     const void *addr = reinterpret_cast<const void *>(addr_);
    444     memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
    445   }
    446 
    447   __dso_hidden void jumpto() const __dead;
    448 
    449 private:
    450   typedef uint32_t fpreg_t[3];
    451 
    452   uint32_t reg[REGNO_M68K_PC + 1];
    453   uint32_t dummy;
    454   fpreg_t fpreg[8];
    455 };
    456 
    457 enum {
    458   DWARF_SH3_R0 = 0,
    459   DWARF_SH3_R15 = 15,
    460   DWARF_SH3_PC = 16,
    461   DWARF_SH3_PR = 17,
    462 
    463   REGNO_SH3_R0 = 0,
    464   REGNO_SH3_R15 = 15,
    465   REGNO_SH3_PC = 16,
    466   REGNO_SH3_PR = 17,
    467 };
    468 
    469 class Registers_SH3 {
    470 public:
    471   enum {
    472     LAST_REGISTER = REGNO_SH3_PR,
    473     LAST_RESTORE_REG = REGNO_SH3_PR,
    474     RETURN_OFFSET = 0,
    475   };
    476 
    477   __dso_hidden Registers_SH3();
    478 
    479   static int dwarf2regno(int num) {
    480     if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
    481       return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
    482     if (num == DWARF_SH3_PC)
    483       return REGNO_SH3_PC;
    484     if (num == DWARF_SH3_PR)
    485       return REGNO_SH3_PR;
    486     return LAST_REGISTER + 1;
    487   }
    488 
    489   bool validRegister(int num) const {
    490     return num >= 0 && num <= REGNO_SH3_PR;
    491   }
    492 
    493   uint64_t getRegister(int num) const {
    494     assert(validRegister(num));
    495     return reg[num];
    496   }
    497 
    498   void setRegister(int num, uint64_t value) {
    499     assert(validRegister(num));
    500     reg[num] = value;
    501   }
    502 
    503   uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
    504 
    505   void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
    506 
    507   uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
    508 
    509   void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
    510 
    511   bool validFloatVectorRegister(int num) const { return false; }
    512 
    513   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    514 
    515   __dso_hidden void jumpto() const __dead;
    516 
    517 private:
    518   uint32_t reg[REGNO_SH3_PR + 1];
    519 };
    520 
    521 enum {
    522   DWARF_SPARC64_R0 = 0,
    523   DWARF_SPARC64_R31 = 31,
    524   DWARF_SPARC64_PC = 32,
    525 
    526   REGNO_SPARC64_R0 = 0,
    527   REGNO_SPARC64_R14 = 14,
    528   REGNO_SPARC64_R15 = 15,
    529   REGNO_SPARC64_R31 = 31,
    530   REGNO_SPARC64_PC = 32,
    531 };
    532 
    533 class Registers_SPARC64 {
    534 public:
    535   enum {
    536     LAST_REGISTER = REGNO_SPARC64_PC,
    537     LAST_RESTORE_REG = REGNO_SPARC64_PC,
    538     RETURN_OFFSET = 8,
    539   };
    540   typedef uint64_t reg_t;
    541 
    542   __dso_hidden Registers_SPARC64();
    543 
    544   static int dwarf2regno(int num) {
    545     if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
    546       return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
    547     if (num == DWARF_SPARC64_PC)
    548       return REGNO_SPARC64_PC;
    549     return LAST_REGISTER + 1;
    550   }
    551 
    552   bool validRegister(int num) const {
    553     return num >= 0 && num <= REGNO_SPARC64_PC;
    554   }
    555 
    556   uint64_t getRegister(int num) const {
    557     assert(validRegister(num));
    558     return reg[num];
    559   }
    560 
    561   void setRegister(int num, uint64_t value) {
    562     assert(validRegister(num));
    563     reg[num] = value;
    564   }
    565 
    566   uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
    567 
    568   void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
    569 
    570   uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
    571 
    572   void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
    573 
    574   bool validFloatVectorRegister(int num) const { return false; }
    575 
    576   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    577 
    578   __dso_hidden void jumpto() const __dead;
    579 
    580 private:
    581   uint64_t reg[REGNO_SPARC64_PC + 1];
    582 };
    583 
    584 enum {
    585   DWARF_SPARC_R0 = 0,
    586   DWARF_SPARC_R31 = 31,
    587   DWARF_SPARC_PC = 32,
    588 
    589   REGNO_SPARC_R0 = 0,
    590   REGNO_SPARC_R14 = 14,
    591   REGNO_SPARC_R15 = 15,
    592   REGNO_SPARC_R31 = 31,
    593   REGNO_SPARC_PC = 32,
    594 };
    595 
    596 class Registers_SPARC {
    597 public:
    598   enum {
    599     LAST_REGISTER = REGNO_SPARC_PC,
    600     LAST_RESTORE_REG = REGNO_SPARC_PC,
    601     RETURN_OFFSET = 8,
    602   };
    603   typedef uint32_t reg_t;
    604 
    605   __dso_hidden Registers_SPARC();
    606 
    607   static int dwarf2regno(int num) {
    608     if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
    609       return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
    610     if (num == DWARF_SPARC_PC)
    611       return REGNO_SPARC_PC;
    612     return LAST_REGISTER + 1;
    613   }
    614 
    615   bool validRegister(int num) const {
    616     return num >= 0 && num <= REGNO_SPARC_PC;
    617   }
    618 
    619   uint64_t getRegister(int num) const {
    620     assert(validRegister(num));
    621     return reg[num];
    622   }
    623 
    624   void setRegister(int num, uint64_t value) {
    625     assert(validRegister(num));
    626     reg[num] = value;
    627   }
    628 
    629   uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
    630 
    631   void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
    632 
    633   uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
    634 
    635   void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
    636 
    637   bool validFloatVectorRegister(int num) const { return false; }
    638 
    639   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    640 
    641   __dso_hidden void jumpto() const __dead;
    642 
    643 private:
    644   uint32_t reg[REGNO_SPARC_PC + 1];
    645 };
    646 
    647 enum {
    648   DWARF_ALPHA_R0 = 0,
    649   DWARF_ALPHA_R30 = 30,
    650   DWARF_ALPHA_F0 = 32,
    651   DWARF_ALPHA_F30 = 62,
    652 
    653   REGNO_ALPHA_R0 = 0,
    654   REGNO_ALPHA_R26 = 26,
    655   REGNO_ALPHA_R30 = 30,
    656   REGNO_ALPHA_PC = 31,
    657   REGNO_ALPHA_F0 = 32,
    658   REGNO_ALPHA_F30 = 62,
    659 };
    660 
    661 class Registers_Alpha {
    662 public:
    663   enum {
    664     LAST_REGISTER = REGNO_ALPHA_F30,
    665     LAST_RESTORE_REG = REGNO_ALPHA_F30,
    666     RETURN_OFFSET = 0,
    667   };
    668   typedef uint32_t reg_t;
    669 
    670   __dso_hidden Registers_Alpha();
    671 
    672   static int dwarf2regno(int num) { return num; }
    673 
    674   bool validRegister(int num) const {
    675     return num >= 0 && num <= REGNO_ALPHA_PC;
    676   }
    677 
    678   uint64_t getRegister(int num) const {
    679     assert(validRegister(num));
    680     return reg[num];
    681   }
    682 
    683   void setRegister(int num, uint64_t value) {
    684     assert(validRegister(num));
    685     reg[num] = value;
    686   }
    687 
    688   uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
    689 
    690   void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
    691 
    692   uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
    693 
    694   void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
    695 
    696   bool validFloatVectorRegister(int num) const {
    697     return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
    698   }
    699 
    700   void copyFloatVectorRegister(int num, uint64_t addr_) {
    701     assert(validFloatVectorRegister(num));
    702     const void *addr = reinterpret_cast<const void *>(addr_);
    703     memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
    704   }
    705 
    706   __dso_hidden void jumpto() const __dead;
    707 
    708 private:
    709   uint64_t reg[REGNO_ALPHA_PC + 1];
    710   uint64_t fpreg[31];
    711 };
    712 
    713 enum {
    714   DWARF_HPPA_R1 = 1,
    715   DWARF_HPPA_R31 = 31,
    716   DWARF_HPPA_FR4L = 32,
    717   DWARF_HPPA_FR31H = 87,
    718 
    719   REGNO_HPPA_PC = 0,
    720   REGNO_HPPA_R1 = 1,
    721   REGNO_HPPA_R2 = 2,
    722   REGNO_HPPA_R30 = 30,
    723   REGNO_HPPA_R31 = 31,
    724   REGNO_HPPA_FR4L = 32,
    725   REGNO_HPPA_FR31H = 87,
    726 };
    727 
    728 class Registers_HPPA {
    729 public:
    730   enum {
    731     LAST_REGISTER = REGNO_HPPA_FR31H,
    732     LAST_RESTORE_REG = REGNO_HPPA_FR31H,
    733     RETURN_OFFSET = -3, // strictly speaking, this is a mask
    734   };
    735 
    736   __dso_hidden Registers_HPPA();
    737 
    738   static int dwarf2regno(int num) {
    739     if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
    740       return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
    741     if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
    742       return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
    743     return LAST_REGISTER + 1;
    744   }
    745 
    746   bool validRegister(int num) const {
    747     return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
    748   }
    749 
    750   uint64_t getRegister(int num) const {
    751     assert(validRegister(num));
    752     return reg[num];
    753   }
    754 
    755   void setRegister(int num, uint64_t value) {
    756     assert(validRegister(num));
    757     reg[num] = value;
    758   }
    759 
    760   uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
    761 
    762   void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
    763 
    764   uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
    765 
    766   void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
    767 
    768   bool validFloatVectorRegister(int num) const {
    769     return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
    770   }
    771 
    772   void copyFloatVectorRegister(int num, uint64_t addr_) {
    773     assert(validFloatVectorRegister(num));
    774     const void *addr = reinterpret_cast<const void *>(addr_);
    775     memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
    776   }
    777 
    778   __dso_hidden void jumpto() const __dead;
    779 
    780 private:
    781   uint32_t reg[REGNO_HPPA_R31 + 1];
    782   uint32_t fpreg[56];
    783 };
    784 
    785 enum {
    786   DWARF_MIPS_R1 = 0,
    787   DWARF_MIPS_R31 = 31,
    788   DWARF_MIPS_F0 = 32,
    789   DWARF_MIPS_F31 = 63,
    790 
    791   REGNO_MIPS_PC = 0,
    792   REGNO_MIPS_R1 = 0,
    793   REGNO_MIPS_R29 = 29,
    794   REGNO_MIPS_R31 = 31,
    795   REGNO_MIPS_F0 = 33,
    796   REGNO_MIPS_F31 = 64
    797 };
    798 
    799 class Registers_MIPS {
    800 public:
    801   enum {
    802     LAST_REGISTER = REGNO_MIPS_F31,
    803     LAST_RESTORE_REG = REGNO_MIPS_F31,
    804     RETURN_OFFSET = 0,
    805   };
    806 
    807   __dso_hidden Registers_MIPS();
    808 
    809   static int dwarf2regno(int num) {
    810     if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
    811       return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
    812     if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
    813       return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
    814     return LAST_REGISTER + 1;
    815   }
    816 
    817   bool validRegister(int num) const {
    818     return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31;
    819   }
    820 
    821   uint64_t getRegister(int num) const {
    822     assert(validRegister(num));
    823     return reg[num];
    824   }
    825 
    826   void setRegister(int num, uint64_t value) {
    827     assert(validRegister(num));
    828     reg[num] = value;
    829   }
    830 
    831   uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
    832 
    833   void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
    834 
    835   uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
    836 
    837   void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
    838 
    839   bool validFloatVectorRegister(int num) const {
    840     return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31;
    841   }
    842 
    843   void copyFloatVectorRegister(int num, uint64_t addr_) {
    844     assert(validFloatVectorRegister(num));
    845     const void *addr = reinterpret_cast<const void *>(addr_);
    846     memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
    847   }
    848 
    849   __dso_hidden void jumpto() const __dead;
    850 
    851 private:
    852   uint32_t reg[REGNO_MIPS_R31 + 1];
    853   uint64_t fpreg[32];
    854 };
    855 
    856 enum {
    857   DWARF_MIPS64_R1 = 0,
    858   DWARF_MIPS64_R31 = 31,
    859   DWARF_MIPS64_F0 = 32,
    860   DWARF_MIPS64_F31 = 63,
    861 
    862   REGNO_MIPS64_PC = 0,
    863   REGNO_MIPS64_R1 = 0,
    864   REGNO_MIPS64_R29 = 29,
    865   REGNO_MIPS64_R31 = 31,
    866   REGNO_MIPS64_F0 = 33,
    867   REGNO_MIPS64_F31 = 64
    868 };
    869 
    870 class Registers_MIPS64 {
    871 public:
    872   enum {
    873     LAST_REGISTER = REGNO_MIPS64_F31,
    874     LAST_RESTORE_REG = REGNO_MIPS64_F31,
    875     RETURN_OFFSET = 0,
    876   };
    877 
    878   __dso_hidden Registers_MIPS64();
    879 
    880   static int dwarf2regno(int num) {
    881     if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
    882       return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
    883     if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
    884       return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
    885     return LAST_REGISTER + 1;
    886   }
    887 
    888   bool validRegister(int num) const {
    889     return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31;
    890   }
    891 
    892   uint64_t getRegister(int num) const {
    893     assert(validRegister(num));
    894     return reg[num];
    895   }
    896 
    897   void setRegister(int num, uint64_t value) {
    898     assert(validRegister(num));
    899     reg[num] = value;
    900   }
    901 
    902   uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
    903 
    904   void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
    905 
    906   uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
    907 
    908   void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
    909 
    910   bool validFloatVectorRegister(int num) const {
    911     return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31;
    912   }
    913 
    914   void copyFloatVectorRegister(int num, uint64_t addr_) {
    915     assert(validFloatVectorRegister(num));
    916     const void *addr = reinterpret_cast<const void *>(addr_);
    917     memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
    918   }
    919 
    920   __dso_hidden void jumpto() const __dead;
    921 
    922 private:
    923   uint64_t reg[REGNO_MIPS64_R31 + 1];
    924   uint64_t fpreg[32];
    925 };
    926 
    927 #if __i386__
    928 typedef Registers_x86 NativeUnwindRegisters;
    929 #elif __x86_64__
    930 typedef Registers_x86_64 NativeUnwindRegisters;
    931 #elif __powerpc__
    932 typedef Registers_ppc32 NativeUnwindRegisters;
    933 #elif __arm__ && !defined(__ARM_EABI__)
    934 typedef Registers_arm32 NativeUnwindRegisters;
    935 #elif __vax__
    936 typedef Registers_vax NativeUnwindRegisters;
    937 #elif __m68k__
    938 typedef Registers_M68K NativeUnwindRegisters;
    939 #elif __mips_n64 || __mips_n32
    940 typedef Registers_MIPS64 NativeUnwindRegisters;
    941 #elif __mips__
    942 typedef Registers_MIPS NativeUnwindRegisters;
    943 #elif __sh3__
    944 typedef Registers_SH3 NativeUnwindRegisters;
    945 #elif __sparc64__
    946 typedef Registers_SPARC64 NativeUnwindRegisters;
    947 #elif __sparc__
    948 typedef Registers_SPARC NativeUnwindRegisters;
    949 #elif __alpha__
    950 typedef Registers_Alpha NativeUnwindRegisters;
    951 #elif __hppa__
    952 typedef Registers_HPPA NativeUnwindRegisters;
    953 #endif
    954 } // namespace _Unwind
    955 
    956 #endif // __REGISTERS_HPP__
    957