Home | History | Annotate | Download | only in src
      1 //===----------------------------- Registers.hpp --------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //
      9 //  Models register sets for supported processors.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #ifndef __REGISTERS_HPP__
     14 #define __REGISTERS_HPP__
     15 
     16 #include <stdint.h>
     17 #include <string.h>
     18 
     19 #include "libunwind.h"
     20 #include "config.h"
     21 
     22 namespace libunwind {
     23 
     24 // For emulating 128-bit registers
     25 struct v128 { uint32_t vec[4]; };
     26 
     27 
     28 #if defined(_LIBUNWIND_TARGET_I386)
     29 /// Registers_x86 holds the register state of a thread in a 32-bit intel
     30 /// process.
     31 class _LIBUNWIND_HIDDEN Registers_x86 {
     32 public:
     33   Registers_x86();
     34   Registers_x86(const void *registers);
     35 
     36   bool        validRegister(int num) const;
     37   uint32_t    getRegister(int num) const;
     38   void        setRegister(int num, uint32_t value);
     39   bool        validFloatRegister(int) const { return false; }
     40   double      getFloatRegister(int num) const;
     41   void        setFloatRegister(int num, double value);
     42   bool        validVectorRegister(int) const { return false; }
     43   v128        getVectorRegister(int num) const;
     44   void        setVectorRegister(int num, v128 value);
     45   const char *getRegisterName(int num);
     46   void        jumpto();
     47   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
     48 
     49   uint32_t  getSP() const          { return _registers.__esp; }
     50   void      setSP(uint32_t value)  { _registers.__esp = value; }
     51   uint32_t  getIP() const          { return _registers.__eip; }
     52   void      setIP(uint32_t value)  { _registers.__eip = value; }
     53   uint32_t  getEBP() const         { return _registers.__ebp; }
     54   void      setEBP(uint32_t value) { _registers.__ebp = value; }
     55   uint32_t  getEBX() const         { return _registers.__ebx; }
     56   void      setEBX(uint32_t value) { _registers.__ebx = value; }
     57   uint32_t  getECX() const         { return _registers.__ecx; }
     58   void      setECX(uint32_t value) { _registers.__ecx = value; }
     59   uint32_t  getEDX() const         { return _registers.__edx; }
     60   void      setEDX(uint32_t value) { _registers.__edx = value; }
     61   uint32_t  getESI() const         { return _registers.__esi; }
     62   void      setESI(uint32_t value) { _registers.__esi = value; }
     63   uint32_t  getEDI() const         { return _registers.__edi; }
     64   void      setEDI(uint32_t value) { _registers.__edi = value; }
     65 
     66 private:
     67   struct GPRs {
     68     unsigned int __eax;
     69     unsigned int __ebx;
     70     unsigned int __ecx;
     71     unsigned int __edx;
     72     unsigned int __edi;
     73     unsigned int __esi;
     74     unsigned int __ebp;
     75     unsigned int __esp;
     76     unsigned int __ss;
     77     unsigned int __eflags;
     78     unsigned int __eip;
     79     unsigned int __cs;
     80     unsigned int __ds;
     81     unsigned int __es;
     82     unsigned int __fs;
     83     unsigned int __gs;
     84   };
     85 
     86   GPRs _registers;
     87 };
     88 
     89 inline Registers_x86::Registers_x86(const void *registers) {
     90   static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
     91                 "x86 registers do not fit into unw_context_t");
     92   memcpy(&_registers, registers, sizeof(_registers));
     93 }
     94 
     95 inline Registers_x86::Registers_x86() {
     96   memset(&_registers, 0, sizeof(_registers));
     97 }
     98 
     99 inline bool Registers_x86::validRegister(int regNum) const {
    100   if (regNum == UNW_REG_IP)
    101     return true;
    102   if (regNum == UNW_REG_SP)
    103     return true;
    104   if (regNum < 0)
    105     return false;
    106   if (regNum > 7)
    107     return false;
    108   return true;
    109 }
    110 
    111 inline uint32_t Registers_x86::getRegister(int regNum) const {
    112   switch (regNum) {
    113   case UNW_REG_IP:
    114     return _registers.__eip;
    115   case UNW_REG_SP:
    116     return _registers.__esp;
    117   case UNW_X86_EAX:
    118     return _registers.__eax;
    119   case UNW_X86_ECX:
    120     return _registers.__ecx;
    121   case UNW_X86_EDX:
    122     return _registers.__edx;
    123   case UNW_X86_EBX:
    124     return _registers.__ebx;
    125 #if !defined(__APPLE__)
    126   case UNW_X86_ESP:
    127 #else
    128   case UNW_X86_EBP:
    129 #endif
    130     return _registers.__ebp;
    131 #if !defined(__APPLE__)
    132   case UNW_X86_EBP:
    133 #else
    134   case UNW_X86_ESP:
    135 #endif
    136     return _registers.__esp;
    137   case UNW_X86_ESI:
    138     return _registers.__esi;
    139   case UNW_X86_EDI:
    140     return _registers.__edi;
    141   }
    142   _LIBUNWIND_ABORT("unsupported x86 register");
    143 }
    144 
    145 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
    146   switch (regNum) {
    147   case UNW_REG_IP:
    148     _registers.__eip = value;
    149     return;
    150   case UNW_REG_SP:
    151     _registers.__esp = value;
    152     return;
    153   case UNW_X86_EAX:
    154     _registers.__eax = value;
    155     return;
    156   case UNW_X86_ECX:
    157     _registers.__ecx = value;
    158     return;
    159   case UNW_X86_EDX:
    160     _registers.__edx = value;
    161     return;
    162   case UNW_X86_EBX:
    163     _registers.__ebx = value;
    164     return;
    165 #if !defined(__APPLE__)
    166   case UNW_X86_ESP:
    167 #else
    168   case UNW_X86_EBP:
    169 #endif
    170     _registers.__ebp = value;
    171     return;
    172 #if !defined(__APPLE__)
    173   case UNW_X86_EBP:
    174 #else
    175   case UNW_X86_ESP:
    176 #endif
    177     _registers.__esp = value;
    178     return;
    179   case UNW_X86_ESI:
    180     _registers.__esi = value;
    181     return;
    182   case UNW_X86_EDI:
    183     _registers.__edi = value;
    184     return;
    185   }
    186   _LIBUNWIND_ABORT("unsupported x86 register");
    187 }
    188 
    189 inline const char *Registers_x86::getRegisterName(int regNum) {
    190   switch (regNum) {
    191   case UNW_REG_IP:
    192     return "ip";
    193   case UNW_REG_SP:
    194     return "esp";
    195   case UNW_X86_EAX:
    196     return "eax";
    197   case UNW_X86_ECX:
    198     return "ecx";
    199   case UNW_X86_EDX:
    200     return "edx";
    201   case UNW_X86_EBX:
    202     return "ebx";
    203   case UNW_X86_EBP:
    204     return "ebp";
    205   case UNW_X86_ESP:
    206     return "esp";
    207   case UNW_X86_ESI:
    208     return "esi";
    209   case UNW_X86_EDI:
    210     return "edi";
    211   default:
    212     return "unknown register";
    213   }
    214 }
    215 
    216 inline double Registers_x86::getFloatRegister(int) const {
    217   _LIBUNWIND_ABORT("no x86 float registers");
    218 }
    219 
    220 inline void Registers_x86::setFloatRegister(int, double) {
    221   _LIBUNWIND_ABORT("no x86 float registers");
    222 }
    223 
    224 inline v128 Registers_x86::getVectorRegister(int) const {
    225   _LIBUNWIND_ABORT("no x86 vector registers");
    226 }
    227 
    228 inline void Registers_x86::setVectorRegister(int, v128) {
    229   _LIBUNWIND_ABORT("no x86 vector registers");
    230 }
    231 #endif // _LIBUNWIND_TARGET_I386
    232 
    233 
    234 #if defined(_LIBUNWIND_TARGET_X86_64)
    235 /// Registers_x86_64  holds the register state of a thread in a 64-bit intel
    236 /// process.
    237 class _LIBUNWIND_HIDDEN Registers_x86_64 {
    238 public:
    239   Registers_x86_64();
    240   Registers_x86_64(const void *registers);
    241 
    242   bool        validRegister(int num) const;
    243   uint64_t    getRegister(int num) const;
    244   void        setRegister(int num, uint64_t value);
    245   bool        validFloatRegister(int) const { return false; }
    246   double      getFloatRegister(int num) const;
    247   void        setFloatRegister(int num, double value);
    248   bool        validVectorRegister(int) const;
    249   v128        getVectorRegister(int num) const;
    250   void        setVectorRegister(int num, v128 value);
    251   const char *getRegisterName(int num);
    252   void        jumpto();
    253   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
    254 
    255   uint64_t  getSP() const          { return _registers.__rsp; }
    256   void      setSP(uint64_t value)  { _registers.__rsp = value; }
    257   uint64_t  getIP() const          { return _registers.__rip; }
    258   void      setIP(uint64_t value)  { _registers.__rip = value; }
    259   uint64_t  getRBP() const         { return _registers.__rbp; }
    260   void      setRBP(uint64_t value) { _registers.__rbp = value; }
    261   uint64_t  getRBX() const         { return _registers.__rbx; }
    262   void      setRBX(uint64_t value) { _registers.__rbx = value; }
    263   uint64_t  getR12() const         { return _registers.__r12; }
    264   void      setR12(uint64_t value) { _registers.__r12 = value; }
    265   uint64_t  getR13() const         { return _registers.__r13; }
    266   void      setR13(uint64_t value) { _registers.__r13 = value; }
    267   uint64_t  getR14() const         { return _registers.__r14; }
    268   void      setR14(uint64_t value) { _registers.__r14 = value; }
    269   uint64_t  getR15() const         { return _registers.__r15; }
    270   void      setR15(uint64_t value) { _registers.__r15 = value; }
    271 
    272 private:
    273   struct GPRs {
    274     uint64_t __rax;
    275     uint64_t __rbx;
    276     uint64_t __rcx;
    277     uint64_t __rdx;
    278     uint64_t __rdi;
    279     uint64_t __rsi;
    280     uint64_t __rbp;
    281     uint64_t __rsp;
    282     uint64_t __r8;
    283     uint64_t __r9;
    284     uint64_t __r10;
    285     uint64_t __r11;
    286     uint64_t __r12;
    287     uint64_t __r13;
    288     uint64_t __r14;
    289     uint64_t __r15;
    290     uint64_t __rip;
    291     uint64_t __rflags;
    292     uint64_t __cs;
    293     uint64_t __fs;
    294     uint64_t __gs;
    295 #if defined(_WIN64)
    296     uint64_t __padding; // 16-byte align
    297 #endif
    298   };
    299   GPRs _registers;
    300 #if defined(_WIN64)
    301   v128 _xmm[16];
    302 #endif
    303 };
    304 
    305 inline Registers_x86_64::Registers_x86_64(const void *registers) {
    306   static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
    307                 "x86_64 registers do not fit into unw_context_t");
    308   memcpy(&_registers, registers, sizeof(_registers));
    309 }
    310 
    311 inline Registers_x86_64::Registers_x86_64() {
    312   memset(&_registers, 0, sizeof(_registers));
    313 }
    314 
    315 inline bool Registers_x86_64::validRegister(int regNum) const {
    316   if (regNum == UNW_REG_IP)
    317     return true;
    318   if (regNum == UNW_REG_SP)
    319     return true;
    320   if (regNum < 0)
    321     return false;
    322   if (regNum > 15)
    323     return false;
    324   return true;
    325 }
    326 
    327 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
    328   switch (regNum) {
    329   case UNW_REG_IP:
    330     return _registers.__rip;
    331   case UNW_REG_SP:
    332     return _registers.__rsp;
    333   case UNW_X86_64_RAX:
    334     return _registers.__rax;
    335   case UNW_X86_64_RDX:
    336     return _registers.__rdx;
    337   case UNW_X86_64_RCX:
    338     return _registers.__rcx;
    339   case UNW_X86_64_RBX:
    340     return _registers.__rbx;
    341   case UNW_X86_64_RSI:
    342     return _registers.__rsi;
    343   case UNW_X86_64_RDI:
    344     return _registers.__rdi;
    345   case UNW_X86_64_RBP:
    346     return _registers.__rbp;
    347   case UNW_X86_64_RSP:
    348     return _registers.__rsp;
    349   case UNW_X86_64_R8:
    350     return _registers.__r8;
    351   case UNW_X86_64_R9:
    352     return _registers.__r9;
    353   case UNW_X86_64_R10:
    354     return _registers.__r10;
    355   case UNW_X86_64_R11:
    356     return _registers.__r11;
    357   case UNW_X86_64_R12:
    358     return _registers.__r12;
    359   case UNW_X86_64_R13:
    360     return _registers.__r13;
    361   case UNW_X86_64_R14:
    362     return _registers.__r14;
    363   case UNW_X86_64_R15:
    364     return _registers.__r15;
    365   }
    366   _LIBUNWIND_ABORT("unsupported x86_64 register");
    367 }
    368 
    369 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
    370   switch (regNum) {
    371   case UNW_REG_IP:
    372     _registers.__rip = value;
    373     return;
    374   case UNW_REG_SP:
    375     _registers.__rsp = value;
    376     return;
    377   case UNW_X86_64_RAX:
    378     _registers.__rax = value;
    379     return;
    380   case UNW_X86_64_RDX:
    381     _registers.__rdx = value;
    382     return;
    383   case UNW_X86_64_RCX:
    384     _registers.__rcx = value;
    385     return;
    386   case UNW_X86_64_RBX:
    387     _registers.__rbx = value;
    388     return;
    389   case UNW_X86_64_RSI:
    390     _registers.__rsi = value;
    391     return;
    392   case UNW_X86_64_RDI:
    393     _registers.__rdi = value;
    394     return;
    395   case UNW_X86_64_RBP:
    396     _registers.__rbp = value;
    397     return;
    398   case UNW_X86_64_RSP:
    399     _registers.__rsp = value;
    400     return;
    401   case UNW_X86_64_R8:
    402     _registers.__r8 = value;
    403     return;
    404   case UNW_X86_64_R9:
    405     _registers.__r9 = value;
    406     return;
    407   case UNW_X86_64_R10:
    408     _registers.__r10 = value;
    409     return;
    410   case UNW_X86_64_R11:
    411     _registers.__r11 = value;
    412     return;
    413   case UNW_X86_64_R12:
    414     _registers.__r12 = value;
    415     return;
    416   case UNW_X86_64_R13:
    417     _registers.__r13 = value;
    418     return;
    419   case UNW_X86_64_R14:
    420     _registers.__r14 = value;
    421     return;
    422   case UNW_X86_64_R15:
    423     _registers.__r15 = value;
    424     return;
    425   }
    426   _LIBUNWIND_ABORT("unsupported x86_64 register");
    427 }
    428 
    429 inline const char *Registers_x86_64::getRegisterName(int regNum) {
    430   switch (regNum) {
    431   case UNW_REG_IP:
    432     return "rip";
    433   case UNW_REG_SP:
    434     return "rsp";
    435   case UNW_X86_64_RAX:
    436     return "rax";
    437   case UNW_X86_64_RDX:
    438     return "rdx";
    439   case UNW_X86_64_RCX:
    440     return "rcx";
    441   case UNW_X86_64_RBX:
    442     return "rbx";
    443   case UNW_X86_64_RSI:
    444     return "rsi";
    445   case UNW_X86_64_RDI:
    446     return "rdi";
    447   case UNW_X86_64_RBP:
    448     return "rbp";
    449   case UNW_X86_64_RSP:
    450     return "rsp";
    451   case UNW_X86_64_R8:
    452     return "r8";
    453   case UNW_X86_64_R9:
    454     return "r9";
    455   case UNW_X86_64_R10:
    456     return "r10";
    457   case UNW_X86_64_R11:
    458     return "r11";
    459   case UNW_X86_64_R12:
    460     return "r12";
    461   case UNW_X86_64_R13:
    462     return "r13";
    463   case UNW_X86_64_R14:
    464     return "r14";
    465   case UNW_X86_64_R15:
    466     return "r15";
    467   case UNW_X86_64_XMM0:
    468     return "xmm0";
    469   case UNW_X86_64_XMM1:
    470     return "xmm1";
    471   case UNW_X86_64_XMM2:
    472     return "xmm2";
    473   case UNW_X86_64_XMM3:
    474     return "xmm3";
    475   case UNW_X86_64_XMM4:
    476     return "xmm4";
    477   case UNW_X86_64_XMM5:
    478     return "xmm5";
    479   case UNW_X86_64_XMM6:
    480     return "xmm6";
    481   case UNW_X86_64_XMM7:
    482     return "xmm7";
    483   case UNW_X86_64_XMM8:
    484     return "xmm8";
    485   case UNW_X86_64_XMM9:
    486     return "xmm9";
    487   case UNW_X86_64_XMM10:
    488     return "xmm10";
    489   case UNW_X86_64_XMM11:
    490     return "xmm11";
    491   case UNW_X86_64_XMM12:
    492     return "xmm12";
    493   case UNW_X86_64_XMM13:
    494     return "xmm13";
    495   case UNW_X86_64_XMM14:
    496     return "xmm14";
    497   case UNW_X86_64_XMM15:
    498     return "xmm15";
    499   default:
    500     return "unknown register";
    501   }
    502 }
    503 
    504 inline double Registers_x86_64::getFloatRegister(int) const {
    505   _LIBUNWIND_ABORT("no x86_64 float registers");
    506 }
    507 
    508 inline void Registers_x86_64::setFloatRegister(int, double) {
    509   _LIBUNWIND_ABORT("no x86_64 float registers");
    510 }
    511 
    512 inline bool Registers_x86_64::validVectorRegister(int regNum) const {
    513 #if defined(_WIN64)
    514   if (regNum < UNW_X86_64_XMM0)
    515     return false;
    516   if (regNum > UNW_X86_64_XMM15)
    517     return false;
    518   return true;
    519 #else
    520   return false;
    521 #endif
    522 }
    523 
    524 inline v128 Registers_x86_64::getVectorRegister(int regNum) const {
    525 #if defined(_WIN64)
    526   assert(validVectorRegister(regNum));
    527   return _xmm[regNum - UNW_X86_64_XMM0];
    528 #else
    529   _LIBUNWIND_ABORT("no x86_64 vector registers");
    530 #endif
    531 }
    532 
    533 inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {
    534 #if defined(_WIN64)
    535   assert(validVectorRegister(regNum));
    536   _xmm[regNum - UNW_X86_64_XMM0] = value;
    537 #else
    538   _LIBUNWIND_ABORT("no x86_64 vector registers");
    539 #endif
    540 }
    541 #endif // _LIBUNWIND_TARGET_X86_64
    542 
    543 
    544 #if defined(_LIBUNWIND_TARGET_PPC)
    545 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
    546 /// process.
    547 class _LIBUNWIND_HIDDEN Registers_ppc {
    548 public:
    549   Registers_ppc();
    550   Registers_ppc(const void *registers);
    551 
    552   bool        validRegister(int num) const;
    553   uint32_t    getRegister(int num) const;
    554   void        setRegister(int num, uint32_t value);
    555   bool        validFloatRegister(int num) const;
    556   double      getFloatRegister(int num) const;
    557   void        setFloatRegister(int num, double value);
    558   bool        validVectorRegister(int num) const;
    559   v128        getVectorRegister(int num) const;
    560   void        setVectorRegister(int num, v128 value);
    561   const char *getRegisterName(int num);
    562   void        jumpto();
    563   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; }
    564 
    565   uint64_t  getSP() const         { return _registers.__r1; }
    566   void      setSP(uint32_t value) { _registers.__r1 = value; }
    567   uint64_t  getIP() const         { return _registers.__srr0; }
    568   void      setIP(uint32_t value) { _registers.__srr0 = value; }
    569 
    570 private:
    571   struct ppc_thread_state_t {
    572     unsigned int __srr0; /* Instruction address register (PC) */
    573     unsigned int __srr1; /* Machine state register (supervisor) */
    574     unsigned int __r0;
    575     unsigned int __r1;
    576     unsigned int __r2;
    577     unsigned int __r3;
    578     unsigned int __r4;
    579     unsigned int __r5;
    580     unsigned int __r6;
    581     unsigned int __r7;
    582     unsigned int __r8;
    583     unsigned int __r9;
    584     unsigned int __r10;
    585     unsigned int __r11;
    586     unsigned int __r12;
    587     unsigned int __r13;
    588     unsigned int __r14;
    589     unsigned int __r15;
    590     unsigned int __r16;
    591     unsigned int __r17;
    592     unsigned int __r18;
    593     unsigned int __r19;
    594     unsigned int __r20;
    595     unsigned int __r21;
    596     unsigned int __r22;
    597     unsigned int __r23;
    598     unsigned int __r24;
    599     unsigned int __r25;
    600     unsigned int __r26;
    601     unsigned int __r27;
    602     unsigned int __r28;
    603     unsigned int __r29;
    604     unsigned int __r30;
    605     unsigned int __r31;
    606     unsigned int __cr;     /* Condition register */
    607     unsigned int __xer;    /* User's integer exception register */
    608     unsigned int __lr;     /* Link register */
    609     unsigned int __ctr;    /* Count register */
    610     unsigned int __mq;     /* MQ register (601 only) */
    611     unsigned int __vrsave; /* Vector Save Register */
    612   };
    613 
    614   struct ppc_float_state_t {
    615     double __fpregs[32];
    616 
    617     unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
    618     unsigned int __fpscr;     /* floating point status register */
    619   };
    620 
    621   ppc_thread_state_t _registers;
    622   ppc_float_state_t  _floatRegisters;
    623   v128               _vectorRegisters[32]; // offset 424
    624 };
    625 
    626 inline Registers_ppc::Registers_ppc(const void *registers) {
    627   static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
    628                 "ppc registers do not fit into unw_context_t");
    629   memcpy(&_registers, static_cast<const uint8_t *>(registers),
    630          sizeof(_registers));
    631   static_assert(sizeof(ppc_thread_state_t) == 160,
    632                 "expected float register offset to be 160");
    633   memcpy(&_floatRegisters,
    634          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
    635          sizeof(_floatRegisters));
    636   static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
    637                 "expected vector register offset to be 424 bytes");
    638   memcpy(_vectorRegisters,
    639          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
    640              sizeof(ppc_float_state_t),
    641          sizeof(_vectorRegisters));
    642 }
    643 
    644 inline Registers_ppc::Registers_ppc() {
    645   memset(&_registers, 0, sizeof(_registers));
    646   memset(&_floatRegisters, 0, sizeof(_floatRegisters));
    647   memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
    648 }
    649 
    650 inline bool Registers_ppc::validRegister(int regNum) const {
    651   if (regNum == UNW_REG_IP)
    652     return true;
    653   if (regNum == UNW_REG_SP)
    654     return true;
    655   if (regNum == UNW_PPC_VRSAVE)
    656     return true;
    657   if (regNum < 0)
    658     return false;
    659   if (regNum <= UNW_PPC_R31)
    660     return true;
    661   if (regNum == UNW_PPC_MQ)
    662     return true;
    663   if (regNum == UNW_PPC_LR)
    664     return true;
    665   if (regNum == UNW_PPC_CTR)
    666     return true;
    667   if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
    668     return true;
    669   return false;
    670 }
    671 
    672 inline uint32_t Registers_ppc::getRegister(int regNum) const {
    673   switch (regNum) {
    674   case UNW_REG_IP:
    675     return _registers.__srr0;
    676   case UNW_REG_SP:
    677     return _registers.__r1;
    678   case UNW_PPC_R0:
    679     return _registers.__r0;
    680   case UNW_PPC_R1:
    681     return _registers.__r1;
    682   case UNW_PPC_R2:
    683     return _registers.__r2;
    684   case UNW_PPC_R3:
    685     return _registers.__r3;
    686   case UNW_PPC_R4:
    687     return _registers.__r4;
    688   case UNW_PPC_R5:
    689     return _registers.__r5;
    690   case UNW_PPC_R6:
    691     return _registers.__r6;
    692   case UNW_PPC_R7:
    693     return _registers.__r7;
    694   case UNW_PPC_R8:
    695     return _registers.__r8;
    696   case UNW_PPC_R9:
    697     return _registers.__r9;
    698   case UNW_PPC_R10:
    699     return _registers.__r10;
    700   case UNW_PPC_R11:
    701     return _registers.__r11;
    702   case UNW_PPC_R12:
    703     return _registers.__r12;
    704   case UNW_PPC_R13:
    705     return _registers.__r13;
    706   case UNW_PPC_R14:
    707     return _registers.__r14;
    708   case UNW_PPC_R15:
    709     return _registers.__r15;
    710   case UNW_PPC_R16:
    711     return _registers.__r16;
    712   case UNW_PPC_R17:
    713     return _registers.__r17;
    714   case UNW_PPC_R18:
    715     return _registers.__r18;
    716   case UNW_PPC_R19:
    717     return _registers.__r19;
    718   case UNW_PPC_R20:
    719     return _registers.__r20;
    720   case UNW_PPC_R21:
    721     return _registers.__r21;
    722   case UNW_PPC_R22:
    723     return _registers.__r22;
    724   case UNW_PPC_R23:
    725     return _registers.__r23;
    726   case UNW_PPC_R24:
    727     return _registers.__r24;
    728   case UNW_PPC_R25:
    729     return _registers.__r25;
    730   case UNW_PPC_R26:
    731     return _registers.__r26;
    732   case UNW_PPC_R27:
    733     return _registers.__r27;
    734   case UNW_PPC_R28:
    735     return _registers.__r28;
    736   case UNW_PPC_R29:
    737     return _registers.__r29;
    738   case UNW_PPC_R30:
    739     return _registers.__r30;
    740   case UNW_PPC_R31:
    741     return _registers.__r31;
    742   case UNW_PPC_LR:
    743     return _registers.__lr;
    744   case UNW_PPC_CR0:
    745     return (_registers.__cr & 0xF0000000);
    746   case UNW_PPC_CR1:
    747     return (_registers.__cr & 0x0F000000);
    748   case UNW_PPC_CR2:
    749     return (_registers.__cr & 0x00F00000);
    750   case UNW_PPC_CR3:
    751     return (_registers.__cr & 0x000F0000);
    752   case UNW_PPC_CR4:
    753     return (_registers.__cr & 0x0000F000);
    754   case UNW_PPC_CR5:
    755     return (_registers.__cr & 0x00000F00);
    756   case UNW_PPC_CR6:
    757     return (_registers.__cr & 0x000000F0);
    758   case UNW_PPC_CR7:
    759     return (_registers.__cr & 0x0000000F);
    760   case UNW_PPC_VRSAVE:
    761     return _registers.__vrsave;
    762   }
    763   _LIBUNWIND_ABORT("unsupported ppc register");
    764 }
    765 
    766 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
    767   //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
    768   switch (regNum) {
    769   case UNW_REG_IP:
    770     _registers.__srr0 = value;
    771     return;
    772   case UNW_REG_SP:
    773     _registers.__r1 = value;
    774     return;
    775   case UNW_PPC_R0:
    776     _registers.__r0 = value;
    777     return;
    778   case UNW_PPC_R1:
    779     _registers.__r1 = value;
    780     return;
    781   case UNW_PPC_R2:
    782     _registers.__r2 = value;
    783     return;
    784   case UNW_PPC_R3:
    785     _registers.__r3 = value;
    786     return;
    787   case UNW_PPC_R4:
    788     _registers.__r4 = value;
    789     return;
    790   case UNW_PPC_R5:
    791     _registers.__r5 = value;
    792     return;
    793   case UNW_PPC_R6:
    794     _registers.__r6 = value;
    795     return;
    796   case UNW_PPC_R7:
    797     _registers.__r7 = value;
    798     return;
    799   case UNW_PPC_R8:
    800     _registers.__r8 = value;
    801     return;
    802   case UNW_PPC_R9:
    803     _registers.__r9 = value;
    804     return;
    805   case UNW_PPC_R10:
    806     _registers.__r10 = value;
    807     return;
    808   case UNW_PPC_R11:
    809     _registers.__r11 = value;
    810     return;
    811   case UNW_PPC_R12:
    812     _registers.__r12 = value;
    813     return;
    814   case UNW_PPC_R13:
    815     _registers.__r13 = value;
    816     return;
    817   case UNW_PPC_R14:
    818     _registers.__r14 = value;
    819     return;
    820   case UNW_PPC_R15:
    821     _registers.__r15 = value;
    822     return;
    823   case UNW_PPC_R16:
    824     _registers.__r16 = value;
    825     return;
    826   case UNW_PPC_R17:
    827     _registers.__r17 = value;
    828     return;
    829   case UNW_PPC_R18:
    830     _registers.__r18 = value;
    831     return;
    832   case UNW_PPC_R19:
    833     _registers.__r19 = value;
    834     return;
    835   case UNW_PPC_R20:
    836     _registers.__r20 = value;
    837     return;
    838   case UNW_PPC_R21:
    839     _registers.__r21 = value;
    840     return;
    841   case UNW_PPC_R22:
    842     _registers.__r22 = value;
    843     return;
    844   case UNW_PPC_R23:
    845     _registers.__r23 = value;
    846     return;
    847   case UNW_PPC_R24:
    848     _registers.__r24 = value;
    849     return;
    850   case UNW_PPC_R25:
    851     _registers.__r25 = value;
    852     return;
    853   case UNW_PPC_R26:
    854     _registers.__r26 = value;
    855     return;
    856   case UNW_PPC_R27:
    857     _registers.__r27 = value;
    858     return;
    859   case UNW_PPC_R28:
    860     _registers.__r28 = value;
    861     return;
    862   case UNW_PPC_R29:
    863     _registers.__r29 = value;
    864     return;
    865   case UNW_PPC_R30:
    866     _registers.__r30 = value;
    867     return;
    868   case UNW_PPC_R31:
    869     _registers.__r31 = value;
    870     return;
    871   case UNW_PPC_MQ:
    872     _registers.__mq = value;
    873     return;
    874   case UNW_PPC_LR:
    875     _registers.__lr = value;
    876     return;
    877   case UNW_PPC_CTR:
    878     _registers.__ctr = value;
    879     return;
    880   case UNW_PPC_CR0:
    881     _registers.__cr &= 0x0FFFFFFF;
    882     _registers.__cr |= (value & 0xF0000000);
    883     return;
    884   case UNW_PPC_CR1:
    885     _registers.__cr &= 0xF0FFFFFF;
    886     _registers.__cr |= (value & 0x0F000000);
    887     return;
    888   case UNW_PPC_CR2:
    889     _registers.__cr &= 0xFF0FFFFF;
    890     _registers.__cr |= (value & 0x00F00000);
    891     return;
    892   case UNW_PPC_CR3:
    893     _registers.__cr &= 0xFFF0FFFF;
    894     _registers.__cr |= (value & 0x000F0000);
    895     return;
    896   case UNW_PPC_CR4:
    897     _registers.__cr &= 0xFFFF0FFF;
    898     _registers.__cr |= (value & 0x0000F000);
    899     return;
    900   case UNW_PPC_CR5:
    901     _registers.__cr &= 0xFFFFF0FF;
    902     _registers.__cr |= (value & 0x00000F00);
    903     return;
    904   case UNW_PPC_CR6:
    905     _registers.__cr &= 0xFFFFFF0F;
    906     _registers.__cr |= (value & 0x000000F0);
    907     return;
    908   case UNW_PPC_CR7:
    909     _registers.__cr &= 0xFFFFFFF0;
    910     _registers.__cr |= (value & 0x0000000F);
    911     return;
    912   case UNW_PPC_VRSAVE:
    913     _registers.__vrsave = value;
    914     return;
    915     // not saved
    916     return;
    917   case UNW_PPC_XER:
    918     _registers.__xer = value;
    919     return;
    920   case UNW_PPC_AP:
    921   case UNW_PPC_VSCR:
    922   case UNW_PPC_SPEFSCR:
    923     // not saved
    924     return;
    925   }
    926   _LIBUNWIND_ABORT("unsupported ppc register");
    927 }
    928 
    929 inline bool Registers_ppc::validFloatRegister(int regNum) const {
    930   if (regNum < UNW_PPC_F0)
    931     return false;
    932   if (regNum > UNW_PPC_F31)
    933     return false;
    934   return true;
    935 }
    936 
    937 inline double Registers_ppc::getFloatRegister(int regNum) const {
    938   assert(validFloatRegister(regNum));
    939   return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
    940 }
    941 
    942 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
    943   assert(validFloatRegister(regNum));
    944   _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
    945 }
    946 
    947 inline bool Registers_ppc::validVectorRegister(int regNum) const {
    948   if (regNum < UNW_PPC_V0)
    949     return false;
    950   if (regNum > UNW_PPC_V31)
    951     return false;
    952   return true;
    953 }
    954 
    955 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
    956   assert(validVectorRegister(regNum));
    957   v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
    958   return result;
    959 }
    960 
    961 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
    962   assert(validVectorRegister(regNum));
    963   _vectorRegisters[regNum - UNW_PPC_V0] = value;
    964 }
    965 
    966 inline const char *Registers_ppc::getRegisterName(int regNum) {
    967   switch (regNum) {
    968   case UNW_REG_IP:
    969     return "ip";
    970   case UNW_REG_SP:
    971     return "sp";
    972   case UNW_PPC_R0:
    973     return "r0";
    974   case UNW_PPC_R1:
    975     return "r1";
    976   case UNW_PPC_R2:
    977     return "r2";
    978   case UNW_PPC_R3:
    979     return "r3";
    980   case UNW_PPC_R4:
    981     return "r4";
    982   case UNW_PPC_R5:
    983     return "r5";
    984   case UNW_PPC_R6:
    985     return "r6";
    986   case UNW_PPC_R7:
    987     return "r7";
    988   case UNW_PPC_R8:
    989     return "r8";
    990   case UNW_PPC_R9:
    991     return "r9";
    992   case UNW_PPC_R10:
    993     return "r10";
    994   case UNW_PPC_R11:
    995     return "r11";
    996   case UNW_PPC_R12:
    997     return "r12";
    998   case UNW_PPC_R13:
    999     return "r13";
   1000   case UNW_PPC_R14:
   1001     return "r14";
   1002   case UNW_PPC_R15:
   1003     return "r15";
   1004   case UNW_PPC_R16:
   1005     return "r16";
   1006   case UNW_PPC_R17:
   1007     return "r17";
   1008   case UNW_PPC_R18:
   1009     return "r18";
   1010   case UNW_PPC_R19:
   1011     return "r19";
   1012   case UNW_PPC_R20:
   1013     return "r20";
   1014   case UNW_PPC_R21:
   1015     return "r21";
   1016   case UNW_PPC_R22:
   1017     return "r22";
   1018   case UNW_PPC_R23:
   1019     return "r23";
   1020   case UNW_PPC_R24:
   1021     return "r24";
   1022   case UNW_PPC_R25:
   1023     return "r25";
   1024   case UNW_PPC_R26:
   1025     return "r26";
   1026   case UNW_PPC_R27:
   1027     return "r27";
   1028   case UNW_PPC_R28:
   1029     return "r28";
   1030   case UNW_PPC_R29:
   1031     return "r29";
   1032   case UNW_PPC_R30:
   1033     return "r30";
   1034   case UNW_PPC_R31:
   1035     return "r31";
   1036   case UNW_PPC_F0:
   1037     return "fp0";
   1038   case UNW_PPC_F1:
   1039     return "fp1";
   1040   case UNW_PPC_F2:
   1041     return "fp2";
   1042   case UNW_PPC_F3:
   1043     return "fp3";
   1044   case UNW_PPC_F4:
   1045     return "fp4";
   1046   case UNW_PPC_F5:
   1047     return "fp5";
   1048   case UNW_PPC_F6:
   1049     return "fp6";
   1050   case UNW_PPC_F7:
   1051     return "fp7";
   1052   case UNW_PPC_F8:
   1053     return "fp8";
   1054   case UNW_PPC_F9:
   1055     return "fp9";
   1056   case UNW_PPC_F10:
   1057     return "fp10";
   1058   case UNW_PPC_F11:
   1059     return "fp11";
   1060   case UNW_PPC_F12:
   1061     return "fp12";
   1062   case UNW_PPC_F13:
   1063     return "fp13";
   1064   case UNW_PPC_F14:
   1065     return "fp14";
   1066   case UNW_PPC_F15:
   1067     return "fp15";
   1068   case UNW_PPC_F16:
   1069     return "fp16";
   1070   case UNW_PPC_F17:
   1071     return "fp17";
   1072   case UNW_PPC_F18:
   1073     return "fp18";
   1074   case UNW_PPC_F19:
   1075     return "fp19";
   1076   case UNW_PPC_F20:
   1077     return "fp20";
   1078   case UNW_PPC_F21:
   1079     return "fp21";
   1080   case UNW_PPC_F22:
   1081     return "fp22";
   1082   case UNW_PPC_F23:
   1083     return "fp23";
   1084   case UNW_PPC_F24:
   1085     return "fp24";
   1086   case UNW_PPC_F25:
   1087     return "fp25";
   1088   case UNW_PPC_F26:
   1089     return "fp26";
   1090   case UNW_PPC_F27:
   1091     return "fp27";
   1092   case UNW_PPC_F28:
   1093     return "fp28";
   1094   case UNW_PPC_F29:
   1095     return "fp29";
   1096   case UNW_PPC_F30:
   1097     return "fp30";
   1098   case UNW_PPC_F31:
   1099     return "fp31";
   1100   case UNW_PPC_LR:
   1101     return "lr";
   1102   default:
   1103     return "unknown register";
   1104   }
   1105 
   1106 }
   1107 #endif // _LIBUNWIND_TARGET_PPC
   1108 
   1109 
   1110 #if defined(_LIBUNWIND_TARGET_AARCH64)
   1111 /// Registers_arm64  holds the register state of a thread in a 64-bit arm
   1112 /// process.
   1113 class _LIBUNWIND_HIDDEN Registers_arm64 {
   1114 public:
   1115   Registers_arm64();
   1116   Registers_arm64(const void *registers);
   1117 
   1118   bool        validRegister(int num) const;
   1119   uint64_t    getRegister(int num) const;
   1120   void        setRegister(int num, uint64_t value);
   1121   bool        validFloatRegister(int num) const;
   1122   double      getFloatRegister(int num) const;
   1123   void        setFloatRegister(int num, double value);
   1124   bool        validVectorRegister(int num) const;
   1125   v128        getVectorRegister(int num) const;
   1126   void        setVectorRegister(int num, v128 value);
   1127   const char *getRegisterName(int num);
   1128   void        jumpto();
   1129   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
   1130 
   1131   uint64_t  getSP() const         { return _registers.__sp; }
   1132   void      setSP(uint64_t value) { _registers.__sp = value; }
   1133   uint64_t  getIP() const         { return _registers.__pc; }
   1134   void      setIP(uint64_t value) { _registers.__pc = value; }
   1135   uint64_t  getFP() const         { return _registers.__fp; }
   1136   void      setFP(uint64_t value) { _registers.__fp = value; }
   1137 
   1138 private:
   1139   struct GPRs {
   1140     uint64_t __x[29]; // x0-x28
   1141     uint64_t __fp;    // Frame pointer x29
   1142     uint64_t __lr;    // Link register x30
   1143     uint64_t __sp;    // Stack pointer x31
   1144     uint64_t __pc;    // Program counter
   1145     uint64_t padding; // 16-byte align
   1146   };
   1147 
   1148   GPRs    _registers;
   1149   double  _vectorHalfRegisters[32];
   1150   // Currently only the lower double in 128-bit vectore registers
   1151   // is perserved during unwinding.  We could define new register
   1152   // numbers (> 96) which mean whole vector registers, then this
   1153   // struct would need to change to contain whole vector registers.
   1154 };
   1155 
   1156 inline Registers_arm64::Registers_arm64(const void *registers) {
   1157   static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
   1158                 "arm64 registers do not fit into unw_context_t");
   1159   memcpy(&_registers, registers, sizeof(_registers));
   1160   static_assert(sizeof(GPRs) == 0x110,
   1161                 "expected VFP registers to be at offset 272");
   1162   memcpy(_vectorHalfRegisters,
   1163          static_cast<const uint8_t *>(registers) + sizeof(GPRs),
   1164          sizeof(_vectorHalfRegisters));
   1165 }
   1166 
   1167 inline Registers_arm64::Registers_arm64() {
   1168   memset(&_registers, 0, sizeof(_registers));
   1169   memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
   1170 }
   1171 
   1172 inline bool Registers_arm64::validRegister(int regNum) const {
   1173   if (regNum == UNW_REG_IP)
   1174     return true;
   1175   if (regNum == UNW_REG_SP)
   1176     return true;
   1177   if (regNum < 0)
   1178     return false;
   1179   if (regNum > 95)
   1180     return false;
   1181   if ((regNum > 31) && (regNum < 64))
   1182     return false;
   1183   return true;
   1184 }
   1185 
   1186 inline uint64_t Registers_arm64::getRegister(int regNum) const {
   1187   if (regNum == UNW_REG_IP)
   1188     return _registers.__pc;
   1189   if (regNum == UNW_REG_SP)
   1190     return _registers.__sp;
   1191   if ((regNum >= 0) && (regNum < 32))
   1192     return _registers.__x[regNum];
   1193   _LIBUNWIND_ABORT("unsupported arm64 register");
   1194 }
   1195 
   1196 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
   1197   if (regNum == UNW_REG_IP)
   1198     _registers.__pc = value;
   1199   else if (regNum == UNW_REG_SP)
   1200     _registers.__sp = value;
   1201   else if ((regNum >= 0) && (regNum < 32))
   1202     _registers.__x[regNum] = value;
   1203   else
   1204     _LIBUNWIND_ABORT("unsupported arm64 register");
   1205 }
   1206 
   1207 inline const char *Registers_arm64::getRegisterName(int regNum) {
   1208   switch (regNum) {
   1209   case UNW_REG_IP:
   1210     return "pc";
   1211   case UNW_REG_SP:
   1212     return "sp";
   1213   case UNW_ARM64_X0:
   1214     return "x0";
   1215   case UNW_ARM64_X1:
   1216     return "x1";
   1217   case UNW_ARM64_X2:
   1218     return "x2";
   1219   case UNW_ARM64_X3:
   1220     return "x3";
   1221   case UNW_ARM64_X4:
   1222     return "x4";
   1223   case UNW_ARM64_X5:
   1224     return "x5";
   1225   case UNW_ARM64_X6:
   1226     return "x6";
   1227   case UNW_ARM64_X7:
   1228     return "x7";
   1229   case UNW_ARM64_X8:
   1230     return "x8";
   1231   case UNW_ARM64_X9:
   1232     return "x9";
   1233   case UNW_ARM64_X10:
   1234     return "x10";
   1235   case UNW_ARM64_X11:
   1236     return "x11";
   1237   case UNW_ARM64_X12:
   1238     return "x12";
   1239   case UNW_ARM64_X13:
   1240     return "x13";
   1241   case UNW_ARM64_X14:
   1242     return "x14";
   1243   case UNW_ARM64_X15:
   1244     return "x15";
   1245   case UNW_ARM64_X16:
   1246     return "x16";
   1247   case UNW_ARM64_X17:
   1248     return "x17";
   1249   case UNW_ARM64_X18:
   1250     return "x18";
   1251   case UNW_ARM64_X19:
   1252     return "x19";
   1253   case UNW_ARM64_X20:
   1254     return "x20";
   1255   case UNW_ARM64_X21:
   1256     return "x21";
   1257   case UNW_ARM64_X22:
   1258     return "x22";
   1259   case UNW_ARM64_X23:
   1260     return "x23";
   1261   case UNW_ARM64_X24:
   1262     return "x24";
   1263   case UNW_ARM64_X25:
   1264     return "x25";
   1265   case UNW_ARM64_X26:
   1266     return "x26";
   1267   case UNW_ARM64_X27:
   1268     return "x27";
   1269   case UNW_ARM64_X28:
   1270     return "x28";
   1271   case UNW_ARM64_X29:
   1272     return "fp";
   1273   case UNW_ARM64_X30:
   1274     return "lr";
   1275   case UNW_ARM64_X31:
   1276     return "sp";
   1277   case UNW_ARM64_D0:
   1278     return "d0";
   1279   case UNW_ARM64_D1:
   1280     return "d1";
   1281   case UNW_ARM64_D2:
   1282     return "d2";
   1283   case UNW_ARM64_D3:
   1284     return "d3";
   1285   case UNW_ARM64_D4:
   1286     return "d4";
   1287   case UNW_ARM64_D5:
   1288     return "d5";
   1289   case UNW_ARM64_D6:
   1290     return "d6";
   1291   case UNW_ARM64_D7:
   1292     return "d7";
   1293   case UNW_ARM64_D8:
   1294     return "d8";
   1295   case UNW_ARM64_D9:
   1296     return "d9";
   1297   case UNW_ARM64_D10:
   1298     return "d10";
   1299   case UNW_ARM64_D11:
   1300     return "d11";
   1301   case UNW_ARM64_D12:
   1302     return "d12";
   1303   case UNW_ARM64_D13:
   1304     return "d13";
   1305   case UNW_ARM64_D14:
   1306     return "d14";
   1307   case UNW_ARM64_D15:
   1308     return "d15";
   1309   case UNW_ARM64_D16:
   1310     return "d16";
   1311   case UNW_ARM64_D17:
   1312     return "d17";
   1313   case UNW_ARM64_D18:
   1314     return "d18";
   1315   case UNW_ARM64_D19:
   1316     return "d19";
   1317   case UNW_ARM64_D20:
   1318     return "d20";
   1319   case UNW_ARM64_D21:
   1320     return "d21";
   1321   case UNW_ARM64_D22:
   1322     return "d22";
   1323   case UNW_ARM64_D23:
   1324     return "d23";
   1325   case UNW_ARM64_D24:
   1326     return "d24";
   1327   case UNW_ARM64_D25:
   1328     return "d25";
   1329   case UNW_ARM64_D26:
   1330     return "d26";
   1331   case UNW_ARM64_D27:
   1332     return "d27";
   1333   case UNW_ARM64_D28:
   1334     return "d28";
   1335   case UNW_ARM64_D29:
   1336     return "d29";
   1337   case UNW_ARM64_D30:
   1338     return "d30";
   1339   case UNW_ARM64_D31:
   1340     return "d31";
   1341   default:
   1342     return "unknown register";
   1343   }
   1344 }
   1345 
   1346 inline bool Registers_arm64::validFloatRegister(int regNum) const {
   1347   if (regNum < UNW_ARM64_D0)
   1348     return false;
   1349   if (regNum > UNW_ARM64_D31)
   1350     return false;
   1351   return true;
   1352 }
   1353 
   1354 inline double Registers_arm64::getFloatRegister(int regNum) const {
   1355   assert(validFloatRegister(regNum));
   1356   return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
   1357 }
   1358 
   1359 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
   1360   assert(validFloatRegister(regNum));
   1361   _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
   1362 }
   1363 
   1364 inline bool Registers_arm64::validVectorRegister(int) const {
   1365   return false;
   1366 }
   1367 
   1368 inline v128 Registers_arm64::getVectorRegister(int) const {
   1369   _LIBUNWIND_ABORT("no arm64 vector register support yet");
   1370 }
   1371 
   1372 inline void Registers_arm64::setVectorRegister(int, v128) {
   1373   _LIBUNWIND_ABORT("no arm64 vector register support yet");
   1374 }
   1375 #endif // _LIBUNWIND_TARGET_AARCH64
   1376 
   1377 #if defined(_LIBUNWIND_TARGET_ARM)
   1378 /// Registers_arm holds the register state of a thread in a 32-bit arm
   1379 /// process.
   1380 ///
   1381 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
   1382 /// this uses more memory than required.
   1383 class _LIBUNWIND_HIDDEN Registers_arm {
   1384 public:
   1385   Registers_arm();
   1386   Registers_arm(const void *registers);
   1387 
   1388   bool        validRegister(int num) const;
   1389   uint32_t    getRegister(int num) const;
   1390   void        setRegister(int num, uint32_t value);
   1391   bool        validFloatRegister(int num) const;
   1392   unw_fpreg_t getFloatRegister(int num);
   1393   void        setFloatRegister(int num, unw_fpreg_t value);
   1394   bool        validVectorRegister(int num) const;
   1395   v128        getVectorRegister(int num) const;
   1396   void        setVectorRegister(int num, v128 value);
   1397   const char *getRegisterName(int num);
   1398   void        jumpto() {
   1399     restoreSavedFloatRegisters();
   1400     restoreCoreAndJumpTo();
   1401   }
   1402   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; }
   1403 
   1404   uint32_t  getSP() const         { return _registers.__sp; }
   1405   void      setSP(uint32_t value) { _registers.__sp = value; }
   1406   uint32_t  getIP() const         { return _registers.__pc; }
   1407   void      setIP(uint32_t value) { _registers.__pc = value; }
   1408 
   1409   void saveVFPAsX() {
   1410     assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
   1411     _use_X_for_vfp_save = true;
   1412   }
   1413 
   1414   void restoreSavedFloatRegisters() {
   1415     if (_saved_vfp_d0_d15) {
   1416       if (_use_X_for_vfp_save)
   1417         restoreVFPWithFLDMX(_vfp_d0_d15_pad);
   1418       else
   1419         restoreVFPWithFLDMD(_vfp_d0_d15_pad);
   1420     }
   1421     if (_saved_vfp_d16_d31)
   1422       restoreVFPv3(_vfp_d16_d31);
   1423 #if defined(__ARM_WMMX)
   1424     if (_saved_iwmmx)
   1425       restoreiWMMX(_iwmmx);
   1426     if (_saved_iwmmx_control)
   1427       restoreiWMMXControl(_iwmmx_control);
   1428 #endif
   1429   }
   1430 
   1431 private:
   1432   struct GPRs {
   1433     uint32_t __r[13]; // r0-r12
   1434     uint32_t __sp;    // Stack pointer r13
   1435     uint32_t __lr;    // Link register r14
   1436     uint32_t __pc;    // Program counter r15
   1437   };
   1438 
   1439   static void saveVFPWithFSTMD(unw_fpreg_t*);
   1440   static void saveVFPWithFSTMX(unw_fpreg_t*);
   1441   static void saveVFPv3(unw_fpreg_t*);
   1442   static void restoreVFPWithFLDMD(unw_fpreg_t*);
   1443   static void restoreVFPWithFLDMX(unw_fpreg_t*);
   1444   static void restoreVFPv3(unw_fpreg_t*);
   1445 #if defined(__ARM_WMMX)
   1446   static void saveiWMMX(unw_fpreg_t*);
   1447   static void saveiWMMXControl(uint32_t*);
   1448   static void restoreiWMMX(unw_fpreg_t*);
   1449   static void restoreiWMMXControl(uint32_t*);
   1450 #endif
   1451   void restoreCoreAndJumpTo();
   1452 
   1453   // ARM registers
   1454   GPRs _registers;
   1455 
   1456   // We save floating point registers lazily because we can't know ahead of
   1457   // time which ones are used. See EHABI #4.7.
   1458 
   1459   // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
   1460   //
   1461   // See EHABI #7.5 that explains how matching instruction sequences for load
   1462   // and store need to be used to correctly restore the exact register bits.
   1463   bool _use_X_for_vfp_save;
   1464   // Whether VFP D0-D15 are saved.
   1465   bool _saved_vfp_d0_d15;
   1466   // Whether VFPv3 D16-D31 are saved.
   1467   bool _saved_vfp_d16_d31;
   1468   // VFP registers D0-D15, + padding if saved using FSTMX
   1469   unw_fpreg_t _vfp_d0_d15_pad[17];
   1470   // VFPv3 registers D16-D31, always saved using FSTMD
   1471   unw_fpreg_t _vfp_d16_d31[16];
   1472 #if defined(__ARM_WMMX)
   1473   // Whether iWMMX data registers are saved.
   1474   bool _saved_iwmmx;
   1475   // Whether iWMMX control registers are saved.
   1476   mutable bool _saved_iwmmx_control;
   1477   // iWMMX registers
   1478   unw_fpreg_t _iwmmx[16];
   1479   // iWMMX control registers
   1480   mutable uint32_t _iwmmx_control[4];
   1481 #endif
   1482 };
   1483 
   1484 inline Registers_arm::Registers_arm(const void *registers)
   1485   : _use_X_for_vfp_save(false),
   1486     _saved_vfp_d0_d15(false),
   1487     _saved_vfp_d16_d31(false) {
   1488   static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
   1489                 "arm registers do not fit into unw_context_t");
   1490   // See unw_getcontext() note about data.
   1491   memcpy(&_registers, registers, sizeof(_registers));
   1492   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
   1493   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
   1494 #if defined(__ARM_WMMX)
   1495   _saved_iwmmx = false;
   1496   _saved_iwmmx_control = false;
   1497   memset(&_iwmmx, 0, sizeof(_iwmmx));
   1498   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
   1499 #endif
   1500 }
   1501 
   1502 inline Registers_arm::Registers_arm()
   1503   : _use_X_for_vfp_save(false),
   1504     _saved_vfp_d0_d15(false),
   1505     _saved_vfp_d16_d31(false) {
   1506   memset(&_registers, 0, sizeof(_registers));
   1507   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
   1508   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
   1509 #if defined(__ARM_WMMX)
   1510   _saved_iwmmx = false;
   1511   _saved_iwmmx_control = false;
   1512   memset(&_iwmmx, 0, sizeof(_iwmmx));
   1513   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
   1514 #endif
   1515 }
   1516 
   1517 inline bool Registers_arm::validRegister(int regNum) const {
   1518   // Returns true for all non-VFP registers supported by the EHABI
   1519   // virtual register set (VRS).
   1520   if (regNum == UNW_REG_IP)
   1521     return true;
   1522 
   1523   if (regNum == UNW_REG_SP)
   1524     return true;
   1525 
   1526   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
   1527     return true;
   1528 
   1529 #if defined(__ARM_WMMX)
   1530   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
   1531     return true;
   1532 #endif
   1533 
   1534   return false;
   1535 }
   1536 
   1537 inline uint32_t Registers_arm::getRegister(int regNum) const {
   1538   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
   1539     return _registers.__sp;
   1540 
   1541   if (regNum == UNW_ARM_LR)
   1542     return _registers.__lr;
   1543 
   1544   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
   1545     return _registers.__pc;
   1546 
   1547   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
   1548     return _registers.__r[regNum];
   1549 
   1550 #if defined(__ARM_WMMX)
   1551   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
   1552     if (!_saved_iwmmx_control) {
   1553       _saved_iwmmx_control = true;
   1554       saveiWMMXControl(_iwmmx_control);
   1555     }
   1556     return _iwmmx_control[regNum - UNW_ARM_WC0];
   1557   }
   1558 #endif
   1559 
   1560   _LIBUNWIND_ABORT("unsupported arm register");
   1561 }
   1562 
   1563 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
   1564   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
   1565     _registers.__sp = value;
   1566     return;
   1567   }
   1568 
   1569   if (regNum == UNW_ARM_LR) {
   1570     _registers.__lr = value;
   1571     return;
   1572   }
   1573 
   1574   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
   1575     _registers.__pc = value;
   1576     return;
   1577   }
   1578 
   1579   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
   1580     _registers.__r[regNum] = value;
   1581     return;
   1582   }
   1583 
   1584 #if defined(__ARM_WMMX)
   1585   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
   1586     if (!_saved_iwmmx_control) {
   1587       _saved_iwmmx_control = true;
   1588       saveiWMMXControl(_iwmmx_control);
   1589     }
   1590     _iwmmx_control[regNum - UNW_ARM_WC0] = value;
   1591     return;
   1592   }
   1593 #endif
   1594 
   1595   _LIBUNWIND_ABORT("unsupported arm register");
   1596 }
   1597 
   1598 inline const char *Registers_arm::getRegisterName(int regNum) {
   1599   switch (regNum) {
   1600   case UNW_REG_IP:
   1601   case UNW_ARM_IP: // UNW_ARM_R15 is alias
   1602     return "pc";
   1603   case UNW_ARM_LR: // UNW_ARM_R14 is alias
   1604     return "lr";
   1605   case UNW_REG_SP:
   1606   case UNW_ARM_SP: // UNW_ARM_R13 is alias
   1607     return "sp";
   1608   case UNW_ARM_R0:
   1609     return "r0";
   1610   case UNW_ARM_R1:
   1611     return "r1";
   1612   case UNW_ARM_R2:
   1613     return "r2";
   1614   case UNW_ARM_R3:
   1615     return "r3";
   1616   case UNW_ARM_R4:
   1617     return "r4";
   1618   case UNW_ARM_R5:
   1619     return "r5";
   1620   case UNW_ARM_R6:
   1621     return "r6";
   1622   case UNW_ARM_R7:
   1623     return "r7";
   1624   case UNW_ARM_R8:
   1625     return "r8";
   1626   case UNW_ARM_R9:
   1627     return "r9";
   1628   case UNW_ARM_R10:
   1629     return "r10";
   1630   case UNW_ARM_R11:
   1631     return "r11";
   1632   case UNW_ARM_R12:
   1633     return "r12";
   1634   case UNW_ARM_S0:
   1635     return "s0";
   1636   case UNW_ARM_S1:
   1637     return "s1";
   1638   case UNW_ARM_S2:
   1639     return "s2";
   1640   case UNW_ARM_S3:
   1641     return "s3";
   1642   case UNW_ARM_S4:
   1643     return "s4";
   1644   case UNW_ARM_S5:
   1645     return "s5";
   1646   case UNW_ARM_S6:
   1647     return "s6";
   1648   case UNW_ARM_S7:
   1649     return "s7";
   1650   case UNW_ARM_S8:
   1651     return "s8";
   1652   case UNW_ARM_S9:
   1653     return "s9";
   1654   case UNW_ARM_S10:
   1655     return "s10";
   1656   case UNW_ARM_S11:
   1657     return "s11";
   1658   case UNW_ARM_S12:
   1659     return "s12";
   1660   case UNW_ARM_S13:
   1661     return "s13";
   1662   case UNW_ARM_S14:
   1663     return "s14";
   1664   case UNW_ARM_S15:
   1665     return "s15";
   1666   case UNW_ARM_S16:
   1667     return "s16";
   1668   case UNW_ARM_S17:
   1669     return "s17";
   1670   case UNW_ARM_S18:
   1671     return "s18";
   1672   case UNW_ARM_S19:
   1673     return "s19";
   1674   case UNW_ARM_S20:
   1675     return "s20";
   1676   case UNW_ARM_S21:
   1677     return "s21";
   1678   case UNW_ARM_S22:
   1679     return "s22";
   1680   case UNW_ARM_S23:
   1681     return "s23";
   1682   case UNW_ARM_S24:
   1683     return "s24";
   1684   case UNW_ARM_S25:
   1685     return "s25";
   1686   case UNW_ARM_S26:
   1687     return "s26";
   1688   case UNW_ARM_S27:
   1689     return "s27";
   1690   case UNW_ARM_S28:
   1691     return "s28";
   1692   case UNW_ARM_S29:
   1693     return "s29";
   1694   case UNW_ARM_S30:
   1695     return "s30";
   1696   case UNW_ARM_S31:
   1697     return "s31";
   1698   case UNW_ARM_D0:
   1699     return "d0";
   1700   case UNW_ARM_D1:
   1701     return "d1";
   1702   case UNW_ARM_D2:
   1703     return "d2";
   1704   case UNW_ARM_D3:
   1705     return "d3";
   1706   case UNW_ARM_D4:
   1707     return "d4";
   1708   case UNW_ARM_D5:
   1709     return "d5";
   1710   case UNW_ARM_D6:
   1711     return "d6";
   1712   case UNW_ARM_D7:
   1713     return "d7";
   1714   case UNW_ARM_D8:
   1715     return "d8";
   1716   case UNW_ARM_D9:
   1717     return "d9";
   1718   case UNW_ARM_D10:
   1719     return "d10";
   1720   case UNW_ARM_D11:
   1721     return "d11";
   1722   case UNW_ARM_D12:
   1723     return "d12";
   1724   case UNW_ARM_D13:
   1725     return "d13";
   1726   case UNW_ARM_D14:
   1727     return "d14";
   1728   case UNW_ARM_D15:
   1729     return "d15";
   1730   case UNW_ARM_D16:
   1731     return "d16";
   1732   case UNW_ARM_D17:
   1733     return "d17";
   1734   case UNW_ARM_D18:
   1735     return "d18";
   1736   case UNW_ARM_D19:
   1737     return "d19";
   1738   case UNW_ARM_D20:
   1739     return "d20";
   1740   case UNW_ARM_D21:
   1741     return "d21";
   1742   case UNW_ARM_D22:
   1743     return "d22";
   1744   case UNW_ARM_D23:
   1745     return "d23";
   1746   case UNW_ARM_D24:
   1747     return "d24";
   1748   case UNW_ARM_D25:
   1749     return "d25";
   1750   case UNW_ARM_D26:
   1751     return "d26";
   1752   case UNW_ARM_D27:
   1753     return "d27";
   1754   case UNW_ARM_D28:
   1755     return "d28";
   1756   case UNW_ARM_D29:
   1757     return "d29";
   1758   case UNW_ARM_D30:
   1759     return "d30";
   1760   case UNW_ARM_D31:
   1761     return "d31";
   1762   default:
   1763     return "unknown register";
   1764   }
   1765 }
   1766 
   1767 inline bool Registers_arm::validFloatRegister(int regNum) const {
   1768   // NOTE: Consider the intel MMX registers floating points so the
   1769   // unw_get_fpreg can be used to transmit the 64-bit data back.
   1770   return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
   1771 #if defined(__ARM_WMMX)
   1772       || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
   1773 #endif
   1774       ;
   1775 }
   1776 
   1777 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
   1778   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
   1779     if (!_saved_vfp_d0_d15) {
   1780       _saved_vfp_d0_d15 = true;
   1781       if (_use_X_for_vfp_save)
   1782         saveVFPWithFSTMX(_vfp_d0_d15_pad);
   1783       else
   1784         saveVFPWithFSTMD(_vfp_d0_d15_pad);
   1785     }
   1786     return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
   1787   }
   1788 
   1789   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
   1790     if (!_saved_vfp_d16_d31) {
   1791       _saved_vfp_d16_d31 = true;
   1792       saveVFPv3(_vfp_d16_d31);
   1793     }
   1794     return _vfp_d16_d31[regNum - UNW_ARM_D16];
   1795   }
   1796 
   1797 #if defined(__ARM_WMMX)
   1798   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
   1799     if (!_saved_iwmmx) {
   1800       _saved_iwmmx = true;
   1801       saveiWMMX(_iwmmx);
   1802     }
   1803     return _iwmmx[regNum - UNW_ARM_WR0];
   1804   }
   1805 #endif
   1806 
   1807   _LIBUNWIND_ABORT("Unknown ARM float register");
   1808 }
   1809 
   1810 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
   1811   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
   1812     if (!_saved_vfp_d0_d15) {
   1813       _saved_vfp_d0_d15 = true;
   1814       if (_use_X_for_vfp_save)
   1815         saveVFPWithFSTMX(_vfp_d0_d15_pad);
   1816       else
   1817         saveVFPWithFSTMD(_vfp_d0_d15_pad);
   1818     }
   1819     _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
   1820     return;
   1821   }
   1822 
   1823   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
   1824     if (!_saved_vfp_d16_d31) {
   1825       _saved_vfp_d16_d31 = true;
   1826       saveVFPv3(_vfp_d16_d31);
   1827     }
   1828     _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
   1829     return;
   1830   }
   1831 
   1832 #if defined(__ARM_WMMX)
   1833   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
   1834     if (!_saved_iwmmx) {
   1835       _saved_iwmmx = true;
   1836       saveiWMMX(_iwmmx);
   1837     }
   1838     _iwmmx[regNum - UNW_ARM_WR0] = value;
   1839     return;
   1840   }
   1841 #endif
   1842 
   1843   _LIBUNWIND_ABORT("Unknown ARM float register");
   1844 }
   1845 
   1846 inline bool Registers_arm::validVectorRegister(int) const {
   1847   return false;
   1848 }
   1849 
   1850 inline v128 Registers_arm::getVectorRegister(int) const {
   1851   _LIBUNWIND_ABORT("ARM vector support not implemented");
   1852 }
   1853 
   1854 inline void Registers_arm::setVectorRegister(int, v128) {
   1855   _LIBUNWIND_ABORT("ARM vector support not implemented");
   1856 }
   1857 #endif // _LIBUNWIND_TARGET_ARM
   1858 
   1859 
   1860 #if defined(_LIBUNWIND_TARGET_OR1K)
   1861 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
   1862 /// process.
   1863 class _LIBUNWIND_HIDDEN Registers_or1k {
   1864 public:
   1865   Registers_or1k();
   1866   Registers_or1k(const void *registers);
   1867 
   1868   bool        validRegister(int num) const;
   1869   uint32_t    getRegister(int num) const;
   1870   void        setRegister(int num, uint32_t value);
   1871   bool        validFloatRegister(int num) const;
   1872   double      getFloatRegister(int num) const;
   1873   void        setFloatRegister(int num, double value);
   1874   bool        validVectorRegister(int num) const;
   1875   v128        getVectorRegister(int num) const;
   1876   void        setVectorRegister(int num, v128 value);
   1877   const char *getRegisterName(int num);
   1878   void        jumpto();
   1879   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; }
   1880 
   1881   uint64_t  getSP() const         { return _registers.__r[1]; }
   1882   void      setSP(uint32_t value) { _registers.__r[1] = value; }
   1883   uint64_t  getIP() const         { return _registers.__r[9]; }
   1884   void      setIP(uint32_t value) { _registers.__r[9] = value; }
   1885 
   1886 private:
   1887   struct or1k_thread_state_t {
   1888     unsigned int __r[32];
   1889   };
   1890 
   1891   or1k_thread_state_t _registers;
   1892 };
   1893 
   1894 inline Registers_or1k::Registers_or1k(const void *registers) {
   1895   static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
   1896                 "or1k registers do not fit into unw_context_t");
   1897   memcpy(&_registers, static_cast<const uint8_t *>(registers),
   1898          sizeof(_registers));
   1899 }
   1900 
   1901 inline Registers_or1k::Registers_or1k() {
   1902   memset(&_registers, 0, sizeof(_registers));
   1903 }
   1904 
   1905 inline bool Registers_or1k::validRegister(int regNum) const {
   1906   if (regNum == UNW_REG_IP)
   1907     return true;
   1908   if (regNum == UNW_REG_SP)
   1909     return true;
   1910   if (regNum < 0)
   1911     return false;
   1912   if (regNum <= UNW_OR1K_R31)
   1913     return true;
   1914   return false;
   1915 }
   1916 
   1917 inline uint32_t Registers_or1k::getRegister(int regNum) const {
   1918   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
   1919     return _registers.__r[regNum - UNW_OR1K_R0];
   1920 
   1921   switch (regNum) {
   1922   case UNW_REG_IP:
   1923     return _registers.__r[9];
   1924   case UNW_REG_SP:
   1925     return _registers.__r[1];
   1926   }
   1927   _LIBUNWIND_ABORT("unsupported or1k register");
   1928 }
   1929 
   1930 inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
   1931   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
   1932     _registers.__r[regNum - UNW_OR1K_R0] = value;
   1933     return;
   1934   }
   1935 
   1936   switch (regNum) {
   1937   case UNW_REG_IP:
   1938     _registers.__r[9] = value;
   1939     return;
   1940   case UNW_REG_SP:
   1941     _registers.__r[1] = value;
   1942     return;
   1943   }
   1944   _LIBUNWIND_ABORT("unsupported or1k register");
   1945 }
   1946 
   1947 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
   1948   return false;
   1949 }
   1950 
   1951 inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
   1952   _LIBUNWIND_ABORT("or1k float support not implemented");
   1953 }
   1954 
   1955 inline void Registers_or1k::setFloatRegister(int /* regNum */,
   1956                                              double /* value */) {
   1957   _LIBUNWIND_ABORT("or1k float support not implemented");
   1958 }
   1959 
   1960 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
   1961   return false;
   1962 }
   1963 
   1964 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
   1965   _LIBUNWIND_ABORT("or1k vector support not implemented");
   1966 }
   1967 
   1968 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
   1969   _LIBUNWIND_ABORT("or1k vector support not implemented");
   1970 }
   1971 
   1972 inline const char *Registers_or1k::getRegisterName(int regNum) {
   1973   switch (regNum) {
   1974   case UNW_OR1K_R0:
   1975     return "r0";
   1976   case UNW_OR1K_R1:
   1977     return "r1";
   1978   case UNW_OR1K_R2:
   1979     return "r2";
   1980   case UNW_OR1K_R3:
   1981     return "r3";
   1982   case UNW_OR1K_R4:
   1983     return "r4";
   1984   case UNW_OR1K_R5:
   1985     return "r5";
   1986   case UNW_OR1K_R6:
   1987     return "r6";
   1988   case UNW_OR1K_R7:
   1989     return "r7";
   1990   case UNW_OR1K_R8:
   1991     return "r8";
   1992   case UNW_OR1K_R9:
   1993     return "r9";
   1994   case UNW_OR1K_R10:
   1995     return "r10";
   1996   case UNW_OR1K_R11:
   1997     return "r11";
   1998   case UNW_OR1K_R12:
   1999     return "r12";
   2000   case UNW_OR1K_R13:
   2001     return "r13";
   2002   case UNW_OR1K_R14:
   2003     return "r14";
   2004   case UNW_OR1K_R15:
   2005     return "r15";
   2006   case UNW_OR1K_R16:
   2007     return "r16";
   2008   case UNW_OR1K_R17:
   2009     return "r17";
   2010   case UNW_OR1K_R18:
   2011     return "r18";
   2012   case UNW_OR1K_R19:
   2013     return "r19";
   2014   case UNW_OR1K_R20:
   2015     return "r20";
   2016   case UNW_OR1K_R21:
   2017     return "r21";
   2018   case UNW_OR1K_R22:
   2019     return "r22";
   2020   case UNW_OR1K_R23:
   2021     return "r23";
   2022   case UNW_OR1K_R24:
   2023     return "r24";
   2024   case UNW_OR1K_R25:
   2025     return "r25";
   2026   case UNW_OR1K_R26:
   2027     return "r26";
   2028   case UNW_OR1K_R27:
   2029     return "r27";
   2030   case UNW_OR1K_R28:
   2031     return "r28";
   2032   case UNW_OR1K_R29:
   2033     return "r29";
   2034   case UNW_OR1K_R30:
   2035     return "r30";
   2036   case UNW_OR1K_R31:
   2037     return "r31";
   2038   default:
   2039     return "unknown register";
   2040   }
   2041 
   2042 }
   2043 #endif // _LIBUNWIND_TARGET_OR1K
   2044 
   2045 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
   2046 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
   2047 /// process.
   2048 class _LIBUNWIND_HIDDEN Registers_mips_o32 {
   2049 public:
   2050   Registers_mips_o32();
   2051   Registers_mips_o32(const void *registers);
   2052 
   2053   bool        validRegister(int num) const;
   2054   uint32_t    getRegister(int num) const;
   2055   void        setRegister(int num, uint32_t value);
   2056   bool        validFloatRegister(int num) const;
   2057   double      getFloatRegister(int num) const;
   2058   void        setFloatRegister(int num, double value);
   2059   bool        validVectorRegister(int num) const;
   2060   v128        getVectorRegister(int num) const;
   2061   void        setVectorRegister(int num, v128 value);
   2062   const char *getRegisterName(int num);
   2063   void        jumpto();
   2064   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
   2065 
   2066   uint32_t  getSP() const         { return _registers.__r[29]; }
   2067   void      setSP(uint32_t value) { _registers.__r[29] = value; }
   2068   uint32_t  getIP() const         { return _registers.__pc; }
   2069   void      setIP(uint32_t value) { _registers.__pc = value; }
   2070 
   2071 private:
   2072   struct mips_o32_thread_state_t {
   2073     uint32_t __r[32];
   2074     uint32_t __pc;
   2075     uint32_t __hi;
   2076     uint32_t __lo;
   2077   };
   2078 
   2079   mips_o32_thread_state_t _registers;
   2080 };
   2081 
   2082 inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
   2083   static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
   2084                 "mips_o32 registers do not fit into unw_context_t");
   2085   memcpy(&_registers, static_cast<const uint8_t *>(registers),
   2086          sizeof(_registers));
   2087 }
   2088 
   2089 inline Registers_mips_o32::Registers_mips_o32() {
   2090   memset(&_registers, 0, sizeof(_registers));
   2091 }
   2092 
   2093 inline bool Registers_mips_o32::validRegister(int regNum) const {
   2094   if (regNum == UNW_REG_IP)
   2095     return true;
   2096   if (regNum == UNW_REG_SP)
   2097     return true;
   2098   if (regNum < 0)
   2099     return false;
   2100   if (regNum <= UNW_MIPS_R31)
   2101     return true;
   2102   if (regNum == UNW_MIPS_HI)
   2103     return true;
   2104   if (regNum == UNW_MIPS_LO)
   2105     return true;
   2106   // FIXME: Hard float, DSP accumulator registers, MSA registers
   2107   return false;
   2108 }
   2109 
   2110 inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
   2111   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
   2112     return _registers.__r[regNum - UNW_MIPS_R0];
   2113 
   2114   switch (regNum) {
   2115   case UNW_REG_IP:
   2116     return _registers.__pc;
   2117   case UNW_REG_SP:
   2118     return _registers.__r[29];
   2119   case UNW_MIPS_HI:
   2120     return _registers.__hi;
   2121   case UNW_MIPS_LO:
   2122     return _registers.__lo;
   2123   }
   2124   _LIBUNWIND_ABORT("unsupported mips_o32 register");
   2125 }
   2126 
   2127 inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
   2128   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
   2129     _registers.__r[regNum - UNW_MIPS_R0] = value;
   2130     return;
   2131   }
   2132 
   2133   switch (regNum) {
   2134   case UNW_REG_IP:
   2135     _registers.__pc = value;
   2136     return;
   2137   case UNW_REG_SP:
   2138     _registers.__r[29] = value;
   2139     return;
   2140   case UNW_MIPS_HI:
   2141     _registers.__hi = value;
   2142     return;
   2143   case UNW_MIPS_LO:
   2144     _registers.__lo = value;
   2145     return;
   2146   }
   2147   _LIBUNWIND_ABORT("unsupported mips_o32 register");
   2148 }
   2149 
   2150 inline bool Registers_mips_o32::validFloatRegister(int /* regNum */) const {
   2151   return false;
   2152 }
   2153 
   2154 inline double Registers_mips_o32::getFloatRegister(int /* regNum */) const {
   2155   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
   2156 }
   2157 
   2158 inline void Registers_mips_o32::setFloatRegister(int /* regNum */,
   2159                                                  double /* value */) {
   2160   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
   2161 }
   2162 
   2163 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
   2164   return false;
   2165 }
   2166 
   2167 inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
   2168   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
   2169 }
   2170 
   2171 inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
   2172   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
   2173 }
   2174 
   2175 inline const char *Registers_mips_o32::getRegisterName(int regNum) {
   2176   switch (regNum) {
   2177   case UNW_MIPS_R0:
   2178     return "$0";
   2179   case UNW_MIPS_R1:
   2180     return "$1";
   2181   case UNW_MIPS_R2:
   2182     return "$2";
   2183   case UNW_MIPS_R3:
   2184     return "$3";
   2185   case UNW_MIPS_R4:
   2186     return "$4";
   2187   case UNW_MIPS_R5:
   2188     return "$5";
   2189   case UNW_MIPS_R6:
   2190     return "$6";
   2191   case UNW_MIPS_R7:
   2192     return "$7";
   2193   case UNW_MIPS_R8:
   2194     return "$8";
   2195   case UNW_MIPS_R9:
   2196     return "$9";
   2197   case UNW_MIPS_R10:
   2198     return "$10";
   2199   case UNW_MIPS_R11:
   2200     return "$11";
   2201   case UNW_MIPS_R12:
   2202     return "$12";
   2203   case UNW_MIPS_R13:
   2204     return "$13";
   2205   case UNW_MIPS_R14:
   2206     return "$14";
   2207   case UNW_MIPS_R15:
   2208     return "$15";
   2209   case UNW_MIPS_R16:
   2210     return "$16";
   2211   case UNW_MIPS_R17:
   2212     return "$17";
   2213   case UNW_MIPS_R18:
   2214     return "$18";
   2215   case UNW_MIPS_R19:
   2216     return "$19";
   2217   case UNW_MIPS_R20:
   2218     return "$20";
   2219   case UNW_MIPS_R21:
   2220     return "$21";
   2221   case UNW_MIPS_R22:
   2222     return "$22";
   2223   case UNW_MIPS_R23:
   2224     return "$23";
   2225   case UNW_MIPS_R24:
   2226     return "$24";
   2227   case UNW_MIPS_R25:
   2228     return "$25";
   2229   case UNW_MIPS_R26:
   2230     return "$26";
   2231   case UNW_MIPS_R27:
   2232     return "$27";
   2233   case UNW_MIPS_R28:
   2234     return "$28";
   2235   case UNW_MIPS_R29:
   2236     return "$29";
   2237   case UNW_MIPS_R30:
   2238     return "$30";
   2239   case UNW_MIPS_R31:
   2240     return "$31";
   2241   case UNW_MIPS_HI:
   2242     return "$hi";
   2243   case UNW_MIPS_LO:
   2244     return "$lo";
   2245   default:
   2246     return "unknown register";
   2247   }
   2248 }
   2249 #endif // _LIBUNWIND_TARGET_MIPS_O32
   2250 
   2251 #if defined(_LIBUNWIND_TARGET_MIPS_N64)
   2252 /// Registers_mips_n64 holds the register state of a thread in a 64-bit MIPS
   2253 /// process.
   2254 class _LIBUNWIND_HIDDEN Registers_mips_n64 {
   2255 public:
   2256   Registers_mips_n64();
   2257   Registers_mips_n64(const void *registers);
   2258 
   2259   bool        validRegister(int num) const;
   2260   uint64_t    getRegister(int num) const;
   2261   void        setRegister(int num, uint64_t value);
   2262   bool        validFloatRegister(int num) const;
   2263   double      getFloatRegister(int num) const;
   2264   void        setFloatRegister(int num, double value);
   2265   bool        validVectorRegister(int num) const;
   2266   v128        getVectorRegister(int num) const;
   2267   void        setVectorRegister(int num, v128 value);
   2268   const char *getRegisterName(int num);
   2269   void        jumpto();
   2270   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
   2271 
   2272   uint64_t  getSP() const         { return _registers.__r[29]; }
   2273   void      setSP(uint64_t value) { _registers.__r[29] = value; }
   2274   uint64_t  getIP() const         { return _registers.__pc; }
   2275   void      setIP(uint64_t value) { _registers.__pc = value; }
   2276 
   2277 private:
   2278   struct mips_n64_thread_state_t {
   2279     uint64_t __r[32];
   2280     uint64_t __pc;
   2281     uint64_t __hi;
   2282     uint64_t __lo;
   2283   };
   2284 
   2285   mips_n64_thread_state_t _registers;
   2286 };
   2287 
   2288 inline Registers_mips_n64::Registers_mips_n64(const void *registers) {
   2289   static_assert((check_fit<Registers_mips_n64, unw_context_t>::does_fit),
   2290                 "mips_n64 registers do not fit into unw_context_t");
   2291   memcpy(&_registers, static_cast<const uint8_t *>(registers),
   2292          sizeof(_registers));
   2293 }
   2294 
   2295 inline Registers_mips_n64::Registers_mips_n64() {
   2296   memset(&_registers, 0, sizeof(_registers));
   2297 }
   2298 
   2299 inline bool Registers_mips_n64::validRegister(int regNum) const {
   2300   if (regNum == UNW_REG_IP)
   2301     return true;
   2302   if (regNum == UNW_REG_SP)
   2303     return true;
   2304   if (regNum < 0)
   2305     return false;
   2306   if (regNum <= UNW_MIPS_R31)
   2307     return true;
   2308   if (regNum == UNW_MIPS_HI)
   2309     return true;
   2310   if (regNum == UNW_MIPS_LO)
   2311     return true;
   2312   // FIXME: Hard float, DSP accumulator registers, MSA registers
   2313   return false;
   2314 }
   2315 
   2316 inline uint64_t Registers_mips_n64::getRegister(int regNum) const {
   2317   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
   2318     return _registers.__r[regNum - UNW_MIPS_R0];
   2319 
   2320   switch (regNum) {
   2321   case UNW_REG_IP:
   2322     return _registers.__pc;
   2323   case UNW_REG_SP:
   2324     return _registers.__r[29];
   2325   case UNW_MIPS_HI:
   2326     return _registers.__hi;
   2327   case UNW_MIPS_LO:
   2328     return _registers.__lo;
   2329   }
   2330   _LIBUNWIND_ABORT("unsupported mips_n64 register");
   2331 }
   2332 
   2333 inline void Registers_mips_n64::setRegister(int regNum, uint64_t value) {
   2334   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
   2335     _registers.__r[regNum - UNW_MIPS_R0] = value;
   2336     return;
   2337   }
   2338 
   2339   switch (regNum) {
   2340   case UNW_REG_IP:
   2341     _registers.__pc = value;
   2342     return;
   2343   case UNW_REG_SP:
   2344     _registers.__r[29] = value;
   2345     return;
   2346   case UNW_MIPS_HI:
   2347     _registers.__hi = value;
   2348     return;
   2349   case UNW_MIPS_LO:
   2350     _registers.__lo = value;
   2351     return;
   2352   }
   2353   _LIBUNWIND_ABORT("unsupported mips_n64 register");
   2354 }
   2355 
   2356 inline bool Registers_mips_n64::validFloatRegister(int /* regNum */) const {
   2357   return false;
   2358 }
   2359 
   2360 inline double Registers_mips_n64::getFloatRegister(int /* regNum */) const {
   2361   _LIBUNWIND_ABORT("mips_n64 float support not implemented");
   2362 }
   2363 
   2364 inline void Registers_mips_n64::setFloatRegister(int /* regNum */,
   2365                                                  double /* value */) {
   2366   _LIBUNWIND_ABORT("mips_n64 float support not implemented");
   2367 }
   2368 
   2369 inline bool Registers_mips_n64::validVectorRegister(int /* regNum */) const {
   2370   return false;
   2371 }
   2372 
   2373 inline v128 Registers_mips_n64::getVectorRegister(int /* regNum */) const {
   2374   _LIBUNWIND_ABORT("mips_n64 vector support not implemented");
   2375 }
   2376 
   2377 inline void Registers_mips_n64::setVectorRegister(int /* regNum */, v128 /* value */) {
   2378   _LIBUNWIND_ABORT("mips_n64 vector support not implemented");
   2379 }
   2380 
   2381 inline const char *Registers_mips_n64::getRegisterName(int regNum) {
   2382   switch (regNum) {
   2383   case UNW_MIPS_R0:
   2384     return "$0";
   2385   case UNW_MIPS_R1:
   2386     return "$1";
   2387   case UNW_MIPS_R2:
   2388     return "$2";
   2389   case UNW_MIPS_R3:
   2390     return "$3";
   2391   case UNW_MIPS_R4:
   2392     return "$4";
   2393   case UNW_MIPS_R5:
   2394     return "$5";
   2395   case UNW_MIPS_R6:
   2396     return "$6";
   2397   case UNW_MIPS_R7:
   2398     return "$7";
   2399   case UNW_MIPS_R8:
   2400     return "$8";
   2401   case UNW_MIPS_R9:
   2402     return "$9";
   2403   case UNW_MIPS_R10:
   2404     return "$10";
   2405   case UNW_MIPS_R11:
   2406     return "$11";
   2407   case UNW_MIPS_R12:
   2408     return "$12";
   2409   case UNW_MIPS_R13:
   2410     return "$13";
   2411   case UNW_MIPS_R14:
   2412     return "$14";
   2413   case UNW_MIPS_R15:
   2414     return "$15";
   2415   case UNW_MIPS_R16:
   2416     return "$16";
   2417   case UNW_MIPS_R17:
   2418     return "$17";
   2419   case UNW_MIPS_R18:
   2420     return "$18";
   2421   case UNW_MIPS_R19:
   2422     return "$19";
   2423   case UNW_MIPS_R20:
   2424     return "$20";
   2425   case UNW_MIPS_R21:
   2426     return "$21";
   2427   case UNW_MIPS_R22:
   2428     return "$22";
   2429   case UNW_MIPS_R23:
   2430     return "$23";
   2431   case UNW_MIPS_R24:
   2432     return "$24";
   2433   case UNW_MIPS_R25:
   2434     return "$25";
   2435   case UNW_MIPS_R26:
   2436     return "$26";
   2437   case UNW_MIPS_R27:
   2438     return "$27";
   2439   case UNW_MIPS_R28:
   2440     return "$28";
   2441   case UNW_MIPS_R29:
   2442     return "$29";
   2443   case UNW_MIPS_R30:
   2444     return "$30";
   2445   case UNW_MIPS_R31:
   2446     return "$31";
   2447   case UNW_MIPS_HI:
   2448     return "$hi";
   2449   case UNW_MIPS_LO:
   2450     return "$lo";
   2451   default:
   2452     return "unknown register";
   2453   }
   2454 }
   2455 #endif // _LIBUNWIND_TARGET_MIPS_N64
   2456 } // namespace libunwind
   2457 
   2458 #endif // __REGISTERS_HPP__
   2459