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