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