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