Home | History | Annotate | Line # | Download | only in libunwind
Registers.hpp revision 1.36
      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 
    659   REGNO_SH3_R0 = 0,
    660   REGNO_SH3_R15 = 15,
    661   REGNO_SH3_PC = 16,
    662   REGNO_SH3_PR = 17,
    663 };
    664 
    665 class Registers_SH3 {
    666 public:
    667   enum {
    668     LAST_REGISTER = REGNO_SH3_PR,
    669     LAST_RESTORE_REG = REGNO_SH3_PR,
    670     RETURN_OFFSET = 0,
    671     RETURN_MASK = 0,
    672   };
    673 
    674   __dso_hidden Registers_SH3();
    675 
    676   static int dwarf2regno(int num) {
    677     if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
    678       return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
    679     if (num == DWARF_SH3_PC)
    680       return REGNO_SH3_PC;
    681     if (num == DWARF_SH3_PR)
    682       return REGNO_SH3_PR;
    683     return LAST_REGISTER + 1;
    684   }
    685 
    686   bool validRegister(int num) const {
    687     return num >= 0 && num <= REGNO_SH3_PR;
    688   }
    689 
    690   uint64_t getRegister(int num) const {
    691     assert(validRegister(num));
    692     return reg[num];
    693   }
    694 
    695   void setRegister(int num, uint64_t value) {
    696     assert(validRegister(num));
    697     reg[num] = value;
    698   }
    699 
    700   uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
    701 
    702   void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
    703 
    704   uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
    705 
    706   void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
    707 
    708   bool validFloatVectorRegister(int num) const { return false; }
    709 
    710   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    711 
    712   __dso_hidden void jumpto() const __dead;
    713 
    714 private:
    715   uint32_t reg[REGNO_SH3_PR + 1];
    716 };
    717 
    718 enum {
    719   DWARF_SPARC64_R0 = 0,
    720   DWARF_SPARC64_R31 = 31,
    721   DWARF_SPARC64_PC = 32,
    722 
    723   REGNO_SPARC64_R0 = 0,
    724   REGNO_SPARC64_R14 = 14,
    725   REGNO_SPARC64_R15 = 15,
    726   REGNO_SPARC64_R31 = 31,
    727   REGNO_SPARC64_PC = 32,
    728 };
    729 
    730 class Registers_SPARC64 {
    731 public:
    732   enum {
    733     LAST_REGISTER = REGNO_SPARC64_PC,
    734     LAST_RESTORE_REG = REGNO_SPARC64_PC,
    735     RETURN_OFFSET = 8,
    736     RETURN_MASK = 0,
    737   };
    738   typedef uint64_t reg_t;
    739 
    740   __dso_hidden Registers_SPARC64();
    741 
    742   static int dwarf2regno(int num) {
    743     if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
    744       return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
    745     if (num == DWARF_SPARC64_PC)
    746       return REGNO_SPARC64_PC;
    747     return LAST_REGISTER + 1;
    748   }
    749 
    750   bool validRegister(int num) const {
    751     return num >= 0 && num <= REGNO_SPARC64_PC;
    752   }
    753 
    754   uint64_t getRegister(int num) const {
    755     assert(validRegister(num));
    756     return reg[num];
    757   }
    758 
    759   void setRegister(int num, uint64_t value) {
    760     assert(validRegister(num));
    761     reg[num] = value;
    762   }
    763 
    764   uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
    765 
    766   void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
    767 
    768   uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
    769 
    770   void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
    771 
    772   bool validFloatVectorRegister(int num) const { return false; }
    773 
    774   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    775 
    776   __dso_hidden void jumpto() const __dead;
    777 
    778 private:
    779   uint64_t reg[REGNO_SPARC64_PC + 1];
    780 };
    781 
    782 enum {
    783   DWARF_SPARC_R0 = 0,
    784   DWARF_SPARC_R31 = 31,
    785   DWARF_SPARC_PC = 32,
    786 
    787   REGNO_SPARC_R0 = 0,
    788   REGNO_SPARC_R14 = 14,
    789   REGNO_SPARC_R15 = 15,
    790   REGNO_SPARC_R31 = 31,
    791   REGNO_SPARC_PC = 32,
    792 };
    793 
    794 class Registers_SPARC {
    795 public:
    796   enum {
    797     LAST_REGISTER = REGNO_SPARC_PC,
    798     LAST_RESTORE_REG = REGNO_SPARC_PC,
    799     RETURN_OFFSET = 8,
    800     RETURN_MASK = 0,
    801   };
    802   typedef uint32_t reg_t;
    803 
    804   __dso_hidden Registers_SPARC();
    805 
    806   static int dwarf2regno(int num) {
    807     if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
    808       return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
    809     if (num == DWARF_SPARC_PC)
    810       return REGNO_SPARC_PC;
    811     return LAST_REGISTER + 1;
    812   }
    813 
    814   bool validRegister(int num) const {
    815     return num >= 0 && num <= REGNO_SPARC_PC;
    816   }
    817 
    818   uint64_t getRegister(int num) const {
    819     assert(validRegister(num));
    820     return reg[num];
    821   }
    822 
    823   void setRegister(int num, uint64_t value) {
    824     assert(validRegister(num));
    825     reg[num] = value;
    826   }
    827 
    828   uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
    829 
    830   void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
    831 
    832   uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
    833 
    834   void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
    835 
    836   bool validFloatVectorRegister(int num) const { return false; }
    837 
    838   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    839 
    840   __dso_hidden void jumpto() const __dead;
    841 
    842 private:
    843   uint32_t reg[REGNO_SPARC_PC + 1];
    844 };
    845 
    846 enum {
    847   DWARF_ALPHA_R0 = 0,
    848   DWARF_ALPHA_R30 = 30,
    849   DWARF_ALPHA_F0 = 32,
    850   DWARF_ALPHA_F30 = 62,
    851   DWARF_ALPHA_SIGRETURN = 64,
    852 
    853   REGNO_ALPHA_R0 = 0,
    854   REGNO_ALPHA_R26 = 26,
    855   REGNO_ALPHA_R30 = 30,
    856   REGNO_ALPHA_PC = 31,
    857   REGNO_ALPHA_F0 = 32,
    858   REGNO_ALPHA_F30 = 62,
    859   REGNO_ALPHA_SIGRETURN = 64,
    860 };
    861 
    862 class Registers_Alpha {
    863 public:
    864   enum {
    865     LAST_REGISTER = REGNO_ALPHA_SIGRETURN,
    866     LAST_RESTORE_REG = REGNO_ALPHA_SIGRETURN,
    867     RETURN_OFFSET = 0,
    868     RETURN_MASK = 0,
    869   };
    870   typedef uint32_t reg_t;
    871 
    872   __dso_hidden Registers_Alpha();
    873 
    874   static int dwarf2regno(int num) { return num; }
    875 
    876   bool validRegister(int num) const {
    877     return (num >= 0 && num <= REGNO_ALPHA_PC) ||
    878 	num == REGNO_ALPHA_SIGRETURN;
    879   }
    880 
    881   uint64_t getRegister(int num) const {
    882     assert(validRegister(num));
    883     if (num == REGNO_ALPHA_SIGRETURN)
    884       return sigreturn_reg;
    885     else
    886       return reg[num];
    887   }
    888 
    889   void setRegister(int num, uint64_t value) {
    890     assert(validRegister(num));
    891     if (num == REGNO_ALPHA_SIGRETURN)
    892       sigreturn_reg = value;
    893     else
    894       reg[num] = value;
    895   }
    896 
    897   uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
    898 
    899   void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
    900 
    901   uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
    902 
    903   void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
    904 
    905   bool validFloatVectorRegister(int num) const {
    906     return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
    907   }
    908 
    909   void copyFloatVectorRegister(int num, uint64_t addr_) {
    910     assert(validFloatVectorRegister(num));
    911     const void *addr = reinterpret_cast<const void *>(addr_);
    912     memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
    913   }
    914 
    915   __dso_hidden void jumpto() const __dead;
    916 
    917 private:
    918   uint64_t reg[REGNO_ALPHA_PC + 1];
    919   uint64_t fpreg[31];
    920   uint64_t sigreturn_reg;
    921 };
    922 
    923 enum {
    924   DWARF_HPPA_R1 = 1,
    925   DWARF_HPPA_R31 = 31,
    926   DWARF_HPPA_FR4L = 32,
    927   DWARF_HPPA_FR31H = 87,
    928 
    929   REGNO_HPPA_PC = 0,
    930   REGNO_HPPA_R1 = 1,
    931   REGNO_HPPA_R2 = 2,
    932   REGNO_HPPA_R30 = 30,
    933   REGNO_HPPA_R31 = 31,
    934   REGNO_HPPA_FR4L = 32,
    935   REGNO_HPPA_FR31H = 87,
    936 };
    937 
    938 class Registers_HPPA {
    939 public:
    940   enum {
    941     LAST_REGISTER = REGNO_HPPA_FR31H,
    942     LAST_RESTORE_REG = REGNO_HPPA_FR31H,
    943     RETURN_OFFSET = 0,
    944     RETURN_MASK = 3,
    945   };
    946 
    947   __dso_hidden Registers_HPPA();
    948 
    949   static int dwarf2regno(int num) {
    950     if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
    951       return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
    952     if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
    953       return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
    954     return LAST_REGISTER + 1;
    955   }
    956 
    957   bool validRegister(int num) const {
    958     return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
    959   }
    960 
    961   uint64_t getRegister(int num) const {
    962     assert(validRegister(num));
    963     return reg[num];
    964   }
    965 
    966   void setRegister(int num, uint64_t value) {
    967     assert(validRegister(num));
    968     reg[num] = value;
    969   }
    970 
    971   uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
    972 
    973   void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
    974 
    975   uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
    976 
    977   void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
    978 
    979   bool validFloatVectorRegister(int num) const {
    980     return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
    981   }
    982 
    983   void copyFloatVectorRegister(int num, uint64_t addr_) {
    984     assert(validFloatVectorRegister(num));
    985     const void *addr = reinterpret_cast<const void *>(addr_);
    986     memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
    987   }
    988 
    989   __dso_hidden void jumpto() const __dead;
    990 
    991 private:
    992   uint32_t reg[REGNO_HPPA_R31 + 1];
    993   uint32_t fpreg[56];
    994 };
    995 
    996 enum {
    997   DWARF_MIPS_R1 = 0,
    998   DWARF_MIPS_R31 = 31,
    999   DWARF_MIPS_F0 = 32,
   1000   DWARF_MIPS_F31 = 63,
   1001   // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and
   1002   // signal handler return address.
   1003   DWARF_MIPS_MDHI = 64,
   1004   DWARF_MIPS_MDLO = 65,
   1005   DWARF_MIPS_SIGRETURN = 66,
   1006 
   1007   REGNO_MIPS_PC = 0,
   1008   REGNO_MIPS_R1 = 0,
   1009   REGNO_MIPS_R29 = 29,
   1010   REGNO_MIPS_R31 = 31,
   1011   REGNO_MIPS_F0 = 33,
   1012   REGNO_MIPS_F31 = 64,
   1013   // these live in other_reg[]
   1014   REGNO_MIPS_MDHI = 65,
   1015   REGNO_MIPS_MDLO = 66,
   1016   REGNO_MIPS_SIGRETURN = 67
   1017 };
   1018 
   1019 class Registers_MIPS {
   1020 public:
   1021   enum {
   1022     LAST_REGISTER = REGNO_MIPS_SIGRETURN,
   1023     LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN,
   1024     RETURN_OFFSET = 0,
   1025     RETURN_MASK = 0,
   1026   };
   1027 
   1028   __dso_hidden Registers_MIPS();
   1029 
   1030   static int dwarf2regno(int num) {
   1031     if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
   1032       return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
   1033     if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
   1034       return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
   1035     if (num >= DWARF_MIPS_MDHI && num <= DWARF_MIPS_SIGRETURN)
   1036       return REGNO_MIPS_MDHI + (num - DWARF_MIPS_MDHI);
   1037     return LAST_REGISTER + 1;
   1038   }
   1039 
   1040   bool validRegister(int num) const {
   1041     return (num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31) ||
   1042       (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN);
   1043   }
   1044 
   1045   uint64_t getRegister(int num) const {
   1046     assert(validRegister(num));
   1047     if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN)
   1048       return other_reg[num - REGNO_MIPS_MDHI];
   1049     return reg[num];
   1050   }
   1051 
   1052   void setRegister(int num, uint64_t value) {
   1053     assert(validRegister(num));
   1054     if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN)
   1055       other_reg[num - REGNO_MIPS_MDHI] = value;
   1056     else
   1057       reg[num] = value;
   1058   }
   1059 
   1060   uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
   1061 
   1062   void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
   1063 
   1064   uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
   1065 
   1066   void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
   1067 
   1068   bool validFloatVectorRegister(int num) const {
   1069     return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31;
   1070   }
   1071 
   1072   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1073     assert(validFloatVectorRegister(num));
   1074     const void *addr = reinterpret_cast<const void *>(addr_);
   1075     memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
   1076   }
   1077 
   1078   __dso_hidden void jumpto() const __dead;
   1079 
   1080 private:
   1081   uint32_t reg[REGNO_MIPS_R31 + 1];
   1082   uint64_t fpreg[32];
   1083   uint32_t other_reg[3];
   1084 };
   1085 
   1086 enum {
   1087   DWARF_MIPS64_R1 = 0,
   1088   DWARF_MIPS64_R31 = 31,
   1089   DWARF_MIPS64_F0 = 32,
   1090   DWARF_MIPS64_F31 = 63,
   1091   // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and
   1092   // signal handler return address.
   1093   DWARF_MIPS64_MDHI = 64,
   1094   DWARF_MIPS64_MDLO = 65,
   1095   DWARF_MIPS64_SIGRETURN = 66,
   1096 
   1097   REGNO_MIPS64_PC = 0,
   1098   REGNO_MIPS64_R1 = 0,
   1099   REGNO_MIPS64_R29 = 29,
   1100   REGNO_MIPS64_R31 = 31,
   1101   REGNO_MIPS64_F0 = 33,
   1102   REGNO_MIPS64_F31 = 64,
   1103   // these live in other_reg[]
   1104   REGNO_MIPS64_MDHI = 65,
   1105   REGNO_MIPS64_MDLO = 66,
   1106   REGNO_MIPS64_SIGRETURN = 67
   1107 };
   1108 
   1109 class Registers_MIPS64 {
   1110 public:
   1111   enum {
   1112     LAST_REGISTER = REGNO_MIPS_SIGRETURN,
   1113     LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN,
   1114     RETURN_OFFSET = 0,
   1115     RETURN_MASK = 0,
   1116   };
   1117 
   1118   __dso_hidden Registers_MIPS64();
   1119 
   1120   static int dwarf2regno(int num) {
   1121     if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
   1122       return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
   1123     if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
   1124       return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
   1125     if (num >= DWARF_MIPS64_MDHI && num <= DWARF_MIPS64_SIGRETURN)
   1126       return REGNO_MIPS64_MDHI + (num - DWARF_MIPS64_MDHI);
   1127     return LAST_REGISTER + 1;
   1128   }
   1129 
   1130   bool validRegister(int num) const {
   1131     return (num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31) ||
   1132         (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN);
   1133   }
   1134 
   1135   uint64_t getRegister(int num) const {
   1136     assert(validRegister(num));
   1137     if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN)
   1138       return other_reg[num - REGNO_MIPS64_MDHI];
   1139     return reg[num];
   1140   }
   1141 
   1142   void setRegister(int num, uint64_t value) {
   1143     assert(validRegister(num));
   1144     if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN)
   1145       other_reg[num - REGNO_MIPS64_MDHI] = value;
   1146     else
   1147       reg[num] = value;
   1148   }
   1149 
   1150   uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
   1151 
   1152   void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
   1153 
   1154   uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
   1155 
   1156   void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
   1157 
   1158   bool validFloatVectorRegister(int num) const {
   1159     return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31;
   1160   }
   1161 
   1162   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1163     assert(validFloatVectorRegister(num));
   1164     const void *addr = reinterpret_cast<const void *>(addr_);
   1165     memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
   1166   }
   1167 
   1168   __dso_hidden void jumpto() const __dead;
   1169 
   1170 private:
   1171   uint64_t reg[REGNO_MIPS64_R31 + 1];
   1172   uint64_t fpreg[32];
   1173   uint64_t other_reg[3];
   1174 };
   1175 
   1176 enum {
   1177   DWARF_OR1K_R0 = 0,
   1178   DWARF_OR1K_SP = 1,
   1179   DWARF_OR1K_LR = 9,
   1180   DWARF_OR1K_R31 = 31,
   1181   DWARF_OR1K_FPCSR = 32,
   1182 
   1183   REGNO_OR1K_R0 = 0,
   1184   REGNO_OR1K_SP = 1,
   1185   REGNO_OR1K_LR = 9,
   1186   REGNO_OR1K_R31 = 31,
   1187   REGNO_OR1K_FPCSR = 32,
   1188 };
   1189 
   1190 class Registers_or1k {
   1191 public:
   1192   enum {
   1193     LAST_REGISTER = REGNO_OR1K_FPCSR,
   1194     LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
   1195     RETURN_OFFSET = 0,
   1196     RETURN_MASK = 0,
   1197   };
   1198 
   1199   __dso_hidden Registers_or1k();
   1200 
   1201   static int dwarf2regno(int num) {
   1202     if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
   1203       return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
   1204     if (num == DWARF_OR1K_FPCSR)
   1205       return REGNO_OR1K_FPCSR;
   1206     return LAST_REGISTER + 1;
   1207   }
   1208 
   1209   bool validRegister(int num) const {
   1210     return num >= 0 && num <= LAST_RESTORE_REG;
   1211   }
   1212 
   1213   uint64_t getRegister(int num) const {
   1214     assert(validRegister(num));
   1215     return reg[num];
   1216   }
   1217 
   1218   void setRegister(int num, uint64_t value) {
   1219     assert(validRegister(num));
   1220     reg[num] = value;
   1221   }
   1222 
   1223   uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
   1224 
   1225   void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
   1226 
   1227   uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
   1228 
   1229   void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
   1230 
   1231   bool validFloatVectorRegister(int num) const {
   1232     return false;
   1233   }
   1234 
   1235   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1236   }
   1237 
   1238   __dso_hidden void jumpto() const __dead;
   1239 
   1240 private:
   1241   uint32_t reg[REGNO_OR1K_FPCSR + 1];
   1242 };
   1243 
   1244 #if __i386__
   1245 typedef Registers_x86 NativeUnwindRegisters;
   1246 #elif __x86_64__
   1247 typedef Registers_x86_64 NativeUnwindRegisters;
   1248 #elif __powerpc__
   1249 typedef Registers_ppc32 NativeUnwindRegisters;
   1250 #elif __aarch64__
   1251 typedef Registers_aarch64 NativeUnwindRegisters;
   1252 #elif __arm__
   1253 typedef Registers_arm32 NativeUnwindRegisters;
   1254 #elif __vax__
   1255 typedef Registers_vax NativeUnwindRegisters;
   1256 #elif __m68k__
   1257 typedef Registers_M68K NativeUnwindRegisters;
   1258 #elif __mips_n64 || __mips_n32
   1259 typedef Registers_MIPS64 NativeUnwindRegisters;
   1260 #elif __mips__
   1261 typedef Registers_MIPS NativeUnwindRegisters;
   1262 #elif __sh3__
   1263 typedef Registers_SH3 NativeUnwindRegisters;
   1264 #elif __sparc64__
   1265 typedef Registers_SPARC64 NativeUnwindRegisters;
   1266 #elif __sparc__
   1267 typedef Registers_SPARC NativeUnwindRegisters;
   1268 #elif __alpha__
   1269 typedef Registers_Alpha NativeUnwindRegisters;
   1270 #elif __hppa__
   1271 typedef Registers_HPPA NativeUnwindRegisters;
   1272 #elif __or1k__
   1273 typedef Registers_or1k NativeUnwindRegisters;
   1274 #endif
   1275 } // namespace _Unwind
   1276 
   1277 #endif // __REGISTERS_HPP__
   1278