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