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