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