Home | History | Annotate | Line # | Download | only in libunwind
Registers.hpp revision 1.39
      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   typedef uint32_t reg_t;
    891 
    892   __dso_hidden Registers_Alpha();
    893 
    894   static int dwarf2regno(int num) { return num; }
    895 
    896   bool validRegister(int num) const {
    897     return (num >= 0 && num <= REGNO_ALPHA_PC) ||
    898 	num == REGNO_ALPHA_SIGRETURN;
    899   }
    900 
    901   uint64_t getRegister(int num) const {
    902     assert(validRegister(num));
    903     if (num == REGNO_ALPHA_SIGRETURN)
    904       return sigreturn_reg;
    905     else
    906       return reg[num];
    907   }
    908 
    909   void setRegister(int num, uint64_t value) {
    910     assert(validRegister(num));
    911     if (num == REGNO_ALPHA_SIGRETURN)
    912       sigreturn_reg = value;
    913     else
    914       reg[num] = value;
    915   }
    916 
    917   uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
    918 
    919   void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
    920 
    921   uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
    922 
    923   void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
    924 
    925   bool validFloatVectorRegister(int num) const {
    926     return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
    927   }
    928 
    929   void copyFloatVectorRegister(int num, uint64_t addr_) {
    930     assert(validFloatVectorRegister(num));
    931     const void *addr = reinterpret_cast<const void *>(addr_);
    932     memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
    933   }
    934 
    935   __dso_hidden void jumpto() const __dead;
    936 
    937 private:
    938   uint64_t reg[REGNO_ALPHA_PC + 1];
    939   uint64_t fpreg[31];
    940   uint64_t sigreturn_reg;
    941 };
    942 
    943 enum {
    944   DWARF_HPPA_R1 = 1,
    945   DWARF_HPPA_R31 = 31,
    946   DWARF_HPPA_FR4L = 32,
    947   DWARF_HPPA_FR31H = 87,
    948   DWARF_HPPA_SIGRETURN = 89,
    949 
    950   REGNO_HPPA_PC = 0,
    951   REGNO_HPPA_R1 = 1,
    952   REGNO_HPPA_R2 = 2,
    953   REGNO_HPPA_R30 = 30,
    954   REGNO_HPPA_R31 = 31,
    955   REGNO_HPPA_FR4L = 32,
    956   REGNO_HPPA_FR31H = 87,
    957   REGNO_HPPA_SIGRETURN = 89,
    958 };
    959 
    960 class Registers_HPPA {
    961 public:
    962   enum {
    963     LAST_REGISTER = REGNO_HPPA_FR31H,
    964     LAST_RESTORE_REG = REGNO_HPPA_SIGRETURN,
    965     RETURN_OFFSET = 0,
    966     RETURN_MASK = 3,
    967   };
    968 
    969   __dso_hidden Registers_HPPA();
    970 
    971   static int dwarf2regno(int num) {
    972     if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
    973       return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
    974     if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
    975       return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
    976     if (num == DWARF_HPPA_SIGRETURN)
    977       return REGNO_HPPA_SIGRETURN;
    978     return LAST_REGISTER + 1;
    979   }
    980 
    981   bool validRegister(int num) const {
    982     return (num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31) ||
    983        num == REGNO_HPPA_SIGRETURN;
    984   }
    985 
    986   uint64_t getRegister(int num) const {
    987     assert(validRegister(num));
    988     if (num == REGNO_HPPA_SIGRETURN)
    989       return sigreturn_reg;
    990     else
    991       return reg[num];
    992   }
    993 
    994   void setRegister(int num, uint64_t value) {
    995     assert(validRegister(num));
    996     if (num == REGNO_HPPA_SIGRETURN)
    997       sigreturn_reg = value;
    998     else
    999       reg[num] = value;
   1000   }
   1001 
   1002   uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
   1003 
   1004   void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
   1005 
   1006   uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
   1007 
   1008   void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
   1009 
   1010   bool validFloatVectorRegister(int num) const {
   1011     return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
   1012   }
   1013 
   1014   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1015     assert(validFloatVectorRegister(num));
   1016     const void *addr = reinterpret_cast<const void *>(addr_);
   1017     memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
   1018   }
   1019 
   1020   __dso_hidden void jumpto() const __dead;
   1021 
   1022 private:
   1023   uint32_t reg[REGNO_HPPA_R31 + 1];
   1024   uint32_t fpreg[56];
   1025   uint32_t sigreturn_reg;
   1026 };
   1027 
   1028 enum {
   1029   DWARF_MIPS_R1 = 0,
   1030   DWARF_MIPS_R31 = 31,
   1031   DWARF_MIPS_F0 = 32,
   1032   DWARF_MIPS_F31 = 63,
   1033   // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and
   1034   // signal handler return address.
   1035   DWARF_MIPS_MDHI = 64,
   1036   DWARF_MIPS_MDLO = 65,
   1037   DWARF_MIPS_SIGRETURN = 66,
   1038 
   1039   REGNO_MIPS_PC = 0,
   1040   REGNO_MIPS_R1 = 0,
   1041   REGNO_MIPS_R29 = 29,
   1042   REGNO_MIPS_R31 = 31,
   1043   REGNO_MIPS_F0 = 33,
   1044   REGNO_MIPS_F31 = 64,
   1045   // these live in other_reg[]
   1046   REGNO_MIPS_MDHI = 65,
   1047   REGNO_MIPS_MDLO = 66,
   1048   REGNO_MIPS_SIGRETURN = 67
   1049 };
   1050 
   1051 class Registers_MIPS {
   1052 public:
   1053   enum {
   1054     LAST_REGISTER = REGNO_MIPS_SIGRETURN,
   1055     LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN,
   1056     RETURN_OFFSET = 0,
   1057     RETURN_MASK = 0,
   1058   };
   1059 
   1060   __dso_hidden Registers_MIPS();
   1061 
   1062   static int dwarf2regno(int num) {
   1063     if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
   1064       return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
   1065     if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
   1066       return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
   1067     if (num >= DWARF_MIPS_MDHI && num <= DWARF_MIPS_SIGRETURN)
   1068       return REGNO_MIPS_MDHI + (num - DWARF_MIPS_MDHI);
   1069     return LAST_REGISTER + 1;
   1070   }
   1071 
   1072   bool validRegister(int num) const {
   1073     return (num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31) ||
   1074       (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN);
   1075   }
   1076 
   1077   uint64_t getRegister(int num) const {
   1078     assert(validRegister(num));
   1079     if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN)
   1080       return other_reg[num - REGNO_MIPS_MDHI];
   1081     return reg[num];
   1082   }
   1083 
   1084   void setRegister(int num, uint64_t value) {
   1085     assert(validRegister(num));
   1086     if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN)
   1087       other_reg[num - REGNO_MIPS_MDHI] = value;
   1088     else
   1089       reg[num] = value;
   1090   }
   1091 
   1092   uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
   1093 
   1094   void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
   1095 
   1096   uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
   1097 
   1098   void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
   1099 
   1100   bool validFloatVectorRegister(int num) const {
   1101     return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31;
   1102   }
   1103 
   1104   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1105     assert(validFloatVectorRegister(num));
   1106     const void *addr = reinterpret_cast<const void *>(addr_);
   1107     memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
   1108   }
   1109 
   1110   __dso_hidden void jumpto() const __dead;
   1111 
   1112 private:
   1113   uint32_t reg[REGNO_MIPS_R31 + 1];
   1114   uint64_t fpreg[32];
   1115   uint32_t other_reg[3];
   1116 };
   1117 
   1118 enum {
   1119   DWARF_MIPS64_R1 = 0,
   1120   DWARF_MIPS64_R31 = 31,
   1121   DWARF_MIPS64_F0 = 32,
   1122   DWARF_MIPS64_F31 = 63,
   1123   // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and
   1124   // signal handler return address.
   1125   DWARF_MIPS64_MDHI = 64,
   1126   DWARF_MIPS64_MDLO = 65,
   1127   DWARF_MIPS64_SIGRETURN = 66,
   1128 
   1129   REGNO_MIPS64_PC = 0,
   1130   REGNO_MIPS64_R1 = 0,
   1131   REGNO_MIPS64_R29 = 29,
   1132   REGNO_MIPS64_R31 = 31,
   1133   REGNO_MIPS64_F0 = 33,
   1134   REGNO_MIPS64_F31 = 64,
   1135   // these live in other_reg[]
   1136   REGNO_MIPS64_MDHI = 65,
   1137   REGNO_MIPS64_MDLO = 66,
   1138   REGNO_MIPS64_SIGRETURN = 67
   1139 };
   1140 
   1141 class Registers_MIPS64 {
   1142 public:
   1143   enum {
   1144     LAST_REGISTER = REGNO_MIPS_SIGRETURN,
   1145     LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN,
   1146     RETURN_OFFSET = 0,
   1147     RETURN_MASK = 0,
   1148   };
   1149 
   1150   __dso_hidden Registers_MIPS64();
   1151 
   1152   static int dwarf2regno(int num) {
   1153     if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
   1154       return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
   1155     if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
   1156       return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
   1157     if (num >= DWARF_MIPS64_MDHI && num <= DWARF_MIPS64_SIGRETURN)
   1158       return REGNO_MIPS64_MDHI + (num - DWARF_MIPS64_MDHI);
   1159     return LAST_REGISTER + 1;
   1160   }
   1161 
   1162   bool validRegister(int num) const {
   1163     return (num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31) ||
   1164         (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN);
   1165   }
   1166 
   1167   uint64_t getRegister(int num) const {
   1168     assert(validRegister(num));
   1169     if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN)
   1170       return other_reg[num - REGNO_MIPS64_MDHI];
   1171     return reg[num];
   1172   }
   1173 
   1174   void setRegister(int num, uint64_t value) {
   1175     assert(validRegister(num));
   1176     if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN)
   1177       other_reg[num - REGNO_MIPS64_MDHI] = value;
   1178     else
   1179       reg[num] = value;
   1180   }
   1181 
   1182   uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
   1183 
   1184   void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
   1185 
   1186   uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
   1187 
   1188   void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
   1189 
   1190   bool validFloatVectorRegister(int num) const {
   1191     return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31;
   1192   }
   1193 
   1194   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1195     assert(validFloatVectorRegister(num));
   1196     const void *addr = reinterpret_cast<const void *>(addr_);
   1197     memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
   1198   }
   1199 
   1200   __dso_hidden void jumpto() const __dead;
   1201 
   1202 private:
   1203   uint64_t reg[REGNO_MIPS64_R31 + 1];
   1204   uint64_t fpreg[32];
   1205   uint64_t other_reg[3];
   1206 };
   1207 
   1208 enum {
   1209   DWARF_OR1K_R0 = 0,
   1210   DWARF_OR1K_SP = 1,
   1211   DWARF_OR1K_LR = 9,
   1212   DWARF_OR1K_R31 = 31,
   1213   DWARF_OR1K_FPCSR = 32,
   1214 
   1215   REGNO_OR1K_R0 = 0,
   1216   REGNO_OR1K_SP = 1,
   1217   REGNO_OR1K_LR = 9,
   1218   REGNO_OR1K_R31 = 31,
   1219   REGNO_OR1K_FPCSR = 32,
   1220 };
   1221 
   1222 class Registers_or1k {
   1223 public:
   1224   enum {
   1225     LAST_REGISTER = REGNO_OR1K_FPCSR,
   1226     LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
   1227     RETURN_OFFSET = 0,
   1228     RETURN_MASK = 0,
   1229   };
   1230 
   1231   __dso_hidden Registers_or1k();
   1232 
   1233   static int dwarf2regno(int num) {
   1234     if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
   1235       return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
   1236     if (num == DWARF_OR1K_FPCSR)
   1237       return REGNO_OR1K_FPCSR;
   1238     return LAST_REGISTER + 1;
   1239   }
   1240 
   1241   bool validRegister(int num) const {
   1242     return num >= 0 && num <= LAST_RESTORE_REG;
   1243   }
   1244 
   1245   uint64_t getRegister(int num) const {
   1246     assert(validRegister(num));
   1247     return reg[num];
   1248   }
   1249 
   1250   void setRegister(int num, uint64_t value) {
   1251     assert(validRegister(num));
   1252     reg[num] = value;
   1253   }
   1254 
   1255   uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
   1256 
   1257   void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
   1258 
   1259   uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
   1260 
   1261   void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
   1262 
   1263   bool validFloatVectorRegister(int num) const {
   1264     return false;
   1265   }
   1266 
   1267   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1268   }
   1269 
   1270   __dso_hidden void jumpto() const __dead;
   1271 
   1272 private:
   1273   uint32_t reg[REGNO_OR1K_FPCSR + 1];
   1274 };
   1275 
   1276 #if __i386__
   1277 typedef Registers_x86 NativeUnwindRegisters;
   1278 #elif __x86_64__
   1279 typedef Registers_x86_64 NativeUnwindRegisters;
   1280 #elif __powerpc__
   1281 typedef Registers_ppc32 NativeUnwindRegisters;
   1282 #elif __aarch64__
   1283 typedef Registers_aarch64 NativeUnwindRegisters;
   1284 #elif __arm__
   1285 typedef Registers_arm32 NativeUnwindRegisters;
   1286 #elif __vax__
   1287 typedef Registers_vax NativeUnwindRegisters;
   1288 #elif __m68k__
   1289 typedef Registers_M68K NativeUnwindRegisters;
   1290 #elif __mips_n64 || __mips_n32
   1291 typedef Registers_MIPS64 NativeUnwindRegisters;
   1292 #elif __mips__
   1293 typedef Registers_MIPS NativeUnwindRegisters;
   1294 #elif __sh3__
   1295 typedef Registers_SH3 NativeUnwindRegisters;
   1296 #elif __sparc64__
   1297 typedef Registers_SPARC64 NativeUnwindRegisters;
   1298 #elif __sparc__
   1299 typedef Registers_SPARC NativeUnwindRegisters;
   1300 #elif __alpha__
   1301 typedef Registers_Alpha NativeUnwindRegisters;
   1302 #elif __hppa__
   1303 typedef Registers_HPPA NativeUnwindRegisters;
   1304 #elif __or1k__
   1305 typedef Registers_or1k NativeUnwindRegisters;
   1306 #endif
   1307 } // namespace _Unwind
   1308 
   1309 #endif // __REGISTERS_HPP__
   1310