Home | History | Annotate | Line # | Download | only in libunwind
Registers.hpp revision 1.20
      1 //===----------------------------- Registers.hpp --------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //
      9 //  Models register sets for supported processors.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 #ifndef __REGISTERS_HPP__
     13 #define __REGISTERS_HPP__
     14 
     15 #include <sys/endian.h>
     16 #include <cassert>
     17 #include <cstdint>
     18 
     19 namespace _Unwind {
     20 
     21 enum {
     22   REGNO_X86_EAX = 0,
     23   REGNO_X86_ECX = 1,
     24   REGNO_X86_EDX = 2,
     25   REGNO_X86_EBX = 3,
     26   REGNO_X86_ESP = 4,
     27   REGNO_X86_EBP = 5,
     28   REGNO_X86_ESI = 6,
     29   REGNO_X86_EDI = 7,
     30   REGNO_X86_EIP = 8,
     31 };
     32 
     33 class Registers_x86 {
     34 public:
     35   enum {
     36     LAST_REGISTER = REGNO_X86_EIP,
     37     LAST_RESTORE_REG = REGNO_X86_EIP,
     38     RETURN_OFFSET = 0,
     39     RETURN_MASK = 0,
     40   };
     41 
     42   __dso_hidden Registers_x86();
     43 
     44   static int dwarf2regno(int num) { return num; }
     45 
     46   bool validRegister(int num) const {
     47     return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
     48   }
     49 
     50   uint32_t getRegister(int num) const {
     51     assert(validRegister(num));
     52     return reg[num];
     53   }
     54 
     55   void setRegister(int num, uint32_t value) {
     56     assert(validRegister(num));
     57     reg[num] = value;
     58   }
     59 
     60   uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
     61 
     62   void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
     63 
     64   uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
     65 
     66   void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
     67 
     68   bool validFloatVectorRegister(int num) const { return false; }
     69 
     70   void copyFloatVectorRegister(int num, uint32_t addr) {
     71   }
     72 
     73   __dso_hidden void jumpto() const __dead;
     74 
     75 private:
     76   uint32_t reg[REGNO_X86_EIP + 1];
     77 };
     78 
     79 enum {
     80   REGNO_X86_64_RAX = 0,
     81   REGNO_X86_64_RDX = 1,
     82   REGNO_X86_64_RCX = 2,
     83   REGNO_X86_64_RBX = 3,
     84   REGNO_X86_64_RSI = 4,
     85   REGNO_X86_64_RDI = 5,
     86   REGNO_X86_64_RBP = 6,
     87   REGNO_X86_64_RSP = 7,
     88   REGNO_X86_64_R8 = 8,
     89   REGNO_X86_64_R9 = 9,
     90   REGNO_X86_64_R10 = 10,
     91   REGNO_X86_64_R11 = 11,
     92   REGNO_X86_64_R12 = 12,
     93   REGNO_X86_64_R13 = 13,
     94   REGNO_X86_64_R14 = 14,
     95   REGNO_X86_64_R15 = 15,
     96   REGNO_X86_64_RIP = 16,
     97 };
     98 
     99 class Registers_x86_64 {
    100 public:
    101   enum {
    102     LAST_REGISTER = REGNO_X86_64_RIP,
    103     LAST_RESTORE_REG = REGNO_X86_64_RIP,
    104     RETURN_OFFSET = 0,
    105     RETURN_MASK = 0,
    106   };
    107 
    108   __dso_hidden Registers_x86_64();
    109 
    110   static int dwarf2regno(int num) { return num; }
    111 
    112   bool validRegister(int num) const {
    113     return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
    114   }
    115 
    116   uint64_t getRegister(int num) const {
    117     assert(validRegister(num));
    118     return reg[num];
    119   }
    120 
    121   void setRegister(int num, uint64_t value) {
    122     assert(validRegister(num));
    123     reg[num] = value;
    124   }
    125 
    126   uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
    127 
    128   void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
    129 
    130   uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
    131 
    132   void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
    133 
    134   bool validFloatVectorRegister(int num) const { return false; }
    135 
    136   void copyFloatVectorRegister(int num, uint64_t addr) {
    137   }
    138 
    139   __dso_hidden void jumpto() const __dead;
    140 
    141 private:
    142   uint64_t reg[REGNO_X86_64_RIP + 1];
    143 };
    144 
    145 enum {
    146   DWARF_PPC32_R0 = 0,
    147   DWARF_PPC32_R31 = 31,
    148   DWARF_PPC32_F0 = 32,
    149   DWARF_PPC32_F31 = 63,
    150   DWARF_PPC32_LR = 65,
    151   DWARF_PPC32_CR = 70,
    152   DWARF_PPC32_V0 = 77,
    153   DWARF_PPC32_V31 = 108,
    154 
    155   REGNO_PPC32_R0 = 0,
    156   REGNO_PPC32_R1 = 1,
    157   REGNO_PPC32_R31 = 31,
    158   REGNO_PPC32_LR = 32,
    159   REGNO_PPC32_CR = 33,
    160   REGNO_PPC32_SRR0 = 34,
    161 
    162   REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
    163   REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
    164   REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
    165   REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
    166 };
    167 
    168 class Registers_ppc32 {
    169 public:
    170   enum {
    171     LAST_REGISTER = REGNO_PPC32_V31,
    172     LAST_RESTORE_REG = REGNO_PPC32_V31,
    173     RETURN_OFFSET = 0,
    174     RETURN_MASK = 0,
    175   };
    176 
    177   __dso_hidden Registers_ppc32();
    178 
    179   static int dwarf2regno(int num) {
    180     if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
    181       return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
    182     if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
    183       return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
    184     if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
    185       return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
    186     switch (num) {
    187     case DWARF_PPC32_LR:
    188       return REGNO_PPC32_LR;
    189     case DWARF_PPC32_CR:
    190       return REGNO_PPC32_CR;
    191     default:
    192       return LAST_REGISTER + 1;
    193     }
    194   }
    195 
    196   bool validRegister(int num) const {
    197     return num >= 0 && num <= LAST_RESTORE_REG;
    198   }
    199 
    200   uint64_t getRegister(int num) const {
    201     assert(validRegister(num));
    202     return reg[num];
    203   }
    204 
    205   void setRegister(int num, uint64_t value) {
    206     assert(validRegister(num));
    207     reg[num] = value;
    208   }
    209 
    210   uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
    211 
    212   void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
    213 
    214   uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
    215 
    216   void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
    217 
    218   bool validFloatVectorRegister(int num) const {
    219     return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
    220            (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
    221   }
    222 
    223   void copyFloatVectorRegister(int num, uint64_t addr_) {
    224     const void *addr = reinterpret_cast<const void *>(addr_);
    225     if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
    226       memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
    227     else
    228       memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
    229   }
    230 
    231   __dso_hidden void jumpto() const __dead;
    232 
    233 private:
    234   struct vecreg_t {
    235     uint64_t low, high;
    236   };
    237   uint32_t reg[REGNO_PPC32_SRR0 + 1];
    238   uint32_t dummy;
    239   uint64_t fpreg[32];
    240   vecreg_t vecreg[64];
    241 };
    242 
    243 enum {
    244   DWARF_AARCH64_X0 = 0,
    245   DWARF_AARCH64_X30 = 30,
    246   DWARF_AARCH64_SP = 31,
    247   DWARF_AARCH64_ELR_MODE = 33,
    248   DWARF_AARCH64_V0 = 64,
    249   DWARF_AARCH64_V31 = 95,
    250 
    251   REGNO_AARCH64_X0 = 0,
    252   REGNO_AARCH64_X30 = 30,
    253   REGNO_AARCH64_SP = 31,
    254   REGNO_AARCH64_ELR_MODE = 32,
    255   REGNO_AARCH64_V0 = 33,
    256   REGNO_AARCH64_V31 = 64,
    257 };
    258 
    259 class Registers_aarch64 {
    260 public:
    261   enum {
    262     LAST_RESTORE_REG = REGNO_AARCH64_V31,
    263     LAST_REGISTER = REGNO_AARCH64_V31,
    264     RETURN_OFFSET = 0,
    265     RETURN_MASK = 0,
    266   };
    267 
    268   __dso_hidden Registers_aarch64();
    269 
    270   static int dwarf2regno(int num) {
    271     if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30)
    272       return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0);
    273     if (num == DWARF_AARCH64_SP)
    274       return REGNO_AARCH64_SP;
    275     if (num == DWARF_AARCH64_ELR_MODE)
    276       return REGNO_AARCH64_ELR_MODE;
    277     if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31)
    278       return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0);
    279     return LAST_REGISTER + 1;
    280   }
    281 
    282   bool validRegister(int num) const {
    283     return num >= 0 && num <= LAST_RESTORE_REG;
    284   }
    285 
    286   uint64_t getRegister(int num) const {
    287     assert(validRegister(num));
    288     return reg[num];
    289   }
    290 
    291   void setRegister(int num, uint64_t value) {
    292     assert(validRegister(num));
    293     reg[num] = value;
    294   }
    295 
    296   uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; }
    297 
    298   void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; }
    299 
    300   uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; }
    301 
    302   void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; }
    303 
    304   bool validFloatVectorRegister(int num) const {
    305     return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31);
    306   }
    307 
    308   void copyFloatVectorRegister(int num, uint64_t addr_) {
    309     const void *addr = reinterpret_cast<const void *>(addr_);
    310     memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, sizeof(vecreg[0]));
    311   }
    312 
    313   __dso_hidden void jumpto() const __dead;
    314 
    315 private:
    316   struct vecreg_t {
    317     uint64_t low, high;
    318   };
    319   uint64_t reg[REGNO_AARCH64_ELR_MODE + 1];
    320   vecreg_t vecreg[32];
    321 };
    322 
    323 enum {
    324   DWARF_ARM32_R0 = 0,
    325   DWARF_ARM32_R15 = 15,
    326   DWARF_ARM32_SPSR = 128,
    327   DWARF_ARM32_S0 = 64,
    328   DWARF_ARM32_S31 = 91,
    329   DWARF_ARM32_D0 = 256,
    330   DWARF_ARM32_D31 = 287,
    331   REGNO_ARM32_R0 = 0,
    332   REGNO_ARM32_SP = 13,
    333   REGNO_ARM32_R15 = 15,
    334   REGNO_ARM32_SPSR = 16,
    335   REGNO_ARM32_D0 = 17,
    336   REGNO_ARM32_D15 = 32,
    337   REGNO_ARM32_D31 = 48,
    338   REGNO_ARM32_S0 = 49,
    339   REGNO_ARM32_S31 = 70,
    340 };
    341 
    342 class Registers_arm32 {
    343 public:
    344   enum {
    345     LAST_REGISTER = REGNO_ARM32_D31,
    346     LAST_RESTORE_REG = REGNO_ARM32_D31,
    347     RETURN_OFFSET = 0,
    348     RETURN_MASK = 0,
    349   };
    350 
    351   __dso_hidden Registers_arm32();
    352 
    353   static int dwarf2regno(int num) {
    354     if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
    355       return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
    356     if (num == DWARF_ARM32_SPSR)
    357       return REGNO_ARM32_SPSR;
    358     if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
    359       return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
    360     if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31) {
    361       return REGNO_ARM32_S0 + (num - DWARF_ARM32_S0);
    362     }
    363     return LAST_REGISTER + 1;
    364   }
    365 
    366   bool validRegister(int num) const {
    367     return num >= 0 && num <= REGNO_ARM32_SPSR;
    368   }
    369 
    370   uint64_t getRegister(int num) const {
    371     assert(validRegister(num));
    372     return reg[num];
    373   }
    374 
    375   void setRegister(int num, uint64_t value) {
    376     assert(validRegister(num));
    377     reg[num] = value;
    378   }
    379 
    380   uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
    381 
    382   void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
    383 
    384   uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
    385 
    386   void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
    387 
    388   bool validFloatVectorRegister(int num) const {
    389     return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31);
    390   }
    391 
    392   void copyFloatVectorRegister(int num, uint64_t addr_) {
    393     const void *addr = reinterpret_cast<const void *>(addr_);
    394     if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) {
    395       if ((flags & 1) == 0) {
    396         lazyVFP1();
    397         flags |= 1;
    398       }
    399       /*
    400        * Emulate single precision register as half of the
    401        * corresponding double register.
    402        */
    403       int dnum = (num - REGNO_ARM32_S0) / 2;
    404       int part = (num - REGNO_ARM32_S0) % 2;
    405 #if _BYTE_ORDER == _BIG_ENDIAN
    406       part = 1 - part;
    407 #endif
    408       memcpy(fpreg + dnum + part * sizeof(fpreg[0]) / 2,
    409         addr, sizeof(fpreg[0]) / 2);
    410     }
    411     if (num <= REGNO_ARM32_D15) {
    412       if ((flags & 1) == 0) {
    413         lazyVFP1();
    414         flags |= 1;
    415       }
    416     } else {
    417       if ((flags & 2) == 0) {
    418         lazyVFP3();
    419         flags |= 2;
    420       }
    421     }
    422     memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
    423   }
    424 
    425   __dso_hidden void lazyVFP1();
    426   __dso_hidden void lazyVFP3();
    427   __dso_hidden void jumpto() const __dead;
    428 
    429 private:
    430   uint32_t reg[REGNO_ARM32_SPSR + 1];
    431   uint32_t flags;
    432   uint64_t fpreg[32];
    433 };
    434 
    435 enum {
    436   DWARF_VAX_R0 = 0,
    437   DWARF_VAX_R15 = 15,
    438   DWARF_VAX_PSW = 16,
    439 
    440   REGNO_VAX_R0 = 0,
    441   REGNO_VAX_R14 = 14,
    442   REGNO_VAX_R15 = 15,
    443   REGNO_VAX_PSW = 16,
    444 };
    445 
    446 class Registers_vax {
    447 public:
    448   enum {
    449     LAST_REGISTER = REGNO_VAX_PSW,
    450     LAST_RESTORE_REG = REGNO_VAX_PSW,
    451     RETURN_OFFSET = 0,
    452     RETURN_MASK = 0,
    453   };
    454 
    455   __dso_hidden Registers_vax();
    456 
    457   static int dwarf2regno(int num) {
    458     if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
    459       return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
    460     if (num == DWARF_VAX_PSW)
    461       return REGNO_VAX_PSW;
    462     return LAST_REGISTER + 1;
    463   }
    464 
    465   bool validRegister(int num) const {
    466     return num >= 0 && num <= LAST_RESTORE_REG;
    467   }
    468 
    469   uint64_t getRegister(int num) const {
    470     assert(validRegister(num));
    471     return reg[num];
    472   }
    473 
    474   void setRegister(int num, uint64_t value) {
    475     assert(validRegister(num));
    476     reg[num] = value;
    477   }
    478 
    479   uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
    480 
    481   void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
    482 
    483   uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
    484 
    485   void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
    486 
    487   bool validFloatVectorRegister(int num) const {
    488     return false;
    489   }
    490 
    491   void copyFloatVectorRegister(int num, uint64_t addr_) {
    492   }
    493 
    494   __dso_hidden void jumpto() const __dead;
    495 
    496 private:
    497   uint32_t reg[REGNO_VAX_PSW + 1];
    498 };
    499 
    500 enum {
    501   DWARF_M68K_A0 = 0,
    502   DWARF_M68K_A7 = 7,
    503   DWARF_M68K_D0 = 8,
    504   DWARF_M68K_D7 = 15,
    505   DWARF_M68K_FP0 = 16,
    506   DWARF_M68K_FP7 = 23,
    507   DWARF_M68K_PC = 24,
    508 
    509   REGNO_M68K_A0 = 0,
    510   REGNO_M68K_A7 = 7,
    511   REGNO_M68K_D0 = 8,
    512   REGNO_M68K_D7 = 15,
    513   REGNO_M68K_PC = 16,
    514   REGNO_M68K_FP0 = 17,
    515   REGNO_M68K_FP7 = 24,
    516 };
    517 
    518 class Registers_M68K {
    519 public:
    520   enum {
    521     LAST_REGISTER = REGNO_M68K_FP7,
    522     LAST_RESTORE_REG = REGNO_M68K_FP7,
    523     RETURN_OFFSET = 0,
    524     RETURN_MASK = 0,
    525   };
    526 
    527   __dso_hidden Registers_M68K();
    528 
    529   static int dwarf2regno(int num) {
    530     if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
    531       return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
    532     if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
    533       return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
    534     if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
    535       return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
    536     if (num == DWARF_M68K_PC)
    537       return REGNO_M68K_PC;
    538     return LAST_REGISTER + 1;
    539   }
    540 
    541   bool validRegister(int num) const {
    542     return num >= 0 && num <= REGNO_M68K_PC;
    543   }
    544 
    545   uint64_t getRegister(int num) const {
    546     assert(validRegister(num));
    547     return reg[num];
    548   }
    549 
    550   void setRegister(int num, uint64_t value) {
    551     assert(validRegister(num));
    552     reg[num] = value;
    553   }
    554 
    555   uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
    556 
    557   void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
    558 
    559   uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
    560 
    561   void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
    562 
    563   bool validFloatVectorRegister(int num) const {
    564     return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
    565   }
    566 
    567   void copyFloatVectorRegister(int num, uint64_t addr_) {
    568     assert(validFloatVectorRegister(num));
    569     const void *addr = reinterpret_cast<const void *>(addr_);
    570     memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
    571   }
    572 
    573   __dso_hidden void jumpto() const __dead;
    574 
    575 private:
    576   typedef uint32_t fpreg_t[3];
    577 
    578   uint32_t reg[REGNO_M68K_PC + 1];
    579   uint32_t dummy;
    580   fpreg_t fpreg[8];
    581 };
    582 
    583 enum {
    584   DWARF_SH3_R0 = 0,
    585   DWARF_SH3_R15 = 15,
    586   DWARF_SH3_PC = 16,
    587   DWARF_SH3_PR = 17,
    588 
    589   REGNO_SH3_R0 = 0,
    590   REGNO_SH3_R15 = 15,
    591   REGNO_SH3_PC = 16,
    592   REGNO_SH3_PR = 17,
    593 };
    594 
    595 class Registers_SH3 {
    596 public:
    597   enum {
    598     LAST_REGISTER = REGNO_SH3_PR,
    599     LAST_RESTORE_REG = REGNO_SH3_PR,
    600     RETURN_OFFSET = 0,
    601     RETURN_MASK = 0,
    602   };
    603 
    604   __dso_hidden Registers_SH3();
    605 
    606   static int dwarf2regno(int num) {
    607     if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
    608       return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
    609     if (num == DWARF_SH3_PC)
    610       return REGNO_SH3_PC;
    611     if (num == DWARF_SH3_PR)
    612       return REGNO_SH3_PR;
    613     return LAST_REGISTER + 1;
    614   }
    615 
    616   bool validRegister(int num) const {
    617     return num >= 0 && num <= REGNO_SH3_PR;
    618   }
    619 
    620   uint64_t getRegister(int num) const {
    621     assert(validRegister(num));
    622     return reg[num];
    623   }
    624 
    625   void setRegister(int num, uint64_t value) {
    626     assert(validRegister(num));
    627     reg[num] = value;
    628   }
    629 
    630   uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
    631 
    632   void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
    633 
    634   uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
    635 
    636   void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
    637 
    638   bool validFloatVectorRegister(int num) const { return false; }
    639 
    640   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    641 
    642   __dso_hidden void jumpto() const __dead;
    643 
    644 private:
    645   uint32_t reg[REGNO_SH3_PR + 1];
    646 };
    647 
    648 enum {
    649   DWARF_SPARC64_R0 = 0,
    650   DWARF_SPARC64_R31 = 31,
    651   DWARF_SPARC64_PC = 32,
    652 
    653   REGNO_SPARC64_R0 = 0,
    654   REGNO_SPARC64_R14 = 14,
    655   REGNO_SPARC64_R15 = 15,
    656   REGNO_SPARC64_R31 = 31,
    657   REGNO_SPARC64_PC = 32,
    658 };
    659 
    660 class Registers_SPARC64 {
    661 public:
    662   enum {
    663     LAST_REGISTER = REGNO_SPARC64_PC,
    664     LAST_RESTORE_REG = REGNO_SPARC64_PC,
    665     RETURN_OFFSET = 8,
    666     RETURN_MASK = 0,
    667   };
    668   typedef uint64_t reg_t;
    669 
    670   __dso_hidden Registers_SPARC64();
    671 
    672   static int dwarf2regno(int num) {
    673     if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
    674       return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
    675     if (num == DWARF_SPARC64_PC)
    676       return REGNO_SPARC64_PC;
    677     return LAST_REGISTER + 1;
    678   }
    679 
    680   bool validRegister(int num) const {
    681     return num >= 0 && num <= REGNO_SPARC64_PC;
    682   }
    683 
    684   uint64_t getRegister(int num) const {
    685     assert(validRegister(num));
    686     return reg[num];
    687   }
    688 
    689   void setRegister(int num, uint64_t value) {
    690     assert(validRegister(num));
    691     reg[num] = value;
    692   }
    693 
    694   uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
    695 
    696   void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
    697 
    698   uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
    699 
    700   void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
    701 
    702   bool validFloatVectorRegister(int num) const { return false; }
    703 
    704   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    705 
    706   __dso_hidden void jumpto() const __dead;
    707 
    708 private:
    709   uint64_t reg[REGNO_SPARC64_PC + 1];
    710 };
    711 
    712 enum {
    713   DWARF_SPARC_R0 = 0,
    714   DWARF_SPARC_R31 = 31,
    715   DWARF_SPARC_PC = 32,
    716 
    717   REGNO_SPARC_R0 = 0,
    718   REGNO_SPARC_R14 = 14,
    719   REGNO_SPARC_R15 = 15,
    720   REGNO_SPARC_R31 = 31,
    721   REGNO_SPARC_PC = 32,
    722 };
    723 
    724 class Registers_SPARC {
    725 public:
    726   enum {
    727     LAST_REGISTER = REGNO_SPARC_PC,
    728     LAST_RESTORE_REG = REGNO_SPARC_PC,
    729     RETURN_OFFSET = 8,
    730     RETURN_MASK = 0,
    731   };
    732   typedef uint32_t reg_t;
    733 
    734   __dso_hidden Registers_SPARC();
    735 
    736   static int dwarf2regno(int num) {
    737     if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
    738       return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
    739     if (num == DWARF_SPARC_PC)
    740       return REGNO_SPARC_PC;
    741     return LAST_REGISTER + 1;
    742   }
    743 
    744   bool validRegister(int num) const {
    745     return num >= 0 && num <= REGNO_SPARC_PC;
    746   }
    747 
    748   uint64_t getRegister(int num) const {
    749     assert(validRegister(num));
    750     return reg[num];
    751   }
    752 
    753   void setRegister(int num, uint64_t value) {
    754     assert(validRegister(num));
    755     reg[num] = value;
    756   }
    757 
    758   uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
    759 
    760   void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
    761 
    762   uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
    763 
    764   void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
    765 
    766   bool validFloatVectorRegister(int num) const { return false; }
    767 
    768   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    769 
    770   __dso_hidden void jumpto() const __dead;
    771 
    772 private:
    773   uint32_t reg[REGNO_SPARC_PC + 1];
    774 };
    775 
    776 enum {
    777   DWARF_ALPHA_R0 = 0,
    778   DWARF_ALPHA_R30 = 30,
    779   DWARF_ALPHA_F0 = 32,
    780   DWARF_ALPHA_F30 = 62,
    781 
    782   REGNO_ALPHA_R0 = 0,
    783   REGNO_ALPHA_R26 = 26,
    784   REGNO_ALPHA_R30 = 30,
    785   REGNO_ALPHA_PC = 31,
    786   REGNO_ALPHA_F0 = 32,
    787   REGNO_ALPHA_F30 = 62,
    788 };
    789 
    790 class Registers_Alpha {
    791 public:
    792   enum {
    793     LAST_REGISTER = REGNO_ALPHA_F30,
    794     LAST_RESTORE_REG = REGNO_ALPHA_F30,
    795     RETURN_OFFSET = 0,
    796     RETURN_MASK = 0,
    797   };
    798   typedef uint32_t reg_t;
    799 
    800   __dso_hidden Registers_Alpha();
    801 
    802   static int dwarf2regno(int num) { return num; }
    803 
    804   bool validRegister(int num) const {
    805     return num >= 0 && num <= REGNO_ALPHA_PC;
    806   }
    807 
    808   uint64_t getRegister(int num) const {
    809     assert(validRegister(num));
    810     return reg[num];
    811   }
    812 
    813   void setRegister(int num, uint64_t value) {
    814     assert(validRegister(num));
    815     reg[num] = value;
    816   }
    817 
    818   uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
    819 
    820   void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
    821 
    822   uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
    823 
    824   void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
    825 
    826   bool validFloatVectorRegister(int num) const {
    827     return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
    828   }
    829 
    830   void copyFloatVectorRegister(int num, uint64_t addr_) {
    831     assert(validFloatVectorRegister(num));
    832     const void *addr = reinterpret_cast<const void *>(addr_);
    833     memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
    834   }
    835 
    836   __dso_hidden void jumpto() const __dead;
    837 
    838 private:
    839   uint64_t reg[REGNO_ALPHA_PC + 1];
    840   uint64_t fpreg[31];
    841 };
    842 
    843 enum {
    844   DWARF_HPPA_R1 = 1,
    845   DWARF_HPPA_R31 = 31,
    846   DWARF_HPPA_FR4L = 32,
    847   DWARF_HPPA_FR31H = 87,
    848 
    849   REGNO_HPPA_PC = 0,
    850   REGNO_HPPA_R1 = 1,
    851   REGNO_HPPA_R2 = 2,
    852   REGNO_HPPA_R30 = 30,
    853   REGNO_HPPA_R31 = 31,
    854   REGNO_HPPA_FR4L = 32,
    855   REGNO_HPPA_FR31H = 87,
    856 };
    857 
    858 class Registers_HPPA {
    859 public:
    860   enum {
    861     LAST_REGISTER = REGNO_HPPA_FR31H,
    862     LAST_RESTORE_REG = REGNO_HPPA_FR31H,
    863     RETURN_OFFSET = 0,
    864     RETURN_MASK = 3,
    865   };
    866 
    867   __dso_hidden Registers_HPPA();
    868 
    869   static int dwarf2regno(int num) {
    870     if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
    871       return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
    872     if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
    873       return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
    874     return LAST_REGISTER + 1;
    875   }
    876 
    877   bool validRegister(int num) const {
    878     return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
    879   }
    880 
    881   uint64_t getRegister(int num) const {
    882     assert(validRegister(num));
    883     return reg[num];
    884   }
    885 
    886   void setRegister(int num, uint64_t value) {
    887     assert(validRegister(num));
    888     reg[num] = value;
    889   }
    890 
    891   uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
    892 
    893   void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
    894 
    895   uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
    896 
    897   void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
    898 
    899   bool validFloatVectorRegister(int num) const {
    900     return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
    901   }
    902 
    903   void copyFloatVectorRegister(int num, uint64_t addr_) {
    904     assert(validFloatVectorRegister(num));
    905     const void *addr = reinterpret_cast<const void *>(addr_);
    906     memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
    907   }
    908 
    909   __dso_hidden void jumpto() const __dead;
    910 
    911 private:
    912   uint32_t reg[REGNO_HPPA_R31 + 1];
    913   uint32_t fpreg[56];
    914 };
    915 
    916 enum {
    917   DWARF_MIPS_R1 = 0,
    918   DWARF_MIPS_R31 = 31,
    919   DWARF_MIPS_F0 = 32,
    920   DWARF_MIPS_F31 = 63,
    921 
    922   REGNO_MIPS_PC = 0,
    923   REGNO_MIPS_R1 = 0,
    924   REGNO_MIPS_R29 = 29,
    925   REGNO_MIPS_R31 = 31,
    926   REGNO_MIPS_F0 = 33,
    927   REGNO_MIPS_F31 = 64
    928 };
    929 
    930 class Registers_MIPS {
    931 public:
    932   enum {
    933     LAST_REGISTER = REGNO_MIPS_F31,
    934     LAST_RESTORE_REG = REGNO_MIPS_F31,
    935     RETURN_OFFSET = 0,
    936     RETURN_MASK = 0,
    937   };
    938 
    939   __dso_hidden Registers_MIPS();
    940 
    941   static int dwarf2regno(int num) {
    942     if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
    943       return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
    944     if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
    945       return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
    946     return LAST_REGISTER + 1;
    947   }
    948 
    949   bool validRegister(int num) const {
    950     return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31;
    951   }
    952 
    953   uint64_t getRegister(int num) const {
    954     assert(validRegister(num));
    955     return reg[num];
    956   }
    957 
    958   void setRegister(int num, uint64_t value) {
    959     assert(validRegister(num));
    960     reg[num] = value;
    961   }
    962 
    963   uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
    964 
    965   void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
    966 
    967   uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
    968 
    969   void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
    970 
    971   bool validFloatVectorRegister(int num) const {
    972     return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31;
    973   }
    974 
    975   void copyFloatVectorRegister(int num, uint64_t addr_) {
    976     assert(validFloatVectorRegister(num));
    977     const void *addr = reinterpret_cast<const void *>(addr_);
    978     memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
    979   }
    980 
    981   __dso_hidden void jumpto() const __dead;
    982 
    983 private:
    984   uint32_t reg[REGNO_MIPS_R31 + 1];
    985   uint64_t fpreg[32];
    986 };
    987 
    988 enum {
    989   DWARF_MIPS64_R1 = 0,
    990   DWARF_MIPS64_R31 = 31,
    991   DWARF_MIPS64_F0 = 32,
    992   DWARF_MIPS64_F31 = 63,
    993 
    994   REGNO_MIPS64_PC = 0,
    995   REGNO_MIPS64_R1 = 0,
    996   REGNO_MIPS64_R29 = 29,
    997   REGNO_MIPS64_R31 = 31,
    998   REGNO_MIPS64_F0 = 33,
    999   REGNO_MIPS64_F31 = 64
   1000 };
   1001 
   1002 class Registers_MIPS64 {
   1003 public:
   1004   enum {
   1005     LAST_REGISTER = REGNO_MIPS64_F31,
   1006     LAST_RESTORE_REG = REGNO_MIPS64_F31,
   1007     RETURN_OFFSET = 0,
   1008     RETURN_MASK = 0,
   1009   };
   1010 
   1011   __dso_hidden Registers_MIPS64();
   1012 
   1013   static int dwarf2regno(int num) {
   1014     if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
   1015       return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
   1016     if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
   1017       return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
   1018     return LAST_REGISTER + 1;
   1019   }
   1020 
   1021   bool validRegister(int num) const {
   1022     return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31;
   1023   }
   1024 
   1025   uint64_t getRegister(int num) const {
   1026     assert(validRegister(num));
   1027     return reg[num];
   1028   }
   1029 
   1030   void setRegister(int num, uint64_t value) {
   1031     assert(validRegister(num));
   1032     reg[num] = value;
   1033   }
   1034 
   1035   uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
   1036 
   1037   void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
   1038 
   1039   uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
   1040 
   1041   void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
   1042 
   1043   bool validFloatVectorRegister(int num) const {
   1044     return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31;
   1045   }
   1046 
   1047   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1048     assert(validFloatVectorRegister(num));
   1049     const void *addr = reinterpret_cast<const void *>(addr_);
   1050     memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
   1051   }
   1052 
   1053   __dso_hidden void jumpto() const __dead;
   1054 
   1055 private:
   1056   uint64_t reg[REGNO_MIPS64_R31 + 1];
   1057   uint64_t fpreg[32];
   1058 };
   1059 
   1060 enum {
   1061   DWARF_OR1K_R0 = 0,
   1062   DWARF_OR1K_SP = 1,
   1063   DWARF_OR1K_LR = 9,
   1064   DWARF_OR1K_R31 = 31,
   1065   DWARF_OR1K_FPCSR = 32,
   1066 
   1067   REGNO_OR1K_R0 = 0,
   1068   REGNO_OR1K_SP = 1,
   1069   REGNO_OR1K_LR = 9,
   1070   REGNO_OR1K_R31 = 31,
   1071   REGNO_OR1K_FPCSR = 32,
   1072 };
   1073 
   1074 class Registers_or1k {
   1075 public:
   1076   enum {
   1077     LAST_REGISTER = REGNO_OR1K_FPCSR,
   1078     LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
   1079     RETURN_OFFSET = 0,
   1080     RETURN_MASK = 0,
   1081   };
   1082 
   1083   __dso_hidden Registers_or1k();
   1084 
   1085   static int dwarf2regno(int num) {
   1086     if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
   1087       return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
   1088     if (num == DWARF_OR1K_FPCSR)
   1089       return REGNO_OR1K_FPCSR;
   1090     return LAST_REGISTER + 1;
   1091   }
   1092 
   1093   bool validRegister(int num) const {
   1094     return num >= 0 && num <= LAST_RESTORE_REG;
   1095   }
   1096 
   1097   uint64_t getRegister(int num) const {
   1098     assert(validRegister(num));
   1099     return reg[num];
   1100   }
   1101 
   1102   void setRegister(int num, uint64_t value) {
   1103     assert(validRegister(num));
   1104     reg[num] = value;
   1105   }
   1106 
   1107   uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
   1108 
   1109   void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
   1110 
   1111   uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
   1112 
   1113   void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
   1114 
   1115   bool validFloatVectorRegister(int num) const {
   1116     return false;
   1117   }
   1118 
   1119   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1120   }
   1121 
   1122   __dso_hidden void jumpto() const __dead;
   1123 
   1124 private:
   1125   uint32_t reg[REGNO_OR1K_FPCSR + 1];
   1126 };
   1127 
   1128 #if __i386__
   1129 typedef Registers_x86 NativeUnwindRegisters;
   1130 #elif __x86_64__
   1131 typedef Registers_x86_64 NativeUnwindRegisters;
   1132 #elif __powerpc__
   1133 typedef Registers_ppc32 NativeUnwindRegisters;
   1134 #elif __aarch64__
   1135 typedef Registers_aarch64 NativeUnwindRegisters;
   1136 #elif __arm__
   1137 typedef Registers_arm32 NativeUnwindRegisters;
   1138 #elif __vax__
   1139 typedef Registers_vax NativeUnwindRegisters;
   1140 #elif __m68k__
   1141 typedef Registers_M68K NativeUnwindRegisters;
   1142 #elif __mips_n64 || __mips_n32
   1143 typedef Registers_MIPS64 NativeUnwindRegisters;
   1144 #elif __mips__
   1145 typedef Registers_MIPS NativeUnwindRegisters;
   1146 #elif __sh3__
   1147 typedef Registers_SH3 NativeUnwindRegisters;
   1148 #elif __sparc64__
   1149 typedef Registers_SPARC64 NativeUnwindRegisters;
   1150 #elif __sparc__
   1151 typedef Registers_SPARC NativeUnwindRegisters;
   1152 #elif __alpha__
   1153 typedef Registers_Alpha NativeUnwindRegisters;
   1154 #elif __hppa__
   1155 typedef Registers_HPPA NativeUnwindRegisters;
   1156 #elif __or1k__
   1157 typedef Registers_or1k NativeUnwindRegisters;
   1158 #endif
   1159 } // namespace _Unwind
   1160 
   1161 #endif // __REGISTERS_HPP__
   1162