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