Home | History | Annotate | Line # | Download | only in libunwind
Registers.hpp revision 1.22
      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 = 91,
    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 = 70,
    333 };
    334 
    335 class Registers_arm32 {
    336 public:
    337   enum {
    338     LAST_REGISTER = REGNO_ARM32_D31,
    339     LAST_RESTORE_REG = REGNO_ARM32_D31,
    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     const void *addr = reinterpret_cast<const void *>(addr_);
    386     if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) {
    387       if ((flags & FLAGS_VFPV2_USED) == 0) {
    388         lazyVFPv2();
    389         flags |= FLAGS_VFPV2_USED;
    390       }
    391       /*
    392        * Emulate single precision register as half of the
    393        * corresponding double register.
    394        */
    395       int dnum = (num - REGNO_ARM32_S0) / 2;
    396       int part = (num - REGNO_ARM32_S0) % 2;
    397 #if _BYTE_ORDER == _BIG_ENDIAN
    398       part = 1 - part;
    399 #endif
    400       memcpy(fpreg + dnum + part * sizeof(fpreg[0]) / 2,
    401         addr, sizeof(fpreg[0]) / 2);
    402     }
    403     if (num <= REGNO_ARM32_D15) {
    404       if ((flags & FLAGS_VFPV2_USED) == 0) {
    405         lazyVFPv2();
    406         flags |= FLAGS_VFPV2_USED;
    407       }
    408     } else {
    409       if ((flags & FLAGS_VFPV3_USED) == 0) {
    410         lazyVFPv3();
    411         flags |= FLAGS_VFPV3_USED;
    412       }
    413     }
    414     memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
    415   }
    416 
    417   __dso_hidden void lazyVFPv2();
    418   __dso_hidden void lazyVFPv3();
    419   __dso_hidden void jumpto() const __dead;
    420 
    421 private:
    422   uint32_t reg[REGNO_ARM32_SPSR + 1];
    423   uint32_t flags;
    424   uint64_t fpreg[32];
    425 
    426   enum {
    427     FLAGS_VFPV2_USED = 0x1,
    428     FLAGS_VFPV3_USED = 0x2,
    429   };
    430 };
    431 
    432 enum {
    433   DWARF_VAX_R0 = 0,
    434   DWARF_VAX_R15 = 15,
    435   DWARF_VAX_PSW = 16,
    436 
    437   REGNO_VAX_R0 = 0,
    438   REGNO_VAX_R14 = 14,
    439   REGNO_VAX_R15 = 15,
    440   REGNO_VAX_PSW = 16,
    441 };
    442 
    443 class Registers_vax {
    444 public:
    445   enum {
    446     LAST_REGISTER = REGNO_VAX_PSW,
    447     LAST_RESTORE_REG = REGNO_VAX_PSW,
    448     RETURN_OFFSET = 0,
    449     RETURN_MASK = 0,
    450   };
    451 
    452   __dso_hidden Registers_vax();
    453 
    454   static int dwarf2regno(int num) {
    455     if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
    456       return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
    457     if (num == DWARF_VAX_PSW)
    458       return REGNO_VAX_PSW;
    459     return LAST_REGISTER + 1;
    460   }
    461 
    462   bool validRegister(int num) const {
    463     return num >= 0 && num <= LAST_RESTORE_REG;
    464   }
    465 
    466   uint64_t getRegister(int num) const {
    467     assert(validRegister(num));
    468     return reg[num];
    469   }
    470 
    471   void setRegister(int num, uint64_t value) {
    472     assert(validRegister(num));
    473     reg[num] = value;
    474   }
    475 
    476   uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
    477 
    478   void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
    479 
    480   uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
    481 
    482   void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
    483 
    484   bool validFloatVectorRegister(int num) const {
    485     return false;
    486   }
    487 
    488   void copyFloatVectorRegister(int num, uint64_t addr_) {
    489   }
    490 
    491   __dso_hidden void jumpto() const __dead;
    492 
    493 private:
    494   uint32_t reg[REGNO_VAX_PSW + 1];
    495 };
    496 
    497 enum {
    498   DWARF_M68K_A0 = 0,
    499   DWARF_M68K_A7 = 7,
    500   DWARF_M68K_D0 = 8,
    501   DWARF_M68K_D7 = 15,
    502   DWARF_M68K_FP0 = 16,
    503   DWARF_M68K_FP7 = 23,
    504   DWARF_M68K_PC = 24,
    505 
    506   REGNO_M68K_A0 = 0,
    507   REGNO_M68K_A7 = 7,
    508   REGNO_M68K_D0 = 8,
    509   REGNO_M68K_D7 = 15,
    510   REGNO_M68K_PC = 16,
    511   REGNO_M68K_FP0 = 17,
    512   REGNO_M68K_FP7 = 24,
    513 };
    514 
    515 class Registers_M68K {
    516 public:
    517   enum {
    518     LAST_REGISTER = REGNO_M68K_FP7,
    519     LAST_RESTORE_REG = REGNO_M68K_FP7,
    520     RETURN_OFFSET = 0,
    521     RETURN_MASK = 0,
    522   };
    523 
    524   __dso_hidden Registers_M68K();
    525 
    526   static int dwarf2regno(int num) {
    527     if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
    528       return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
    529     if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
    530       return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
    531     if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
    532       return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
    533     if (num == DWARF_M68K_PC)
    534       return REGNO_M68K_PC;
    535     return LAST_REGISTER + 1;
    536   }
    537 
    538   bool validRegister(int num) const {
    539     return num >= 0 && num <= REGNO_M68K_PC;
    540   }
    541 
    542   uint64_t getRegister(int num) const {
    543     assert(validRegister(num));
    544     return reg[num];
    545   }
    546 
    547   void setRegister(int num, uint64_t value) {
    548     assert(validRegister(num));
    549     reg[num] = value;
    550   }
    551 
    552   uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
    553 
    554   void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
    555 
    556   uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
    557 
    558   void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
    559 
    560   bool validFloatVectorRegister(int num) const {
    561     return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
    562   }
    563 
    564   void copyFloatVectorRegister(int num, uint64_t addr_) {
    565     assert(validFloatVectorRegister(num));
    566     const void *addr = reinterpret_cast<const void *>(addr_);
    567     memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
    568   }
    569 
    570   __dso_hidden void jumpto() const __dead;
    571 
    572 private:
    573   typedef uint32_t fpreg_t[3];
    574 
    575   uint32_t reg[REGNO_M68K_PC + 1];
    576   uint32_t dummy;
    577   fpreg_t fpreg[8];
    578 };
    579 
    580 enum {
    581   DWARF_SH3_R0 = 0,
    582   DWARF_SH3_R15 = 15,
    583   DWARF_SH3_PC = 16,
    584   DWARF_SH3_PR = 17,
    585 
    586   REGNO_SH3_R0 = 0,
    587   REGNO_SH3_R15 = 15,
    588   REGNO_SH3_PC = 16,
    589   REGNO_SH3_PR = 17,
    590 };
    591 
    592 class Registers_SH3 {
    593 public:
    594   enum {
    595     LAST_REGISTER = REGNO_SH3_PR,
    596     LAST_RESTORE_REG = REGNO_SH3_PR,
    597     RETURN_OFFSET = 0,
    598     RETURN_MASK = 0,
    599   };
    600 
    601   __dso_hidden Registers_SH3();
    602 
    603   static int dwarf2regno(int num) {
    604     if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
    605       return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
    606     if (num == DWARF_SH3_PC)
    607       return REGNO_SH3_PC;
    608     if (num == DWARF_SH3_PR)
    609       return REGNO_SH3_PR;
    610     return LAST_REGISTER + 1;
    611   }
    612 
    613   bool validRegister(int num) const {
    614     return num >= 0 && num <= REGNO_SH3_PR;
    615   }
    616 
    617   uint64_t getRegister(int num) const {
    618     assert(validRegister(num));
    619     return reg[num];
    620   }
    621 
    622   void setRegister(int num, uint64_t value) {
    623     assert(validRegister(num));
    624     reg[num] = value;
    625   }
    626 
    627   uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
    628 
    629   void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
    630 
    631   uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
    632 
    633   void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
    634 
    635   bool validFloatVectorRegister(int num) const { return false; }
    636 
    637   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    638 
    639   __dso_hidden void jumpto() const __dead;
    640 
    641 private:
    642   uint32_t reg[REGNO_SH3_PR + 1];
    643 };
    644 
    645 enum {
    646   DWARF_SPARC64_R0 = 0,
    647   DWARF_SPARC64_R31 = 31,
    648   DWARF_SPARC64_PC = 32,
    649 
    650   REGNO_SPARC64_R0 = 0,
    651   REGNO_SPARC64_R14 = 14,
    652   REGNO_SPARC64_R15 = 15,
    653   REGNO_SPARC64_R31 = 31,
    654   REGNO_SPARC64_PC = 32,
    655 };
    656 
    657 class Registers_SPARC64 {
    658 public:
    659   enum {
    660     LAST_REGISTER = REGNO_SPARC64_PC,
    661     LAST_RESTORE_REG = REGNO_SPARC64_PC,
    662     RETURN_OFFSET = 8,
    663     RETURN_MASK = 0,
    664   };
    665   typedef uint64_t reg_t;
    666 
    667   __dso_hidden Registers_SPARC64();
    668 
    669   static int dwarf2regno(int num) {
    670     if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
    671       return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
    672     if (num == DWARF_SPARC64_PC)
    673       return REGNO_SPARC64_PC;
    674     return LAST_REGISTER + 1;
    675   }
    676 
    677   bool validRegister(int num) const {
    678     return num >= 0 && num <= REGNO_SPARC64_PC;
    679   }
    680 
    681   uint64_t getRegister(int num) const {
    682     assert(validRegister(num));
    683     return reg[num];
    684   }
    685 
    686   void setRegister(int num, uint64_t value) {
    687     assert(validRegister(num));
    688     reg[num] = value;
    689   }
    690 
    691   uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
    692 
    693   void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
    694 
    695   uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
    696 
    697   void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
    698 
    699   bool validFloatVectorRegister(int num) const { return false; }
    700 
    701   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    702 
    703   __dso_hidden void jumpto() const __dead;
    704 
    705 private:
    706   uint64_t reg[REGNO_SPARC64_PC + 1];
    707 };
    708 
    709 enum {
    710   DWARF_SPARC_R0 = 0,
    711   DWARF_SPARC_R31 = 31,
    712   DWARF_SPARC_PC = 32,
    713 
    714   REGNO_SPARC_R0 = 0,
    715   REGNO_SPARC_R14 = 14,
    716   REGNO_SPARC_R15 = 15,
    717   REGNO_SPARC_R31 = 31,
    718   REGNO_SPARC_PC = 32,
    719 };
    720 
    721 class Registers_SPARC {
    722 public:
    723   enum {
    724     LAST_REGISTER = REGNO_SPARC_PC,
    725     LAST_RESTORE_REG = REGNO_SPARC_PC,
    726     RETURN_OFFSET = 8,
    727     RETURN_MASK = 0,
    728   };
    729   typedef uint32_t reg_t;
    730 
    731   __dso_hidden Registers_SPARC();
    732 
    733   static int dwarf2regno(int num) {
    734     if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
    735       return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
    736     if (num == DWARF_SPARC_PC)
    737       return REGNO_SPARC_PC;
    738     return LAST_REGISTER + 1;
    739   }
    740 
    741   bool validRegister(int num) const {
    742     return num >= 0 && num <= REGNO_SPARC_PC;
    743   }
    744 
    745   uint64_t getRegister(int num) const {
    746     assert(validRegister(num));
    747     return reg[num];
    748   }
    749 
    750   void setRegister(int num, uint64_t value) {
    751     assert(validRegister(num));
    752     reg[num] = value;
    753   }
    754 
    755   uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
    756 
    757   void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
    758 
    759   uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
    760 
    761   void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
    762 
    763   bool validFloatVectorRegister(int num) const { return false; }
    764 
    765   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    766 
    767   __dso_hidden void jumpto() const __dead;
    768 
    769 private:
    770   uint32_t reg[REGNO_SPARC_PC + 1];
    771 };
    772 
    773 enum {
    774   DWARF_ALPHA_R0 = 0,
    775   DWARF_ALPHA_R30 = 30,
    776   DWARF_ALPHA_F0 = 32,
    777   DWARF_ALPHA_F30 = 62,
    778 
    779   REGNO_ALPHA_R0 = 0,
    780   REGNO_ALPHA_R26 = 26,
    781   REGNO_ALPHA_R30 = 30,
    782   REGNO_ALPHA_PC = 31,
    783   REGNO_ALPHA_F0 = 32,
    784   REGNO_ALPHA_F30 = 62,
    785 };
    786 
    787 class Registers_Alpha {
    788 public:
    789   enum {
    790     LAST_REGISTER = REGNO_ALPHA_F30,
    791     LAST_RESTORE_REG = REGNO_ALPHA_F30,
    792     RETURN_OFFSET = 0,
    793     RETURN_MASK = 0,
    794   };
    795   typedef uint32_t reg_t;
    796 
    797   __dso_hidden Registers_Alpha();
    798 
    799   static int dwarf2regno(int num) { return num; }
    800 
    801   bool validRegister(int num) const {
    802     return num >= 0 && num <= REGNO_ALPHA_PC;
    803   }
    804 
    805   uint64_t getRegister(int num) const {
    806     assert(validRegister(num));
    807     return reg[num];
    808   }
    809 
    810   void setRegister(int num, uint64_t value) {
    811     assert(validRegister(num));
    812     reg[num] = value;
    813   }
    814 
    815   uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
    816 
    817   void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
    818 
    819   uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
    820 
    821   void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
    822 
    823   bool validFloatVectorRegister(int num) const {
    824     return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
    825   }
    826 
    827   void copyFloatVectorRegister(int num, uint64_t addr_) {
    828     assert(validFloatVectorRegister(num));
    829     const void *addr = reinterpret_cast<const void *>(addr_);
    830     memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
    831   }
    832 
    833   __dso_hidden void jumpto() const __dead;
    834 
    835 private:
    836   uint64_t reg[REGNO_ALPHA_PC + 1];
    837   uint64_t fpreg[31];
    838 };
    839 
    840 enum {
    841   DWARF_HPPA_R1 = 1,
    842   DWARF_HPPA_R31 = 31,
    843   DWARF_HPPA_FR4L = 32,
    844   DWARF_HPPA_FR31H = 87,
    845 
    846   REGNO_HPPA_PC = 0,
    847   REGNO_HPPA_R1 = 1,
    848   REGNO_HPPA_R2 = 2,
    849   REGNO_HPPA_R30 = 30,
    850   REGNO_HPPA_R31 = 31,
    851   REGNO_HPPA_FR4L = 32,
    852   REGNO_HPPA_FR31H = 87,
    853 };
    854 
    855 class Registers_HPPA {
    856 public:
    857   enum {
    858     LAST_REGISTER = REGNO_HPPA_FR31H,
    859     LAST_RESTORE_REG = REGNO_HPPA_FR31H,
    860     RETURN_OFFSET = 0,
    861     RETURN_MASK = 3,
    862   };
    863 
    864   __dso_hidden Registers_HPPA();
    865 
    866   static int dwarf2regno(int num) {
    867     if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
    868       return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
    869     if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
    870       return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
    871     return LAST_REGISTER + 1;
    872   }
    873 
    874   bool validRegister(int num) const {
    875     return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
    876   }
    877 
    878   uint64_t getRegister(int num) const {
    879     assert(validRegister(num));
    880     return reg[num];
    881   }
    882 
    883   void setRegister(int num, uint64_t value) {
    884     assert(validRegister(num));
    885     reg[num] = value;
    886   }
    887 
    888   uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
    889 
    890   void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
    891 
    892   uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
    893 
    894   void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
    895 
    896   bool validFloatVectorRegister(int num) const {
    897     return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
    898   }
    899 
    900   void copyFloatVectorRegister(int num, uint64_t addr_) {
    901     assert(validFloatVectorRegister(num));
    902     const void *addr = reinterpret_cast<const void *>(addr_);
    903     memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
    904   }
    905 
    906   __dso_hidden void jumpto() const __dead;
    907 
    908 private:
    909   uint32_t reg[REGNO_HPPA_R31 + 1];
    910   uint32_t fpreg[56];
    911 };
    912 
    913 enum {
    914   DWARF_MIPS_R1 = 0,
    915   DWARF_MIPS_R31 = 31,
    916   DWARF_MIPS_F0 = 32,
    917   DWARF_MIPS_F31 = 63,
    918 
    919   REGNO_MIPS_PC = 0,
    920   REGNO_MIPS_R1 = 0,
    921   REGNO_MIPS_R29 = 29,
    922   REGNO_MIPS_R31 = 31,
    923   REGNO_MIPS_F0 = 33,
    924   REGNO_MIPS_F31 = 64
    925 };
    926 
    927 class Registers_MIPS {
    928 public:
    929   enum {
    930     LAST_REGISTER = REGNO_MIPS_F31,
    931     LAST_RESTORE_REG = REGNO_MIPS_F31,
    932     RETURN_OFFSET = 0,
    933     RETURN_MASK = 0,
    934   };
    935 
    936   __dso_hidden Registers_MIPS();
    937 
    938   static int dwarf2regno(int num) {
    939     if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
    940       return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
    941     if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
    942       return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
    943     return LAST_REGISTER + 1;
    944   }
    945 
    946   bool validRegister(int num) const {
    947     return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31;
    948   }
    949 
    950   uint64_t getRegister(int num) const {
    951     assert(validRegister(num));
    952     return reg[num];
    953   }
    954 
    955   void setRegister(int num, uint64_t value) {
    956     assert(validRegister(num));
    957     reg[num] = value;
    958   }
    959 
    960   uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
    961 
    962   void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
    963 
    964   uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
    965 
    966   void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
    967 
    968   bool validFloatVectorRegister(int num) const {
    969     return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31;
    970   }
    971 
    972   void copyFloatVectorRegister(int num, uint64_t addr_) {
    973     assert(validFloatVectorRegister(num));
    974     const void *addr = reinterpret_cast<const void *>(addr_);
    975     memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
    976   }
    977 
    978   __dso_hidden void jumpto() const __dead;
    979 
    980 private:
    981   uint32_t reg[REGNO_MIPS_R31 + 1];
    982   uint64_t fpreg[32];
    983 };
    984 
    985 enum {
    986   DWARF_MIPS64_R1 = 0,
    987   DWARF_MIPS64_R31 = 31,
    988   DWARF_MIPS64_F0 = 32,
    989   DWARF_MIPS64_F31 = 63,
    990 
    991   REGNO_MIPS64_PC = 0,
    992   REGNO_MIPS64_R1 = 0,
    993   REGNO_MIPS64_R29 = 29,
    994   REGNO_MIPS64_R31 = 31,
    995   REGNO_MIPS64_F0 = 33,
    996   REGNO_MIPS64_F31 = 64
    997 };
    998 
    999 class Registers_MIPS64 {
   1000 public:
   1001   enum {
   1002     LAST_REGISTER = REGNO_MIPS64_F31,
   1003     LAST_RESTORE_REG = REGNO_MIPS64_F31,
   1004     RETURN_OFFSET = 0,
   1005     RETURN_MASK = 0,
   1006   };
   1007 
   1008   __dso_hidden Registers_MIPS64();
   1009 
   1010   static int dwarf2regno(int num) {
   1011     if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
   1012       return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
   1013     if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
   1014       return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
   1015     return LAST_REGISTER + 1;
   1016   }
   1017 
   1018   bool validRegister(int num) const {
   1019     return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31;
   1020   }
   1021 
   1022   uint64_t getRegister(int num) const {
   1023     assert(validRegister(num));
   1024     return reg[num];
   1025   }
   1026 
   1027   void setRegister(int num, uint64_t value) {
   1028     assert(validRegister(num));
   1029     reg[num] = value;
   1030   }
   1031 
   1032   uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
   1033 
   1034   void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
   1035 
   1036   uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
   1037 
   1038   void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
   1039 
   1040   bool validFloatVectorRegister(int num) const {
   1041     return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31;
   1042   }
   1043 
   1044   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1045     assert(validFloatVectorRegister(num));
   1046     const void *addr = reinterpret_cast<const void *>(addr_);
   1047     memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
   1048   }
   1049 
   1050   __dso_hidden void jumpto() const __dead;
   1051 
   1052 private:
   1053   uint64_t reg[REGNO_MIPS64_R31 + 1];
   1054   uint64_t fpreg[32];
   1055 };
   1056 
   1057 enum {
   1058   DWARF_OR1K_R0 = 0,
   1059   DWARF_OR1K_SP = 1,
   1060   DWARF_OR1K_LR = 9,
   1061   DWARF_OR1K_R31 = 31,
   1062   DWARF_OR1K_FPCSR = 32,
   1063 
   1064   REGNO_OR1K_R0 = 0,
   1065   REGNO_OR1K_SP = 1,
   1066   REGNO_OR1K_LR = 9,
   1067   REGNO_OR1K_R31 = 31,
   1068   REGNO_OR1K_FPCSR = 32,
   1069 };
   1070 
   1071 class Registers_or1k {
   1072 public:
   1073   enum {
   1074     LAST_REGISTER = REGNO_OR1K_FPCSR,
   1075     LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
   1076     RETURN_OFFSET = 0,
   1077     RETURN_MASK = 0,
   1078   };
   1079 
   1080   __dso_hidden Registers_or1k();
   1081 
   1082   static int dwarf2regno(int num) {
   1083     if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
   1084       return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
   1085     if (num == DWARF_OR1K_FPCSR)
   1086       return REGNO_OR1K_FPCSR;
   1087     return LAST_REGISTER + 1;
   1088   }
   1089 
   1090   bool validRegister(int num) const {
   1091     return num >= 0 && num <= LAST_RESTORE_REG;
   1092   }
   1093 
   1094   uint64_t getRegister(int num) const {
   1095     assert(validRegister(num));
   1096     return reg[num];
   1097   }
   1098 
   1099   void setRegister(int num, uint64_t value) {
   1100     assert(validRegister(num));
   1101     reg[num] = value;
   1102   }
   1103 
   1104   uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
   1105 
   1106   void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
   1107 
   1108   uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
   1109 
   1110   void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
   1111 
   1112   bool validFloatVectorRegister(int num) const {
   1113     return false;
   1114   }
   1115 
   1116   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1117   }
   1118 
   1119   __dso_hidden void jumpto() const __dead;
   1120 
   1121 private:
   1122   uint32_t reg[REGNO_OR1K_FPCSR + 1];
   1123 };
   1124 
   1125 #if __i386__
   1126 typedef Registers_x86 NativeUnwindRegisters;
   1127 #elif __x86_64__
   1128 typedef Registers_x86_64 NativeUnwindRegisters;
   1129 #elif __powerpc__
   1130 typedef Registers_ppc32 NativeUnwindRegisters;
   1131 #elif __aarch64__
   1132 typedef Registers_aarch64 NativeUnwindRegisters;
   1133 #elif __arm__
   1134 typedef Registers_arm32 NativeUnwindRegisters;
   1135 #elif __vax__
   1136 typedef Registers_vax NativeUnwindRegisters;
   1137 #elif __m68k__
   1138 typedef Registers_M68K NativeUnwindRegisters;
   1139 #elif __mips_n64 || __mips_n32
   1140 typedef Registers_MIPS64 NativeUnwindRegisters;
   1141 #elif __mips__
   1142 typedef Registers_MIPS NativeUnwindRegisters;
   1143 #elif __sh3__
   1144 typedef Registers_SH3 NativeUnwindRegisters;
   1145 #elif __sparc64__
   1146 typedef Registers_SPARC64 NativeUnwindRegisters;
   1147 #elif __sparc__
   1148 typedef Registers_SPARC NativeUnwindRegisters;
   1149 #elif __alpha__
   1150 typedef Registers_Alpha NativeUnwindRegisters;
   1151 #elif __hppa__
   1152 typedef Registers_HPPA NativeUnwindRegisters;
   1153 #elif __or1k__
   1154 typedef Registers_or1k NativeUnwindRegisters;
   1155 #endif
   1156 } // namespace _Unwind
   1157 
   1158 #endif // __REGISTERS_HPP__
   1159