Home | History | Annotate | Line # | Download | only in libunwind
Registers.hpp revision 1.19.12.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.19.12.1    snj #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_ELR_MODE = 33,
    248       1.17   matt   DWARF_AARCH64_V0 = 64,
    249       1.17   matt   DWARF_AARCH64_V31 = 95,
    250       1.17   matt 
    251       1.17   matt   REGNO_AARCH64_X0 = 0,
    252       1.17   matt   REGNO_AARCH64_X30 = 30,
    253       1.17   matt   REGNO_AARCH64_SP = 31,
    254       1.17   matt   REGNO_AARCH64_ELR_MODE = 32,
    255       1.17   matt   REGNO_AARCH64_V0 = 33,
    256       1.17   matt   REGNO_AARCH64_V31 = 64,
    257       1.17   matt };
    258       1.17   matt 
    259       1.17   matt class Registers_aarch64 {
    260       1.17   matt public:
    261       1.17   matt   enum {
    262       1.17   matt     LAST_RESTORE_REG = REGNO_AARCH64_V31,
    263       1.17   matt     LAST_REGISTER = REGNO_AARCH64_V31,
    264       1.17   matt     RETURN_OFFSET = 0,
    265       1.19  joerg     RETURN_MASK = 0,
    266       1.17   matt   };
    267       1.17   matt 
    268       1.17   matt   __dso_hidden Registers_aarch64();
    269       1.17   matt 
    270       1.17   matt   static int dwarf2regno(int num) {
    271       1.17   matt     if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30)
    272       1.17   matt       return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0);
    273       1.17   matt     if (num == DWARF_AARCH64_SP)
    274       1.17   matt       return REGNO_AARCH64_SP;
    275       1.17   matt     if (num == DWARF_AARCH64_ELR_MODE)
    276       1.17   matt       return REGNO_AARCH64_ELR_MODE;
    277       1.17   matt     if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31)
    278       1.17   matt       return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0);
    279       1.17   matt     return LAST_REGISTER + 1;
    280       1.17   matt   }
    281       1.17   matt 
    282       1.17   matt   bool validRegister(int num) const {
    283       1.17   matt     return num >= 0 && num <= LAST_RESTORE_REG;
    284       1.17   matt   }
    285       1.17   matt 
    286       1.17   matt   uint64_t getRegister(int num) const {
    287       1.17   matt     assert(validRegister(num));
    288       1.17   matt     return reg[num];
    289       1.17   matt   }
    290       1.17   matt 
    291       1.17   matt   void setRegister(int num, uint64_t value) {
    292       1.17   matt     assert(validRegister(num));
    293       1.17   matt     reg[num] = value;
    294       1.17   matt   }
    295       1.17   matt 
    296       1.17   matt   uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; }
    297       1.17   matt 
    298       1.17   matt   void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; }
    299       1.17   matt 
    300       1.17   matt   uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; }
    301       1.17   matt 
    302       1.17   matt   void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; }
    303       1.17   matt 
    304       1.17   matt   bool validFloatVectorRegister(int num) const {
    305       1.17   matt     return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31);
    306       1.17   matt   }
    307       1.17   matt 
    308       1.17   matt   void copyFloatVectorRegister(int num, uint64_t addr_) {
    309       1.17   matt     const void *addr = reinterpret_cast<const void *>(addr_);
    310       1.17   matt     memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, sizeof(vecreg[0]));
    311       1.17   matt   }
    312       1.17   matt 
    313       1.17   matt   __dso_hidden void jumpto() const __dead;
    314       1.17   matt 
    315       1.17   matt private:
    316       1.17   matt   struct vecreg_t {
    317       1.17   matt     uint64_t low, high;
    318       1.17   matt   };
    319       1.17   matt   uint64_t reg[REGNO_AARCH64_ELR_MODE + 1];
    320       1.17   matt   vecreg_t vecreg[32];
    321       1.17   matt };
    322       1.17   matt 
    323       1.17   matt enum {
    324        1.2   matt   DWARF_ARM32_R0 = 0,
    325        1.2   matt   DWARF_ARM32_R15 = 15,
    326        1.2   matt   DWARF_ARM32_SPSR = 128,
    327  1.19.12.1    snj   DWARF_ARM32_S0 = 64,
    328  1.19.12.1    snj   DWARF_ARM32_S31 = 91,
    329       1.16  joerg   DWARF_ARM32_D0 = 256,
    330        1.2   matt   DWARF_ARM32_D31 = 287,
    331        1.2   matt   REGNO_ARM32_R0 = 0,
    332        1.2   matt   REGNO_ARM32_SP = 13,
    333        1.2   matt   REGNO_ARM32_R15 = 15,
    334        1.2   matt   REGNO_ARM32_SPSR = 16,
    335       1.16  joerg   REGNO_ARM32_D0 = 17,
    336       1.16  joerg   REGNO_ARM32_D15 = 32,
    337       1.16  joerg   REGNO_ARM32_D31 = 48,
    338  1.19.12.1    snj   REGNO_ARM32_S0 = 49,
    339  1.19.12.1    snj   REGNO_ARM32_S31 = 70,
    340        1.2   matt };
    341        1.2   matt 
    342        1.2   matt class Registers_arm32 {
    343        1.2   matt public:
    344        1.2   matt   enum {
    345        1.3  joerg     LAST_REGISTER = REGNO_ARM32_D31,
    346       1.16  joerg     LAST_RESTORE_REG = REGNO_ARM32_D31,
    347       1.10  joerg     RETURN_OFFSET = 0,
    348       1.19  joerg     RETURN_MASK = 0,
    349        1.2   matt   };
    350        1.2   matt 
    351        1.2   matt   __dso_hidden Registers_arm32();
    352        1.2   matt 
    353        1.2   matt   static int dwarf2regno(int num) {
    354        1.2   matt     if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
    355        1.2   matt       return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
    356       1.16  joerg     if (num == DWARF_ARM32_SPSR)
    357       1.16  joerg       return REGNO_ARM32_SPSR;
    358        1.2   matt     if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
    359        1.2   matt       return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
    360  1.19.12.1    snj     if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31) {
    361  1.19.12.1    snj       return REGNO_ARM32_S0 + (num - DWARF_ARM32_S0);
    362       1.16  joerg     }
    363        1.2   matt     return LAST_REGISTER + 1;
    364        1.2   matt   }
    365        1.2   matt 
    366        1.2   matt   bool validRegister(int num) const {
    367       1.16  joerg     return num >= 0 && num <= REGNO_ARM32_SPSR;
    368        1.2   matt   }
    369        1.2   matt 
    370        1.2   matt   uint64_t getRegister(int num) const {
    371        1.2   matt     assert(validRegister(num));
    372        1.2   matt     return reg[num];
    373        1.2   matt   }
    374        1.2   matt 
    375        1.2   matt   void setRegister(int num, uint64_t value) {
    376        1.2   matt     assert(validRegister(num));
    377        1.2   matt     reg[num] = value;
    378        1.2   matt   }
    379        1.2   matt 
    380        1.2   matt   uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
    381        1.2   matt 
    382        1.2   matt   void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
    383        1.2   matt 
    384        1.2   matt   uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
    385        1.2   matt 
    386        1.2   matt   void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
    387        1.2   matt 
    388        1.2   matt   bool validFloatVectorRegister(int num) const {
    389  1.19.12.1    snj     return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31);
    390        1.2   matt   }
    391        1.2   matt 
    392        1.2   matt   void copyFloatVectorRegister(int num, uint64_t addr_) {
    393  1.19.12.1    snj     const void *addr = reinterpret_cast<const void *>(addr_);
    394  1.19.12.1    snj     if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) {
    395  1.19.12.1    snj       if ((flags & 1) == 0) {
    396  1.19.12.1    snj         lazyVFP1();
    397  1.19.12.1    snj         flags |= 1;
    398  1.19.12.1    snj       }
    399  1.19.12.1    snj       /*
    400  1.19.12.1    snj        * Emulate single precision register as half of the
    401  1.19.12.1    snj        * corresponding double register.
    402  1.19.12.1    snj        */
    403  1.19.12.1    snj       int dnum = (num - REGNO_ARM32_S0) / 2;
    404  1.19.12.1    snj       int part = (num - REGNO_ARM32_S0) % 2;
    405  1.19.12.1    snj #if _BYTE_ORDER == _BIG_ENDIAN
    406  1.19.12.1    snj       part = 1 - part;
    407  1.19.12.1    snj #endif
    408  1.19.12.1    snj       memcpy(fpreg + dnum + part * sizeof(fpreg[0]) / 2,
    409  1.19.12.1    snj         addr, sizeof(fpreg[0]) / 2);
    410  1.19.12.1    snj     }
    411       1.16  joerg     if (num <= REGNO_ARM32_D15) {
    412       1.16  joerg       if ((flags & 1) == 0) {
    413       1.16  joerg         lazyVFP1();
    414       1.16  joerg         flags |= 1;
    415       1.16  joerg       }
    416       1.16  joerg     } else {
    417       1.16  joerg       if ((flags & 2) == 0) {
    418       1.16  joerg         lazyVFP3();
    419       1.16  joerg         flags |= 2;
    420       1.16  joerg       }
    421       1.16  joerg     }
    422        1.2   matt     memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
    423        1.2   matt   }
    424        1.2   matt 
    425       1.16  joerg   __dso_hidden void lazyVFP1();
    426       1.16  joerg   __dso_hidden void lazyVFP3();
    427        1.2   matt   __dso_hidden void jumpto() const __dead;
    428        1.2   matt 
    429        1.2   matt private:
    430        1.2   matt   uint32_t reg[REGNO_ARM32_SPSR + 1];
    431       1.16  joerg   uint32_t flags;
    432        1.2   matt   uint64_t fpreg[32];
    433        1.2   matt };
    434        1.2   matt 
    435        1.5  joerg enum {
    436        1.5  joerg   DWARF_VAX_R0 = 0,
    437        1.5  joerg   DWARF_VAX_R15 = 15,
    438        1.5  joerg   DWARF_VAX_PSW = 16,
    439        1.5  joerg 
    440        1.5  joerg   REGNO_VAX_R0 = 0,
    441        1.5  joerg   REGNO_VAX_R14 = 14,
    442        1.5  joerg   REGNO_VAX_R15 = 15,
    443        1.5  joerg   REGNO_VAX_PSW = 16,
    444        1.5  joerg };
    445        1.5  joerg 
    446        1.5  joerg class Registers_vax {
    447        1.5  joerg public:
    448        1.5  joerg   enum {
    449        1.5  joerg     LAST_REGISTER = REGNO_VAX_PSW,
    450        1.5  joerg     LAST_RESTORE_REG = REGNO_VAX_PSW,
    451       1.10  joerg     RETURN_OFFSET = 0,
    452       1.19  joerg     RETURN_MASK = 0,
    453        1.5  joerg   };
    454        1.5  joerg 
    455        1.5  joerg   __dso_hidden Registers_vax();
    456        1.5  joerg 
    457        1.5  joerg   static int dwarf2regno(int num) {
    458        1.5  joerg     if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
    459        1.5  joerg       return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
    460        1.5  joerg     if (num == DWARF_VAX_PSW)
    461        1.5  joerg       return REGNO_VAX_PSW;
    462        1.5  joerg     return LAST_REGISTER + 1;
    463        1.5  joerg   }
    464        1.5  joerg 
    465        1.5  joerg   bool validRegister(int num) const {
    466        1.5  joerg     return num >= 0 && num <= LAST_RESTORE_REG;
    467        1.5  joerg   }
    468        1.5  joerg 
    469        1.5  joerg   uint64_t getRegister(int num) const {
    470        1.5  joerg     assert(validRegister(num));
    471        1.5  joerg     return reg[num];
    472        1.5  joerg   }
    473        1.5  joerg 
    474        1.5  joerg   void setRegister(int num, uint64_t value) {
    475        1.5  joerg     assert(validRegister(num));
    476        1.5  joerg     reg[num] = value;
    477        1.5  joerg   }
    478        1.5  joerg 
    479        1.5  joerg   uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
    480        1.5  joerg 
    481        1.5  joerg   void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
    482        1.5  joerg 
    483        1.5  joerg   uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
    484        1.5  joerg 
    485        1.5  joerg   void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
    486        1.5  joerg 
    487        1.5  joerg   bool validFloatVectorRegister(int num) const {
    488        1.5  joerg     return false;
    489        1.5  joerg   }
    490        1.5  joerg 
    491        1.5  joerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
    492        1.5  joerg   }
    493        1.5  joerg 
    494        1.5  joerg   __dso_hidden void jumpto() const __dead;
    495        1.5  joerg 
    496        1.5  joerg private:
    497        1.5  joerg   uint32_t reg[REGNO_VAX_PSW + 1];
    498        1.5  joerg };
    499        1.5  joerg 
    500        1.6  joerg enum {
    501        1.6  joerg   DWARF_M68K_A0 = 0,
    502        1.6  joerg   DWARF_M68K_A7 = 7,
    503        1.6  joerg   DWARF_M68K_D0 = 8,
    504        1.6  joerg   DWARF_M68K_D7 = 15,
    505        1.7  joerg   DWARF_M68K_FP0 = 16,
    506        1.7  joerg   DWARF_M68K_FP7 = 23,
    507        1.6  joerg   DWARF_M68K_PC = 24,
    508        1.6  joerg 
    509        1.6  joerg   REGNO_M68K_A0 = 0,
    510        1.6  joerg   REGNO_M68K_A7 = 7,
    511        1.6  joerg   REGNO_M68K_D0 = 8,
    512        1.6  joerg   REGNO_M68K_D7 = 15,
    513        1.6  joerg   REGNO_M68K_PC = 16,
    514        1.7  joerg   REGNO_M68K_FP0 = 17,
    515        1.7  joerg   REGNO_M68K_FP7 = 24,
    516        1.6  joerg };
    517        1.6  joerg 
    518        1.6  joerg class Registers_M68K {
    519        1.6  joerg public:
    520        1.6  joerg   enum {
    521        1.7  joerg     LAST_REGISTER = REGNO_M68K_FP7,
    522        1.7  joerg     LAST_RESTORE_REG = REGNO_M68K_FP7,
    523       1.10  joerg     RETURN_OFFSET = 0,
    524       1.19  joerg     RETURN_MASK = 0,
    525        1.6  joerg   };
    526        1.6  joerg 
    527        1.6  joerg   __dso_hidden Registers_M68K();
    528        1.6  joerg 
    529        1.6  joerg   static int dwarf2regno(int num) {
    530        1.6  joerg     if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
    531        1.6  joerg       return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
    532        1.6  joerg     if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
    533        1.6  joerg       return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
    534        1.7  joerg     if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
    535        1.7  joerg       return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
    536        1.6  joerg     if (num == DWARF_M68K_PC)
    537        1.6  joerg       return REGNO_M68K_PC;
    538        1.6  joerg     return LAST_REGISTER + 1;
    539        1.6  joerg   }
    540        1.6  joerg 
    541        1.6  joerg   bool validRegister(int num) const {
    542        1.7  joerg     return num >= 0 && num <= REGNO_M68K_PC;
    543        1.6  joerg   }
    544        1.6  joerg 
    545        1.6  joerg   uint64_t getRegister(int num) const {
    546        1.6  joerg     assert(validRegister(num));
    547        1.6  joerg     return reg[num];
    548        1.6  joerg   }
    549        1.6  joerg 
    550        1.6  joerg   void setRegister(int num, uint64_t value) {
    551        1.6  joerg     assert(validRegister(num));
    552        1.6  joerg     reg[num] = value;
    553        1.6  joerg   }
    554        1.6  joerg 
    555        1.6  joerg   uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
    556        1.6  joerg 
    557        1.6  joerg   void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
    558        1.6  joerg 
    559        1.6  joerg   uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
    560        1.6  joerg 
    561        1.6  joerg   void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
    562        1.6  joerg 
    563        1.6  joerg   bool validFloatVectorRegister(int num) const {
    564        1.7  joerg     return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
    565        1.6  joerg   }
    566        1.6  joerg 
    567        1.6  joerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
    568        1.7  joerg     assert(validFloatVectorRegister(num));
    569        1.7  joerg     const void *addr = reinterpret_cast<const void *>(addr_);
    570        1.7  joerg     memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
    571        1.6  joerg   }
    572        1.6  joerg 
    573        1.6  joerg   __dso_hidden void jumpto() const __dead;
    574        1.6  joerg 
    575        1.6  joerg private:
    576        1.7  joerg   typedef uint32_t fpreg_t[3];
    577        1.7  joerg 
    578        1.6  joerg   uint32_t reg[REGNO_M68K_PC + 1];
    579        1.7  joerg   uint32_t dummy;
    580        1.7  joerg   fpreg_t fpreg[8];
    581        1.6  joerg };
    582        1.6  joerg 
    583        1.8  joerg enum {
    584        1.8  joerg   DWARF_SH3_R0 = 0,
    585        1.8  joerg   DWARF_SH3_R15 = 15,
    586        1.8  joerg   DWARF_SH3_PC = 16,
    587        1.8  joerg   DWARF_SH3_PR = 17,
    588        1.8  joerg 
    589        1.8  joerg   REGNO_SH3_R0 = 0,
    590        1.8  joerg   REGNO_SH3_R15 = 15,
    591        1.8  joerg   REGNO_SH3_PC = 16,
    592        1.8  joerg   REGNO_SH3_PR = 17,
    593        1.8  joerg };
    594        1.8  joerg 
    595        1.8  joerg class Registers_SH3 {
    596        1.8  joerg public:
    597        1.8  joerg   enum {
    598        1.8  joerg     LAST_REGISTER = REGNO_SH3_PR,
    599        1.8  joerg     LAST_RESTORE_REG = REGNO_SH3_PR,
    600       1.10  joerg     RETURN_OFFSET = 0,
    601       1.19  joerg     RETURN_MASK = 0,
    602        1.8  joerg   };
    603        1.8  joerg 
    604        1.8  joerg   __dso_hidden Registers_SH3();
    605        1.8  joerg 
    606        1.8  joerg   static int dwarf2regno(int num) {
    607        1.8  joerg     if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
    608        1.8  joerg       return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
    609        1.8  joerg     if (num == DWARF_SH3_PC)
    610        1.8  joerg       return REGNO_SH3_PC;
    611        1.8  joerg     if (num == DWARF_SH3_PR)
    612        1.8  joerg       return REGNO_SH3_PR;
    613        1.8  joerg     return LAST_REGISTER + 1;
    614        1.8  joerg   }
    615        1.8  joerg 
    616        1.8  joerg   bool validRegister(int num) const {
    617        1.8  joerg     return num >= 0 && num <= REGNO_SH3_PR;
    618        1.8  joerg   }
    619        1.8  joerg 
    620        1.8  joerg   uint64_t getRegister(int num) const {
    621        1.8  joerg     assert(validRegister(num));
    622        1.8  joerg     return reg[num];
    623        1.8  joerg   }
    624        1.8  joerg 
    625        1.8  joerg   void setRegister(int num, uint64_t value) {
    626        1.8  joerg     assert(validRegister(num));
    627        1.8  joerg     reg[num] = value;
    628        1.8  joerg   }
    629        1.8  joerg 
    630        1.8  joerg   uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
    631        1.8  joerg 
    632        1.8  joerg   void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
    633        1.8  joerg 
    634        1.8  joerg   uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
    635        1.8  joerg 
    636        1.8  joerg   void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
    637        1.8  joerg 
    638        1.8  joerg   bool validFloatVectorRegister(int num) const { return false; }
    639        1.8  joerg 
    640        1.8  joerg   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    641        1.8  joerg 
    642        1.8  joerg   __dso_hidden void jumpto() const __dead;
    643        1.8  joerg 
    644        1.8  joerg private:
    645        1.8  joerg   uint32_t reg[REGNO_SH3_PR + 1];
    646        1.8  joerg };
    647        1.8  joerg 
    648       1.11  joerg enum {
    649       1.11  joerg   DWARF_SPARC64_R0 = 0,
    650       1.11  joerg   DWARF_SPARC64_R31 = 31,
    651       1.11  joerg   DWARF_SPARC64_PC = 32,
    652       1.11  joerg 
    653       1.11  joerg   REGNO_SPARC64_R0 = 0,
    654       1.11  joerg   REGNO_SPARC64_R14 = 14,
    655       1.11  joerg   REGNO_SPARC64_R15 = 15,
    656       1.11  joerg   REGNO_SPARC64_R31 = 31,
    657       1.11  joerg   REGNO_SPARC64_PC = 32,
    658       1.11  joerg };
    659       1.11  joerg 
    660       1.11  joerg class Registers_SPARC64 {
    661       1.11  joerg public:
    662       1.11  joerg   enum {
    663       1.11  joerg     LAST_REGISTER = REGNO_SPARC64_PC,
    664       1.11  joerg     LAST_RESTORE_REG = REGNO_SPARC64_PC,
    665       1.11  joerg     RETURN_OFFSET = 8,
    666       1.19  joerg     RETURN_MASK = 0,
    667       1.11  joerg   };
    668       1.11  joerg   typedef uint64_t reg_t;
    669       1.11  joerg 
    670       1.11  joerg   __dso_hidden Registers_SPARC64();
    671       1.11  joerg 
    672       1.11  joerg   static int dwarf2regno(int num) {
    673       1.11  joerg     if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
    674       1.11  joerg       return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
    675       1.11  joerg     if (num == DWARF_SPARC64_PC)
    676       1.11  joerg       return REGNO_SPARC64_PC;
    677       1.11  joerg     return LAST_REGISTER + 1;
    678       1.11  joerg   }
    679       1.11  joerg 
    680       1.11  joerg   bool validRegister(int num) const {
    681       1.11  joerg     return num >= 0 && num <= REGNO_SPARC64_PC;
    682       1.11  joerg   }
    683       1.11  joerg 
    684       1.11  joerg   uint64_t getRegister(int num) const {
    685       1.11  joerg     assert(validRegister(num));
    686       1.11  joerg     return reg[num];
    687       1.11  joerg   }
    688       1.11  joerg 
    689       1.11  joerg   void setRegister(int num, uint64_t value) {
    690       1.11  joerg     assert(validRegister(num));
    691       1.11  joerg     reg[num] = value;
    692       1.11  joerg   }
    693       1.11  joerg 
    694       1.11  joerg   uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
    695       1.11  joerg 
    696       1.11  joerg   void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
    697       1.11  joerg 
    698       1.11  joerg   uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
    699       1.11  joerg 
    700       1.11  joerg   void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
    701       1.11  joerg 
    702       1.11  joerg   bool validFloatVectorRegister(int num) const { return false; }
    703       1.11  joerg 
    704       1.11  joerg   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    705       1.11  joerg 
    706       1.11  joerg   __dso_hidden void jumpto() const __dead;
    707       1.11  joerg 
    708       1.11  joerg private:
    709       1.11  joerg   uint64_t reg[REGNO_SPARC64_PC + 1];
    710       1.11  joerg };
    711       1.11  joerg 
    712       1.11  joerg enum {
    713       1.11  joerg   DWARF_SPARC_R0 = 0,
    714       1.11  joerg   DWARF_SPARC_R31 = 31,
    715       1.11  joerg   DWARF_SPARC_PC = 32,
    716       1.11  joerg 
    717       1.11  joerg   REGNO_SPARC_R0 = 0,
    718       1.11  joerg   REGNO_SPARC_R14 = 14,
    719       1.11  joerg   REGNO_SPARC_R15 = 15,
    720       1.11  joerg   REGNO_SPARC_R31 = 31,
    721       1.11  joerg   REGNO_SPARC_PC = 32,
    722       1.11  joerg };
    723       1.11  joerg 
    724       1.11  joerg class Registers_SPARC {
    725       1.11  joerg public:
    726       1.11  joerg   enum {
    727       1.11  joerg     LAST_REGISTER = REGNO_SPARC_PC,
    728       1.11  joerg     LAST_RESTORE_REG = REGNO_SPARC_PC,
    729       1.11  joerg     RETURN_OFFSET = 8,
    730       1.19  joerg     RETURN_MASK = 0,
    731       1.11  joerg   };
    732       1.11  joerg   typedef uint32_t reg_t;
    733       1.11  joerg 
    734       1.11  joerg   __dso_hidden Registers_SPARC();
    735       1.11  joerg 
    736       1.11  joerg   static int dwarf2regno(int num) {
    737       1.11  joerg     if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
    738       1.11  joerg       return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
    739       1.11  joerg     if (num == DWARF_SPARC_PC)
    740       1.11  joerg       return REGNO_SPARC_PC;
    741       1.11  joerg     return LAST_REGISTER + 1;
    742       1.11  joerg   }
    743       1.11  joerg 
    744       1.11  joerg   bool validRegister(int num) const {
    745       1.11  joerg     return num >= 0 && num <= REGNO_SPARC_PC;
    746       1.11  joerg   }
    747       1.11  joerg 
    748       1.11  joerg   uint64_t getRegister(int num) const {
    749       1.11  joerg     assert(validRegister(num));
    750       1.11  joerg     return reg[num];
    751       1.11  joerg   }
    752       1.11  joerg 
    753       1.11  joerg   void setRegister(int num, uint64_t value) {
    754       1.11  joerg     assert(validRegister(num));
    755       1.11  joerg     reg[num] = value;
    756       1.11  joerg   }
    757       1.11  joerg 
    758       1.11  joerg   uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
    759       1.11  joerg 
    760       1.11  joerg   void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
    761       1.11  joerg 
    762       1.11  joerg   uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
    763       1.11  joerg 
    764       1.11  joerg   void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
    765       1.11  joerg 
    766       1.11  joerg   bool validFloatVectorRegister(int num) const { return false; }
    767       1.11  joerg 
    768       1.11  joerg   void copyFloatVectorRegister(int num, uint64_t addr_) {}
    769       1.11  joerg 
    770       1.11  joerg   __dso_hidden void jumpto() const __dead;
    771       1.11  joerg 
    772       1.11  joerg private:
    773       1.11  joerg   uint32_t reg[REGNO_SPARC_PC + 1];
    774       1.11  joerg };
    775       1.11  joerg 
    776       1.12  joerg enum {
    777       1.12  joerg   DWARF_ALPHA_R0 = 0,
    778       1.12  joerg   DWARF_ALPHA_R30 = 30,
    779       1.12  joerg   DWARF_ALPHA_F0 = 32,
    780       1.12  joerg   DWARF_ALPHA_F30 = 62,
    781       1.12  joerg 
    782       1.12  joerg   REGNO_ALPHA_R0 = 0,
    783       1.12  joerg   REGNO_ALPHA_R26 = 26,
    784       1.12  joerg   REGNO_ALPHA_R30 = 30,
    785       1.12  joerg   REGNO_ALPHA_PC = 31,
    786       1.12  joerg   REGNO_ALPHA_F0 = 32,
    787       1.12  joerg   REGNO_ALPHA_F30 = 62,
    788       1.12  joerg };
    789       1.12  joerg 
    790       1.12  joerg class Registers_Alpha {
    791       1.12  joerg public:
    792       1.12  joerg   enum {
    793       1.12  joerg     LAST_REGISTER = REGNO_ALPHA_F30,
    794       1.12  joerg     LAST_RESTORE_REG = REGNO_ALPHA_F30,
    795       1.12  joerg     RETURN_OFFSET = 0,
    796       1.19  joerg     RETURN_MASK = 0,
    797       1.12  joerg   };
    798       1.12  joerg   typedef uint32_t reg_t;
    799       1.12  joerg 
    800       1.12  joerg   __dso_hidden Registers_Alpha();
    801       1.12  joerg 
    802       1.12  joerg   static int dwarf2regno(int num) { return num; }
    803       1.12  joerg 
    804       1.12  joerg   bool validRegister(int num) const {
    805       1.12  joerg     return num >= 0 && num <= REGNO_ALPHA_PC;
    806       1.12  joerg   }
    807       1.12  joerg 
    808       1.12  joerg   uint64_t getRegister(int num) const {
    809       1.12  joerg     assert(validRegister(num));
    810       1.12  joerg     return reg[num];
    811       1.12  joerg   }
    812       1.12  joerg 
    813       1.12  joerg   void setRegister(int num, uint64_t value) {
    814       1.12  joerg     assert(validRegister(num));
    815       1.12  joerg     reg[num] = value;
    816       1.12  joerg   }
    817       1.12  joerg 
    818       1.12  joerg   uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
    819       1.12  joerg 
    820       1.12  joerg   void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
    821       1.12  joerg 
    822       1.12  joerg   uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
    823       1.12  joerg 
    824       1.12  joerg   void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
    825       1.12  joerg 
    826       1.12  joerg   bool validFloatVectorRegister(int num) const {
    827       1.12  joerg     return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
    828       1.12  joerg   }
    829       1.12  joerg 
    830       1.12  joerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
    831       1.12  joerg     assert(validFloatVectorRegister(num));
    832       1.12  joerg     const void *addr = reinterpret_cast<const void *>(addr_);
    833       1.12  joerg     memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
    834       1.12  joerg   }
    835       1.12  joerg 
    836       1.12  joerg   __dso_hidden void jumpto() const __dead;
    837       1.12  joerg 
    838       1.12  joerg private:
    839       1.12  joerg   uint64_t reg[REGNO_ALPHA_PC + 1];
    840       1.12  joerg   uint64_t fpreg[31];
    841       1.12  joerg };
    842       1.12  joerg 
    843       1.13  joerg enum {
    844       1.13  joerg   DWARF_HPPA_R1 = 1,
    845       1.13  joerg   DWARF_HPPA_R31 = 31,
    846       1.13  joerg   DWARF_HPPA_FR4L = 32,
    847       1.13  joerg   DWARF_HPPA_FR31H = 87,
    848       1.13  joerg 
    849       1.13  joerg   REGNO_HPPA_PC = 0,
    850       1.13  joerg   REGNO_HPPA_R1 = 1,
    851       1.13  joerg   REGNO_HPPA_R2 = 2,
    852       1.13  joerg   REGNO_HPPA_R30 = 30,
    853       1.13  joerg   REGNO_HPPA_R31 = 31,
    854       1.13  joerg   REGNO_HPPA_FR4L = 32,
    855       1.13  joerg   REGNO_HPPA_FR31H = 87,
    856       1.13  joerg };
    857       1.13  joerg 
    858       1.13  joerg class Registers_HPPA {
    859       1.13  joerg public:
    860       1.13  joerg   enum {
    861       1.13  joerg     LAST_REGISTER = REGNO_HPPA_FR31H,
    862       1.13  joerg     LAST_RESTORE_REG = REGNO_HPPA_FR31H,
    863       1.19  joerg     RETURN_OFFSET = 0,
    864       1.19  joerg     RETURN_MASK = 3,
    865       1.13  joerg   };
    866       1.13  joerg 
    867       1.13  joerg   __dso_hidden Registers_HPPA();
    868       1.13  joerg 
    869       1.13  joerg   static int dwarf2regno(int num) {
    870       1.13  joerg     if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
    871       1.13  joerg       return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
    872       1.13  joerg     if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
    873       1.13  joerg       return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
    874       1.13  joerg     return LAST_REGISTER + 1;
    875       1.13  joerg   }
    876       1.13  joerg 
    877       1.13  joerg   bool validRegister(int num) const {
    878       1.13  joerg     return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
    879       1.13  joerg   }
    880       1.13  joerg 
    881       1.13  joerg   uint64_t getRegister(int num) const {
    882       1.13  joerg     assert(validRegister(num));
    883       1.13  joerg     return reg[num];
    884       1.13  joerg   }
    885       1.13  joerg 
    886       1.13  joerg   void setRegister(int num, uint64_t value) {
    887       1.13  joerg     assert(validRegister(num));
    888       1.13  joerg     reg[num] = value;
    889       1.13  joerg   }
    890       1.13  joerg 
    891       1.13  joerg   uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
    892       1.13  joerg 
    893       1.13  joerg   void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
    894       1.13  joerg 
    895       1.13  joerg   uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
    896       1.13  joerg 
    897       1.13  joerg   void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
    898       1.13  joerg 
    899       1.13  joerg   bool validFloatVectorRegister(int num) const {
    900       1.13  joerg     return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
    901       1.13  joerg   }
    902       1.13  joerg 
    903       1.13  joerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
    904       1.13  joerg     assert(validFloatVectorRegister(num));
    905       1.13  joerg     const void *addr = reinterpret_cast<const void *>(addr_);
    906       1.13  joerg     memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
    907       1.13  joerg   }
    908       1.13  joerg 
    909       1.13  joerg   __dso_hidden void jumpto() const __dead;
    910       1.13  joerg 
    911       1.13  joerg private:
    912       1.13  joerg   uint32_t reg[REGNO_HPPA_R31 + 1];
    913       1.13  joerg   uint32_t fpreg[56];
    914       1.13  joerg };
    915       1.13  joerg 
    916       1.14  joerg enum {
    917       1.14  joerg   DWARF_MIPS_R1 = 0,
    918       1.14  joerg   DWARF_MIPS_R31 = 31,
    919       1.14  joerg   DWARF_MIPS_F0 = 32,
    920       1.14  joerg   DWARF_MIPS_F31 = 63,
    921       1.14  joerg 
    922       1.14  joerg   REGNO_MIPS_PC = 0,
    923       1.14  joerg   REGNO_MIPS_R1 = 0,
    924       1.14  joerg   REGNO_MIPS_R29 = 29,
    925       1.14  joerg   REGNO_MIPS_R31 = 31,
    926       1.14  joerg   REGNO_MIPS_F0 = 33,
    927       1.14  joerg   REGNO_MIPS_F31 = 64
    928       1.14  joerg };
    929       1.14  joerg 
    930       1.14  joerg class Registers_MIPS {
    931       1.14  joerg public:
    932       1.14  joerg   enum {
    933       1.14  joerg     LAST_REGISTER = REGNO_MIPS_F31,
    934       1.14  joerg     LAST_RESTORE_REG = REGNO_MIPS_F31,
    935       1.14  joerg     RETURN_OFFSET = 0,
    936       1.19  joerg     RETURN_MASK = 0,
    937       1.14  joerg   };
    938       1.14  joerg 
    939       1.14  joerg   __dso_hidden Registers_MIPS();
    940       1.14  joerg 
    941       1.14  joerg   static int dwarf2regno(int num) {
    942       1.14  joerg     if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
    943       1.14  joerg       return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
    944       1.14  joerg     if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
    945       1.14  joerg       return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
    946       1.14  joerg     return LAST_REGISTER + 1;
    947       1.14  joerg   }
    948       1.14  joerg 
    949       1.14  joerg   bool validRegister(int num) const {
    950       1.14  joerg     return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31;
    951       1.14  joerg   }
    952       1.14  joerg 
    953       1.14  joerg   uint64_t getRegister(int num) const {
    954       1.14  joerg     assert(validRegister(num));
    955       1.14  joerg     return reg[num];
    956       1.14  joerg   }
    957       1.14  joerg 
    958       1.14  joerg   void setRegister(int num, uint64_t value) {
    959       1.14  joerg     assert(validRegister(num));
    960       1.14  joerg     reg[num] = value;
    961       1.14  joerg   }
    962       1.14  joerg 
    963       1.14  joerg   uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
    964       1.14  joerg 
    965       1.14  joerg   void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
    966       1.14  joerg 
    967       1.14  joerg   uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
    968       1.14  joerg 
    969       1.14  joerg   void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
    970       1.14  joerg 
    971       1.14  joerg   bool validFloatVectorRegister(int num) const {
    972       1.14  joerg     return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31;
    973       1.14  joerg   }
    974       1.14  joerg 
    975       1.14  joerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
    976       1.14  joerg     assert(validFloatVectorRegister(num));
    977       1.14  joerg     const void *addr = reinterpret_cast<const void *>(addr_);
    978       1.14  joerg     memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
    979       1.14  joerg   }
    980       1.14  joerg 
    981       1.14  joerg   __dso_hidden void jumpto() const __dead;
    982       1.14  joerg 
    983       1.14  joerg private:
    984       1.14  joerg   uint32_t reg[REGNO_MIPS_R31 + 1];
    985       1.14  joerg   uint64_t fpreg[32];
    986       1.14  joerg };
    987       1.14  joerg 
    988       1.14  joerg enum {
    989       1.14  joerg   DWARF_MIPS64_R1 = 0,
    990       1.14  joerg   DWARF_MIPS64_R31 = 31,
    991       1.14  joerg   DWARF_MIPS64_F0 = 32,
    992       1.14  joerg   DWARF_MIPS64_F31 = 63,
    993       1.14  joerg 
    994       1.14  joerg   REGNO_MIPS64_PC = 0,
    995       1.14  joerg   REGNO_MIPS64_R1 = 0,
    996       1.14  joerg   REGNO_MIPS64_R29 = 29,
    997       1.14  joerg   REGNO_MIPS64_R31 = 31,
    998       1.14  joerg   REGNO_MIPS64_F0 = 33,
    999       1.14  joerg   REGNO_MIPS64_F31 = 64
   1000       1.14  joerg };
   1001       1.14  joerg 
   1002       1.14  joerg class Registers_MIPS64 {
   1003       1.14  joerg public:
   1004       1.14  joerg   enum {
   1005       1.14  joerg     LAST_REGISTER = REGNO_MIPS64_F31,
   1006       1.14  joerg     LAST_RESTORE_REG = REGNO_MIPS64_F31,
   1007       1.14  joerg     RETURN_OFFSET = 0,
   1008       1.19  joerg     RETURN_MASK = 0,
   1009       1.14  joerg   };
   1010       1.14  joerg 
   1011       1.14  joerg   __dso_hidden Registers_MIPS64();
   1012       1.14  joerg 
   1013       1.14  joerg   static int dwarf2regno(int num) {
   1014       1.14  joerg     if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
   1015       1.14  joerg       return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
   1016       1.14  joerg     if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
   1017       1.14  joerg       return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
   1018       1.14  joerg     return LAST_REGISTER + 1;
   1019       1.14  joerg   }
   1020       1.14  joerg 
   1021       1.14  joerg   bool validRegister(int num) const {
   1022       1.14  joerg     return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31;
   1023       1.14  joerg   }
   1024       1.14  joerg 
   1025       1.14  joerg   uint64_t getRegister(int num) const {
   1026       1.14  joerg     assert(validRegister(num));
   1027       1.14  joerg     return reg[num];
   1028       1.14  joerg   }
   1029       1.14  joerg 
   1030       1.14  joerg   void setRegister(int num, uint64_t value) {
   1031       1.14  joerg     assert(validRegister(num));
   1032       1.14  joerg     reg[num] = value;
   1033       1.14  joerg   }
   1034       1.14  joerg 
   1035       1.14  joerg   uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
   1036       1.14  joerg 
   1037       1.14  joerg   void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
   1038       1.14  joerg 
   1039       1.14  joerg   uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
   1040       1.14  joerg 
   1041       1.14  joerg   void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
   1042       1.14  joerg 
   1043       1.14  joerg   bool validFloatVectorRegister(int num) const {
   1044       1.14  joerg     return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31;
   1045       1.14  joerg   }
   1046       1.14  joerg 
   1047       1.14  joerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1048       1.14  joerg     assert(validFloatVectorRegister(num));
   1049       1.14  joerg     const void *addr = reinterpret_cast<const void *>(addr_);
   1050       1.14  joerg     memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
   1051       1.14  joerg   }
   1052       1.14  joerg 
   1053       1.14  joerg   __dso_hidden void jumpto() const __dead;
   1054       1.14  joerg 
   1055       1.14  joerg private:
   1056       1.14  joerg   uint64_t reg[REGNO_MIPS64_R31 + 1];
   1057       1.14  joerg   uint64_t fpreg[32];
   1058       1.14  joerg };
   1059       1.14  joerg 
   1060       1.18   matt enum {
   1061       1.18   matt   DWARF_OR1K_R0 = 0,
   1062       1.18   matt   DWARF_OR1K_SP = 1,
   1063       1.18   matt   DWARF_OR1K_LR = 9,
   1064       1.18   matt   DWARF_OR1K_R31 = 31,
   1065       1.18   matt   DWARF_OR1K_FPCSR = 32,
   1066       1.18   matt 
   1067       1.18   matt   REGNO_OR1K_R0 = 0,
   1068       1.18   matt   REGNO_OR1K_SP = 1,
   1069       1.18   matt   REGNO_OR1K_LR = 9,
   1070       1.18   matt   REGNO_OR1K_R31 = 31,
   1071       1.18   matt   REGNO_OR1K_FPCSR = 32,
   1072       1.18   matt };
   1073       1.18   matt 
   1074       1.18   matt class Registers_or1k {
   1075       1.18   matt public:
   1076       1.18   matt   enum {
   1077       1.18   matt     LAST_REGISTER = REGNO_OR1K_FPCSR,
   1078       1.18   matt     LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
   1079       1.18   matt     RETURN_OFFSET = 0,
   1080       1.19  joerg     RETURN_MASK = 0,
   1081       1.18   matt   };
   1082       1.18   matt 
   1083       1.18   matt   __dso_hidden Registers_or1k();
   1084       1.18   matt 
   1085       1.18   matt   static int dwarf2regno(int num) {
   1086       1.18   matt     if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
   1087       1.18   matt       return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
   1088       1.18   matt     if (num == DWARF_OR1K_FPCSR)
   1089       1.18   matt       return REGNO_OR1K_FPCSR;
   1090       1.18   matt     return LAST_REGISTER + 1;
   1091       1.18   matt   }
   1092       1.18   matt 
   1093       1.18   matt   bool validRegister(int num) const {
   1094       1.18   matt     return num >= 0 && num <= LAST_RESTORE_REG;
   1095       1.18   matt   }
   1096       1.18   matt 
   1097       1.18   matt   uint64_t getRegister(int num) const {
   1098       1.18   matt     assert(validRegister(num));
   1099       1.18   matt     return reg[num];
   1100       1.18   matt   }
   1101       1.18   matt 
   1102       1.18   matt   void setRegister(int num, uint64_t value) {
   1103       1.18   matt     assert(validRegister(num));
   1104       1.18   matt     reg[num] = value;
   1105       1.18   matt   }
   1106       1.18   matt 
   1107       1.18   matt   uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
   1108       1.18   matt 
   1109       1.18   matt   void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
   1110       1.18   matt 
   1111       1.18   matt   uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
   1112       1.18   matt 
   1113       1.18   matt   void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
   1114       1.18   matt 
   1115       1.18   matt   bool validFloatVectorRegister(int num) const {
   1116       1.18   matt     return false;
   1117       1.18   matt   }
   1118       1.18   matt 
   1119       1.18   matt   void copyFloatVectorRegister(int num, uint64_t addr_) {
   1120       1.18   matt   }
   1121       1.18   matt 
   1122       1.18   matt   __dso_hidden void jumpto() const __dead;
   1123       1.18   matt 
   1124       1.18   matt private:
   1125       1.18   matt   uint32_t reg[REGNO_OR1K_FPCSR + 1];
   1126       1.18   matt };
   1127       1.18   matt 
   1128        1.9  joerg #if __i386__
   1129        1.9  joerg typedef Registers_x86 NativeUnwindRegisters;
   1130        1.9  joerg #elif __x86_64__
   1131        1.9  joerg typedef Registers_x86_64 NativeUnwindRegisters;
   1132        1.9  joerg #elif __powerpc__
   1133        1.9  joerg typedef Registers_ppc32 NativeUnwindRegisters;
   1134       1.17   matt #elif __aarch64__
   1135       1.17   matt typedef Registers_aarch64 NativeUnwindRegisters;
   1136       1.16  joerg #elif __arm__
   1137        1.9  joerg typedef Registers_arm32 NativeUnwindRegisters;
   1138        1.9  joerg #elif __vax__
   1139        1.9  joerg typedef Registers_vax NativeUnwindRegisters;
   1140        1.9  joerg #elif __m68k__
   1141        1.9  joerg typedef Registers_M68K NativeUnwindRegisters;
   1142       1.14  joerg #elif __mips_n64 || __mips_n32
   1143       1.14  joerg typedef Registers_MIPS64 NativeUnwindRegisters;
   1144       1.14  joerg #elif __mips__
   1145       1.14  joerg typedef Registers_MIPS NativeUnwindRegisters;
   1146        1.9  joerg #elif __sh3__
   1147        1.9  joerg typedef Registers_SH3 NativeUnwindRegisters;
   1148       1.11  joerg #elif __sparc64__
   1149       1.11  joerg typedef Registers_SPARC64 NativeUnwindRegisters;
   1150       1.11  joerg #elif __sparc__
   1151       1.11  joerg typedef Registers_SPARC NativeUnwindRegisters;
   1152       1.12  joerg #elif __alpha__
   1153       1.12  joerg typedef Registers_Alpha NativeUnwindRegisters;
   1154       1.13  joerg #elif __hppa__
   1155       1.13  joerg typedef Registers_HPPA NativeUnwindRegisters;
   1156       1.18   matt #elif __or1k__
   1157       1.18   matt typedef Registers_or1k NativeUnwindRegisters;
   1158        1.9  joerg #endif
   1159        1.1  joerg } // namespace _Unwind
   1160        1.1  joerg 
   1161        1.1  joerg #endif // __REGISTERS_HPP__
   1162