Home | History | Annotate | Line # | Download | only in libunwind
Registers.hpp revision 1.19.2.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.2.1  skrll #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.2.1  skrll   DWARF_ARM32_S0 = 64,
    328  1.19.2.1  skrll   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.2.1  skrll   REGNO_ARM32_S0 = 49,
    339  1.19.2.1  skrll   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.2.1  skrll     if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31) {
    361  1.19.2.1  skrll       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.2.1  skrll     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.2.1  skrll     const void *addr = reinterpret_cast<const void *>(addr_);
    394  1.19.2.1  skrll     if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) {
    395  1.19.2.1  skrll       if ((flags & 1) == 0) {
    396  1.19.2.1  skrll         lazyVFP1();
    397  1.19.2.1  skrll         flags |= 1;
    398  1.19.2.1  skrll       }
    399  1.19.2.1  skrll       /*
    400  1.19.2.1  skrll        * Emulate single precision register as half of the
    401  1.19.2.1  skrll        * corresponding double register.
    402  1.19.2.1  skrll        */
    403  1.19.2.1  skrll       int dnum = (num - REGNO_ARM32_S0) / 2;
    404  1.19.2.1  skrll       int part = (num - REGNO_ARM32_S0) % 2;
    405  1.19.2.1  skrll #if _BYTE_ORDER == _BIG_ENDIAN
    406  1.19.2.1  skrll       part = 1 - part;
    407  1.19.2.1  skrll #endif
    408  1.19.2.1  skrll       memcpy(fpreg + dnum + part * sizeof(fpreg[0]) / 2,
    409  1.19.2.1  skrll         addr, sizeof(fpreg[0]) / 2);
    410  1.19.2.1  skrll     }
    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