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