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