Home | History | Annotate | Line # | Download | only in libunwind
Registers.hpp revision 1.19
      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     RETURN_MASK = 0,
     39   };
     40 
     41   __dso_hidden Registers_x86();
     42 
     43   static int dwarf2regno(int num) { return num; }
     44 
     45   bool validRegister(int num) const {
     46     return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
     47   }
     48 
     49   uint32_t getRegister(int num) const {
     50     assert(validRegister(num));
     51     return reg[num];
     52   }
     53 
     54   void setRegister(int num, uint32_t value) {
     55     assert(validRegister(num));
     56     reg[num] = value;
     57   }
     58 
     59   uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
     60 
     61   void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
     62 
     63   uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
     64 
     65   void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
     66 
     67   bool validFloatVectorRegister(int num) const { return false; }
     68 
     69   void copyFloatVectorRegister(int num, uint32_t addr) {
     70   }
     71 
     72   __dso_hidden void jumpto() const __dead;
     73 
     74 private:
     75   uint32_t reg[REGNO_X86_EIP + 1];
     76 };
     77 
     78 enum {
     79   REGNO_X86_64_RAX = 0,
     80   REGNO_X86_64_RDX = 1,
     81   REGNO_X86_64_RCX = 2,
     82   REGNO_X86_64_RBX = 3,
     83   REGNO_X86_64_RSI = 4,
     84   REGNO_X86_64_RDI = 5,
     85   REGNO_X86_64_RBP = 6,
     86   REGNO_X86_64_RSP = 7,
     87   REGNO_X86_64_R8 = 8,
     88   REGNO_X86_64_R9 = 9,
     89   REGNO_X86_64_R10 = 10,
     90   REGNO_X86_64_R11 = 11,
     91   REGNO_X86_64_R12 = 12,
     92   REGNO_X86_64_R13 = 13,
     93   REGNO_X86_64_R14 = 14,
     94   REGNO_X86_64_R15 = 15,
     95   REGNO_X86_64_RIP = 16,
     96 };
     97 
     98 class Registers_x86_64 {
     99 public:
    100   enum {
    101     LAST_REGISTER = REGNO_X86_64_RIP,
    102     LAST_RESTORE_REG = REGNO_X86_64_RIP,
    103     RETURN_OFFSET = 0,
    104     RETURN_MASK = 0,
    105   };
    106 
    107   __dso_hidden Registers_x86_64();
    108 
    109   static int dwarf2regno(int num) { return num; }
    110 
    111   bool validRegister(int num) const {
    112     return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
    113   }
    114 
    115   uint64_t getRegister(int num) const {
    116     assert(validRegister(num));
    117     return reg[num];
    118   }
    119 
    120   void setRegister(int num, uint64_t value) {
    121     assert(validRegister(num));
    122     reg[num] = value;
    123   }
    124 
    125   uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
    126 
    127   void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
    128 
    129   uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
    130 
    131   void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
    132 
    133   bool validFloatVectorRegister(int num) const { return false; }
    134 
    135   void copyFloatVectorRegister(int num, uint64_t addr) {
    136   }
    137 
    138   __dso_hidden void jumpto() const __dead;
    139 
    140 private:
    141   uint64_t reg[REGNO_X86_64_RIP + 1];
    142 };
    143 
    144 enum {
    145   DWARF_PPC32_R0 = 0,
    146   DWARF_PPC32_R31 = 31,
    147   DWARF_PPC32_F0 = 32,
    148   DWARF_PPC32_F31 = 63,
    149   DWARF_PPC32_LR = 65,
    150   DWARF_PPC32_CR = 70,
    151   DWARF_PPC32_V0 = 77,
    152   DWARF_PPC32_V31 = 108,
    153 
    154   REGNO_PPC32_R0 = 0,
    155   REGNO_PPC32_R1 = 1,
    156   REGNO_PPC32_R31 = 31,
    157   REGNO_PPC32_LR = 32,
    158   REGNO_PPC32_CR = 33,
    159   REGNO_PPC32_SRR0 = 34,
    160 
    161   REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
    162   REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
    163   REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
    164   REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
    165 };
    166 
    167 class Registers_ppc32 {
    168 public:
    169   enum {
    170     LAST_REGISTER = REGNO_PPC32_V31,
    171     LAST_RESTORE_REG = REGNO_PPC32_V31,
    172     RETURN_OFFSET = 0,
    173     RETURN_MASK = 0,
    174   };
    175 
    176   __dso_hidden Registers_ppc32();
    177 
    178   static int dwarf2regno(int num) {
    179     if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
    180       return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
    181     if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
    182       return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
    183     if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
    184       return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
    185     switch (num) {
    186     case DWARF_PPC32_LR:
    187       return REGNO_PPC32_LR;
    188     case DWARF_PPC32_CR:
    189       return REGNO_PPC32_CR;
    190     default:
    191       return LAST_REGISTER + 1;
    192     }
    193   }
    194 
    195   bool validRegister(int num) const {
    196     return num >= 0 && num <= LAST_RESTORE_REG;
    197   }
    198 
    199   uint64_t getRegister(int num) const {
    200     assert(validRegister(num));
    201     return reg[num];
    202   }
    203 
    204   void setRegister(int num, uint64_t value) {
    205     assert(validRegister(num));
    206     reg[num] = value;
    207   }
    208 
    209   uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
    210 
    211   void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
    212 
    213   uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
    214 
    215   void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
    216 
    217   bool validFloatVectorRegister(int num) const {
    218     return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
    219            (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
    220   }
    221 
    222   void copyFloatVectorRegister(int num, uint64_t addr_) {
    223     const void *addr = reinterpret_cast<const void *>(addr_);
    224     if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
    225       memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
    226     else
    227       memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
    228   }
    229 
    230   __dso_hidden void jumpto() const __dead;
    231 
    232 private:
    233   struct vecreg_t {
    234     uint64_t low, high;
    235   };
    236   uint32_t reg[REGNO_PPC32_SRR0 + 1];
    237   uint32_t dummy;
    238   uint64_t fpreg[32];
    239   vecreg_t vecreg[64];
    240 };
    241 
    242 enum {
    243   DWARF_AARCH64_X0 = 0,
    244   DWARF_AARCH64_X30 = 30,
    245   DWARF_AARCH64_SP = 31,
    246   DWARF_AARCH64_ELR_MODE = 33,
    247   DWARF_AARCH64_V0 = 64,
    248   DWARF_AARCH64_V31 = 95,
    249 
    250   REGNO_AARCH64_X0 = 0,
    251   REGNO_AARCH64_X30 = 30,
    252   REGNO_AARCH64_SP = 31,
    253   REGNO_AARCH64_ELR_MODE = 32,
    254   REGNO_AARCH64_V0 = 33,
    255   REGNO_AARCH64_V31 = 64,
    256 };
    257 
    258 class Registers_aarch64 {
    259 public:
    260   enum {
    261     LAST_RESTORE_REG = REGNO_AARCH64_V31,
    262     LAST_REGISTER = REGNO_AARCH64_V31,
    263     RETURN_OFFSET = 0,
    264     RETURN_MASK = 0,
    265   };
    266 
    267   __dso_hidden Registers_aarch64();
    268 
    269   static int dwarf2regno(int num) {
    270     if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30)
    271       return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0);
    272     if (num == DWARF_AARCH64_SP)
    273       return REGNO_AARCH64_SP;
    274     if (num == DWARF_AARCH64_ELR_MODE)
    275       return REGNO_AARCH64_ELR_MODE;
    276     if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31)
    277       return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0);
    278     return LAST_REGISTER + 1;
    279   }
    280 
    281   bool validRegister(int num) const {
    282     return num >= 0 && num <= LAST_RESTORE_REG;
    283   }
    284 
    285   uint64_t getRegister(int num) const {
    286     assert(validRegister(num));
    287     return reg[num];
    288   }
    289 
    290   void setRegister(int num, uint64_t value) {
    291     assert(validRegister(num));
    292     reg[num] = value;
    293   }
    294 
    295   uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; }
    296 
    297   void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; }
    298 
    299   uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; }
    300 
    301   void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; }
    302 
    303   bool validFloatVectorRegister(int num) const {
    304     return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31);
    305   }
    306 
    307   void copyFloatVectorRegister(int num, uint64_t addr_) {
    308     const void *addr = reinterpret_cast<const void *>(addr_);
    309     memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, sizeof(vecreg[0]));
    310   }
    311 
    312   __dso_hidden void jumpto() const __dead;
    313 
    314 private:
    315   struct vecreg_t {
    316     uint64_t low, high;
    317   };
    318   uint64_t reg[REGNO_AARCH64_ELR_MODE + 1];
    319   vecreg_t vecreg[32];
    320 };
    321 
    322 enum {
    323   DWARF_ARM32_R0 = 0,
    324   DWARF_ARM32_R15 = 15,
    325   DWARF_ARM32_SPSR = 128,
    326   DWARF_ARM32_OLD_S0 = 64,
    327   DWARF_ARM32_OLD_S31 = 91,
    328   DWARF_ARM32_D0 = 256,
    329   DWARF_ARM32_D31 = 287,
    330   REGNO_ARM32_R0 = 0,
    331   REGNO_ARM32_SP = 13,
    332   REGNO_ARM32_R15 = 15,
    333   REGNO_ARM32_SPSR = 16,
    334   REGNO_ARM32_D0 = 17,
    335   REGNO_ARM32_D15 = 32,
    336   REGNO_ARM32_D31 = 48,
    337 };
    338 
    339 class Registers_arm32 {
    340 public:
    341   enum {
    342     LAST_REGISTER = REGNO_ARM32_D31,
    343     LAST_RESTORE_REG = REGNO_ARM32_D31,
    344     RETURN_OFFSET = 0,
    345     RETURN_MASK = 0,
    346   };
    347 
    348   __dso_hidden Registers_arm32();
    349 
    350   static int dwarf2regno(int num) {
    351     if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
    352       return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
    353     if (num == DWARF_ARM32_SPSR)
    354       return REGNO_ARM32_SPSR;
    355     if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
    356       return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
    357     if (num >= DWARF_ARM32_OLD_S0 && num <= DWARF_ARM32_OLD_S31) {
    358       assert(num % 2 == 0);
    359       return REGNO_ARM32_D0 + (num - DWARF_ARM32_OLD_S0) / 2;
    360     }
    361     return LAST_REGISTER + 1;
    362   }
    363 
    364   bool validRegister(int num) const {
    365     return num >= 0 && num <= REGNO_ARM32_SPSR;
    366   }
    367 
    368   uint64_t getRegister(int num) const {
    369     assert(validRegister(num));
    370     return reg[num];
    371   }
    372 
    373   void setRegister(int num, uint64_t value) {
    374     assert(validRegister(num));
    375     reg[num] = value;
    376   }
    377 
    378   uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
    379 
    380   void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
    381 
    382   uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
    383 
    384   void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
    385 
    386   bool validFloatVectorRegister(int num) const {
    387     return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31);
    388   }
    389 
    390   void copyFloatVectorRegister(int num, uint64_t addr_) {
    391     if (num <= REGNO_ARM32_D15) {
    392       if ((flags & 1) == 0) {
    393         lazyVFP1();
    394         flags |= 1;
    395       }
    396     } else {
    397       if ((flags & 2) == 0) {
    398         lazyVFP3();
    399         flags |= 2;
    400       }
    401     }
    402     const void *addr = reinterpret_cast<const void *>(addr_);
    403     memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
    404   }
    405 
    406   __dso_hidden void lazyVFP1();
    407   __dso_hidden void lazyVFP3();
    408   __dso_hidden void jumpto() const __dead;
    409 
    410 private:
    411   uint32_t reg[REGNO_ARM32_SPSR + 1];
    412   uint32_t flags;
    413   uint64_t fpreg[32];
    414 };
    415 
    416 enum {
    417   DWARF_VAX_R0 = 0,
    418   DWARF_VAX_R15 = 15,
    419   DWARF_VAX_PSW = 16,
    420 
    421   REGNO_VAX_R0 = 0,
    422   REGNO_VAX_R14 = 14,
    423   REGNO_VAX_R15 = 15,
    424   REGNO_VAX_PSW = 16,
    425 };
    426 
    427 class Registers_vax {
    428 public:
    429   enum {
    430     LAST_REGISTER = REGNO_VAX_PSW,
    431     LAST_RESTORE_REG = REGNO_VAX_PSW,
    432     RETURN_OFFSET = 0,
    433     RETURN_MASK = 0,
    434   };
    435 
    436   __dso_hidden Registers_vax();
    437 
    438   static int dwarf2regno(int num) {
    439     if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
    440       return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
    441     if (num == DWARF_VAX_PSW)
    442       return REGNO_VAX_PSW;
    443     return LAST_REGISTER + 1;
    444   }
    445 
    446   bool validRegister(int num) const {
    447     return num >= 0 && num <= LAST_RESTORE_REG;
    448   }
    449 
    450   uint64_t getRegister(int num) const {
    451     assert(validRegister(num));
    452     return reg[num];
    453   }
    454 
    455   void setRegister(int num, uint64_t value) {
    456     assert(validRegister(num));
    457     reg[num] = value;
    458   }
    459 
    460   uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
    461 
    462   void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
    463 
    464   uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
    465 
    466   void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
    467 
    468   bool validFloatVectorRegister(int num) const {
    469     return false;
    470   }
    471 
    472   void copyFloatVectorRegister(int num, uint64_t addr_) {
    473   }
    474 
    475   __dso_hidden void jumpto() const __dead;
    476 
    477 private:
    478   uint32_t reg[REGNO_VAX_PSW + 1];
    479 };
    480 
    481 enum {
    482   DWARF_M68K_A0 = 0,
    483   DWARF_M68K_A7 = 7,
    484   DWARF_M68K_D0 = 8,
    485   DWARF_M68K_D7 = 15,
    486   DWARF_M68K_FP0 = 16,
    487   DWARF_M68K_FP7 = 23,
    488   DWARF_M68K_PC = 24,
    489 
    490   REGNO_M68K_A0 = 0,
    491   REGNO_M68K_A7 = 7,
    492   REGNO_M68K_D0 = 8,
    493   REGNO_M68K_D7 = 15,
    494   REGNO_M68K_PC = 16,
    495   REGNO_M68K_FP0 = 17,
    496   REGNO_M68K_FP7 = 24,
    497 };
    498 
    499 class Registers_M68K {
    500 public:
    501   enum {
    502     LAST_REGISTER = REGNO_M68K_FP7,
    503     LAST_RESTORE_REG = REGNO_M68K_FP7,
    504     RETURN_OFFSET = 0,
    505     RETURN_MASK = 0,
    506   };
    507 
    508   __dso_hidden Registers_M68K();
    509 
    510   static int dwarf2regno(int num) {
    511     if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
    512       return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
    513     if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
    514       return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
    515     if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
    516       return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
    517     if (num == DWARF_M68K_PC)
    518       return REGNO_M68K_PC;
    519     return LAST_REGISTER + 1;
    520   }
    521 
    522   bool validRegister(int num) const {
    523     return num >= 0 && num <= REGNO_M68K_PC;
    524   }
    525 
    526   uint64_t getRegister(int num) const {
    527     assert(validRegister(num));
    528     return reg[num];
    529   }
    530 
    531   void setRegister(int num, uint64_t value) {
    532     assert(validRegister(num));
    533     reg[num] = value;
    534   }
    535 
    536   uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
    537 
    538   void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
    539 
    540   uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
    541 
    542   void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
    543 
    544   bool validFloatVectorRegister(int num) const {
    545     return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
    546   }
    547 
    548   void copyFloatVectorRegister(int num, uint64_t addr_) {
    549     assert(validFloatVectorRegister(num));
    550     const void *addr = reinterpret_cast<const void *>(addr_);
    551     memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
    552   }
    553 
    554   __dso_hidden void jumpto() const __dead;
    555 
    556 private:
    557   typedef uint32_t fpreg_t[3];
    558 
    559   uint32_t reg[REGNO_M68K_PC + 1];
    560   uint32_t dummy;
    561   fpreg_t fpreg[8];
    562 };
    563 
    564 enum {
    565   DWARF_SH3_R0 = 0,
    566   DWARF_SH3_R15 = 15,
    567   DWARF_SH3_PC = 16,
    568   DWARF_SH3_PR = 17,
    569 
    570   REGNO_SH3_R0 = 0,
    571   REGNO_SH3_R15 = 15,
    572   REGNO_SH3_PC = 16,
    573   REGNO_SH3_PR = 17,
    574 };
    575 
    576 class Registers_SH3 {
    577 public:
    578   enum {
    579     LAST_REGISTER = REGNO_SH3_PR,
    580     LAST_RESTORE_REG = REGNO_SH3_PR,
    581     RETURN_OFFSET = 0,
    582     RETURN_MASK = 0,
    583   };
    584 
    585   __dso_hidden Registers_SH3();
    586 
    587   static int dwarf2regno(int num) {
    588     if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
    589       return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
    590     if (num == DWARF_SH3_PC)
    591       return REGNO_SH3_PC;
    592     if (num == DWARF_SH3_PR)
    593       return REGNO_SH3_PR;
    594     return LAST_REGISTER + 1;
    595   }
    596 
    597   bool validRegister(int num) const {
    598     return num >= 0 && num <= REGNO_SH3_PR;
    599   }
    600 
    601   uint64_t getRegister(int num) const {
    602     assert(validRegister(num));
    603     return reg[num];
    604   }
    605 
    606   void setRegister(int num, uint64_t value) {
    607     assert(validRegister(num));
    608     reg[num] = value;
    609   }
    610 
    611   uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
    612 
    613   void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
    614 
    615   uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
    616 
    617   void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
    618 
    619   bool validFloatVectorRegister(int num) const { return false; }
    620 
    621   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    622 
    623   __dso_hidden void jumpto() const __dead;
    624 
    625 private:
    626   uint32_t reg[REGNO_SH3_PR + 1];
    627 };
    628 
    629 enum {
    630   DWARF_SPARC64_R0 = 0,
    631   DWARF_SPARC64_R31 = 31,
    632   DWARF_SPARC64_PC = 32,
    633 
    634   REGNO_SPARC64_R0 = 0,
    635   REGNO_SPARC64_R14 = 14,
    636   REGNO_SPARC64_R15 = 15,
    637   REGNO_SPARC64_R31 = 31,
    638   REGNO_SPARC64_PC = 32,
    639 };
    640 
    641 class Registers_SPARC64 {
    642 public:
    643   enum {
    644     LAST_REGISTER = REGNO_SPARC64_PC,
    645     LAST_RESTORE_REG = REGNO_SPARC64_PC,
    646     RETURN_OFFSET = 8,
    647     RETURN_MASK = 0,
    648   };
    649   typedef uint64_t reg_t;
    650 
    651   __dso_hidden Registers_SPARC64();
    652 
    653   static int dwarf2regno(int num) {
    654     if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
    655       return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
    656     if (num == DWARF_SPARC64_PC)
    657       return REGNO_SPARC64_PC;
    658     return LAST_REGISTER + 1;
    659   }
    660 
    661   bool validRegister(int num) const {
    662     return num >= 0 && num <= REGNO_SPARC64_PC;
    663   }
    664 
    665   uint64_t getRegister(int num) const {
    666     assert(validRegister(num));
    667     return reg[num];
    668   }
    669 
    670   void setRegister(int num, uint64_t value) {
    671     assert(validRegister(num));
    672     reg[num] = value;
    673   }
    674 
    675   uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
    676 
    677   void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
    678 
    679   uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
    680 
    681   void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
    682 
    683   bool validFloatVectorRegister(int num) const { return false; }
    684 
    685   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    686 
    687   __dso_hidden void jumpto() const __dead;
    688 
    689 private:
    690   uint64_t reg[REGNO_SPARC64_PC + 1];
    691 };
    692 
    693 enum {
    694   DWARF_SPARC_R0 = 0,
    695   DWARF_SPARC_R31 = 31,
    696   DWARF_SPARC_PC = 32,
    697 
    698   REGNO_SPARC_R0 = 0,
    699   REGNO_SPARC_R14 = 14,
    700   REGNO_SPARC_R15 = 15,
    701   REGNO_SPARC_R31 = 31,
    702   REGNO_SPARC_PC = 32,
    703 };
    704 
    705 class Registers_SPARC {
    706 public:
    707   enum {
    708     LAST_REGISTER = REGNO_SPARC_PC,
    709     LAST_RESTORE_REG = REGNO_SPARC_PC,
    710     RETURN_OFFSET = 8,
    711     RETURN_MASK = 0,
    712   };
    713   typedef uint32_t reg_t;
    714 
    715   __dso_hidden Registers_SPARC();
    716 
    717   static int dwarf2regno(int num) {
    718     if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
    719       return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
    720     if (num == DWARF_SPARC_PC)
    721       return REGNO_SPARC_PC;
    722     return LAST_REGISTER + 1;
    723   }
    724 
    725   bool validRegister(int num) const {
    726     return num >= 0 && num <= REGNO_SPARC_PC;
    727   }
    728 
    729   uint64_t getRegister(int num) const {
    730     assert(validRegister(num));
    731     return reg[num];
    732   }
    733 
    734   void setRegister(int num, uint64_t value) {
    735     assert(validRegister(num));
    736     reg[num] = value;
    737   }
    738 
    739   uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
    740 
    741   void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
    742 
    743   uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
    744 
    745   void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
    746 
    747   bool validFloatVectorRegister(int num) const { return false; }
    748 
    749   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    750 
    751   __dso_hidden void jumpto() const __dead;
    752 
    753 private:
    754   uint32_t reg[REGNO_SPARC_PC + 1];
    755 };
    756 
    757 enum {
    758   DWARF_ALPHA_R0 = 0,
    759   DWARF_ALPHA_R30 = 30,
    760   DWARF_ALPHA_F0 = 32,
    761   DWARF_ALPHA_F30 = 62,
    762 
    763   REGNO_ALPHA_R0 = 0,
    764   REGNO_ALPHA_R26 = 26,
    765   REGNO_ALPHA_R30 = 30,
    766   REGNO_ALPHA_PC = 31,
    767   REGNO_ALPHA_F0 = 32,
    768   REGNO_ALPHA_F30 = 62,
    769 };
    770 
    771 class Registers_Alpha {
    772 public:
    773   enum {
    774     LAST_REGISTER = REGNO_ALPHA_F30,
    775     LAST_RESTORE_REG = REGNO_ALPHA_F30,
    776     RETURN_OFFSET = 0,
    777     RETURN_MASK = 0,
    778   };
    779   typedef uint32_t reg_t;
    780 
    781   __dso_hidden Registers_Alpha();
    782 
    783   static int dwarf2regno(int num) { return num; }
    784 
    785   bool validRegister(int num) const {
    786     return num >= 0 && num <= REGNO_ALPHA_PC;
    787   }
    788 
    789   uint64_t getRegister(int num) const {
    790     assert(validRegister(num));
    791     return reg[num];
    792   }
    793 
    794   void setRegister(int num, uint64_t value) {
    795     assert(validRegister(num));
    796     reg[num] = value;
    797   }
    798 
    799   uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
    800 
    801   void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
    802 
    803   uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
    804 
    805   void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
    806 
    807   bool validFloatVectorRegister(int num) const {
    808     return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
    809   }
    810 
    811   void copyFloatVectorRegister(int num, uint64_t addr_) {
    812     assert(validFloatVectorRegister(num));
    813     const void *addr = reinterpret_cast<const void *>(addr_);
    814     memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
    815   }
    816 
    817   __dso_hidden void jumpto() const __dead;
    818 
    819 private:
    820   uint64_t reg[REGNO_ALPHA_PC + 1];
    821   uint64_t fpreg[31];
    822 };
    823 
    824 enum {
    825   DWARF_HPPA_R1 = 1,
    826   DWARF_HPPA_R31 = 31,
    827   DWARF_HPPA_FR4L = 32,
    828   DWARF_HPPA_FR31H = 87,
    829 
    830   REGNO_HPPA_PC = 0,
    831   REGNO_HPPA_R1 = 1,
    832   REGNO_HPPA_R2 = 2,
    833   REGNO_HPPA_R30 = 30,
    834   REGNO_HPPA_R31 = 31,
    835   REGNO_HPPA_FR4L = 32,
    836   REGNO_HPPA_FR31H = 87,
    837 };
    838 
    839 class Registers_HPPA {
    840 public:
    841   enum {
    842     LAST_REGISTER = REGNO_HPPA_FR31H,
    843     LAST_RESTORE_REG = REGNO_HPPA_FR31H,
    844     RETURN_OFFSET = 0,
    845     RETURN_MASK = 3,
    846   };
    847 
    848   __dso_hidden Registers_HPPA();
    849 
    850   static int dwarf2regno(int num) {
    851     if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
    852       return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
    853     if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
    854       return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
    855     return LAST_REGISTER + 1;
    856   }
    857 
    858   bool validRegister(int num) const {
    859     return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
    860   }
    861 
    862   uint64_t getRegister(int num) const {
    863     assert(validRegister(num));
    864     return reg[num];
    865   }
    866 
    867   void setRegister(int num, uint64_t value) {
    868     assert(validRegister(num));
    869     reg[num] = value;
    870   }
    871 
    872   uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
    873 
    874   void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
    875 
    876   uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
    877 
    878   void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
    879 
    880   bool validFloatVectorRegister(int num) const {
    881     return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
    882   }
    883 
    884   void copyFloatVectorRegister(int num, uint64_t addr_) {
    885     assert(validFloatVectorRegister(num));
    886     const void *addr = reinterpret_cast<const void *>(addr_);
    887     memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
    888   }
    889 
    890   __dso_hidden void jumpto() const __dead;
    891 
    892 private:
    893   uint32_t reg[REGNO_HPPA_R31 + 1];
    894   uint32_t fpreg[56];
    895 };
    896 
    897 enum {
    898   DWARF_MIPS_R1 = 0,
    899   DWARF_MIPS_R31 = 31,
    900   DWARF_MIPS_F0 = 32,
    901   DWARF_MIPS_F31 = 63,
    902 
    903   REGNO_MIPS_PC = 0,
    904   REGNO_MIPS_R1 = 0,
    905   REGNO_MIPS_R29 = 29,
    906   REGNO_MIPS_R31 = 31,
    907   REGNO_MIPS_F0 = 33,
    908   REGNO_MIPS_F31 = 64
    909 };
    910 
    911 class Registers_MIPS {
    912 public:
    913   enum {
    914     LAST_REGISTER = REGNO_MIPS_F31,
    915     LAST_RESTORE_REG = REGNO_MIPS_F31,
    916     RETURN_OFFSET = 0,
    917     RETURN_MASK = 0,
    918   };
    919 
    920   __dso_hidden Registers_MIPS();
    921 
    922   static int dwarf2regno(int num) {
    923     if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
    924       return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
    925     if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
    926       return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
    927     return LAST_REGISTER + 1;
    928   }
    929 
    930   bool validRegister(int num) const {
    931     return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31;
    932   }
    933 
    934   uint64_t getRegister(int num) const {
    935     assert(validRegister(num));
    936     return reg[num];
    937   }
    938 
    939   void setRegister(int num, uint64_t value) {
    940     assert(validRegister(num));
    941     reg[num] = value;
    942   }
    943 
    944   uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
    945 
    946   void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
    947 
    948   uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
    949 
    950   void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
    951 
    952   bool validFloatVectorRegister(int num) const {
    953     return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31;
    954   }
    955 
    956   void copyFloatVectorRegister(int num, uint64_t addr_) {
    957     assert(validFloatVectorRegister(num));
    958     const void *addr = reinterpret_cast<const void *>(addr_);
    959     memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
    960   }
    961 
    962   __dso_hidden void jumpto() const __dead;
    963 
    964 private:
    965   uint32_t reg[REGNO_MIPS_R31 + 1];
    966   uint64_t fpreg[32];
    967 };
    968 
    969 enum {
    970   DWARF_MIPS64_R1 = 0,
    971   DWARF_MIPS64_R31 = 31,
    972   DWARF_MIPS64_F0 = 32,
    973   DWARF_MIPS64_F31 = 63,
    974 
    975   REGNO_MIPS64_PC = 0,
    976   REGNO_MIPS64_R1 = 0,
    977   REGNO_MIPS64_R29 = 29,
    978   REGNO_MIPS64_R31 = 31,
    979   REGNO_MIPS64_F0 = 33,
    980   REGNO_MIPS64_F31 = 64
    981 };
    982 
    983 class Registers_MIPS64 {
    984 public:
    985   enum {
    986     LAST_REGISTER = REGNO_MIPS64_F31,
    987     LAST_RESTORE_REG = REGNO_MIPS64_F31,
    988     RETURN_OFFSET = 0,
    989     RETURN_MASK = 0,
    990   };
    991 
    992   __dso_hidden Registers_MIPS64();
    993 
    994   static int dwarf2regno(int num) {
    995     if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
    996       return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
    997     if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
    998       return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
    999     return LAST_REGISTER + 1;
   1000   }
   1001 
   1002   bool validRegister(int num) const {
   1003     return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31;
   1004   }
   1005 
   1006   uint64_t getRegister(int num) const {
   1007     assert(validRegister(num));
   1008     return reg[num];
   1009   }
   1010 
   1011   void setRegister(int num, uint64_t value) {
   1012     assert(validRegister(num));
   1013     reg[num] = value;
   1014   }
   1015 
   1016   uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
   1017 
   1018   void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
   1019 
   1020   uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
   1021 
   1022   void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
   1023 
   1024   bool validFloatVectorRegister(int num) const {
   1025     return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31;
   1026   }
   1027 
   1028   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1029     assert(validFloatVectorRegister(num));
   1030     const void *addr = reinterpret_cast<const void *>(addr_);
   1031     memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
   1032   }
   1033 
   1034   __dso_hidden void jumpto() const __dead;
   1035 
   1036 private:
   1037   uint64_t reg[REGNO_MIPS64_R31 + 1];
   1038   uint64_t fpreg[32];
   1039 };
   1040 
   1041 enum {
   1042   DWARF_OR1K_R0 = 0,
   1043   DWARF_OR1K_SP = 1,
   1044   DWARF_OR1K_LR = 9,
   1045   DWARF_OR1K_R31 = 31,
   1046   DWARF_OR1K_FPCSR = 32,
   1047 
   1048   REGNO_OR1K_R0 = 0,
   1049   REGNO_OR1K_SP = 1,
   1050   REGNO_OR1K_LR = 9,
   1051   REGNO_OR1K_R31 = 31,
   1052   REGNO_OR1K_FPCSR = 32,
   1053 };
   1054 
   1055 class Registers_or1k {
   1056 public:
   1057   enum {
   1058     LAST_REGISTER = REGNO_OR1K_FPCSR,
   1059     LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
   1060     RETURN_OFFSET = 0,
   1061     RETURN_MASK = 0,
   1062   };
   1063 
   1064   __dso_hidden Registers_or1k();
   1065 
   1066   static int dwarf2regno(int num) {
   1067     if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
   1068       return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
   1069     if (num == DWARF_OR1K_FPCSR)
   1070       return REGNO_OR1K_FPCSR;
   1071     return LAST_REGISTER + 1;
   1072   }
   1073 
   1074   bool validRegister(int num) const {
   1075     return num >= 0 && num <= LAST_RESTORE_REG;
   1076   }
   1077 
   1078   uint64_t getRegister(int num) const {
   1079     assert(validRegister(num));
   1080     return reg[num];
   1081   }
   1082 
   1083   void setRegister(int num, uint64_t value) {
   1084     assert(validRegister(num));
   1085     reg[num] = value;
   1086   }
   1087 
   1088   uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
   1089 
   1090   void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
   1091 
   1092   uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
   1093 
   1094   void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
   1095 
   1096   bool validFloatVectorRegister(int num) const {
   1097     return false;
   1098   }
   1099 
   1100   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1101   }
   1102 
   1103   __dso_hidden void jumpto() const __dead;
   1104 
   1105 private:
   1106   uint32_t reg[REGNO_OR1K_FPCSR + 1];
   1107 };
   1108 
   1109 #if __i386__
   1110 typedef Registers_x86 NativeUnwindRegisters;
   1111 #elif __x86_64__
   1112 typedef Registers_x86_64 NativeUnwindRegisters;
   1113 #elif __powerpc__
   1114 typedef Registers_ppc32 NativeUnwindRegisters;
   1115 #elif __aarch64__
   1116 typedef Registers_aarch64 NativeUnwindRegisters;
   1117 #elif __arm__
   1118 typedef Registers_arm32 NativeUnwindRegisters;
   1119 #elif __vax__
   1120 typedef Registers_vax NativeUnwindRegisters;
   1121 #elif __m68k__
   1122 typedef Registers_M68K NativeUnwindRegisters;
   1123 #elif __mips_n64 || __mips_n32
   1124 typedef Registers_MIPS64 NativeUnwindRegisters;
   1125 #elif __mips__
   1126 typedef Registers_MIPS NativeUnwindRegisters;
   1127 #elif __sh3__
   1128 typedef Registers_SH3 NativeUnwindRegisters;
   1129 #elif __sparc64__
   1130 typedef Registers_SPARC64 NativeUnwindRegisters;
   1131 #elif __sparc__
   1132 typedef Registers_SPARC NativeUnwindRegisters;
   1133 #elif __alpha__
   1134 typedef Registers_Alpha NativeUnwindRegisters;
   1135 #elif __hppa__
   1136 typedef Registers_HPPA NativeUnwindRegisters;
   1137 #elif __or1k__
   1138 typedef Registers_or1k NativeUnwindRegisters;
   1139 #endif
   1140 } // namespace _Unwind
   1141 
   1142 #endif // __REGISTERS_HPP__
   1143