Home | History | Annotate | Download | only in src
      1 //===----------------------------- Registers.hpp --------------------------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //
      8 //  Models register sets for supported processors.
      9 //
     10 //===----------------------------------------------------------------------===//
     11 
     12 #ifndef __REGISTERS_HPP__
     13 #define __REGISTERS_HPP__
     14 
     15 #include <stdint.h>
     16 #include <string.h>
     17 
     18 #include "libunwind.h"
     19 #include "config.h"
     20 
     21 namespace libunwind {
     22 
     23 // For emulating 128-bit registers
     24 struct v128 { uint32_t vec[4]; };
     25 
     26 enum {
     27   REGISTERS_X86,
     28   REGISTERS_X86_64,
     29   REGISTERS_PPC,
     30   REGISTERS_PPC64,
     31   REGISTERS_ARM64,
     32   REGISTERS_ARM,
     33   REGISTERS_OR1K,
     34   REGISTERS_MIPS_O32,
     35   REGISTERS_MIPS_NEWABI,
     36   REGISTERS_SPARC,
     37 };
     38 
     39 #if defined(_LIBUNWIND_TARGET_I386)
     40 /// Registers_x86 holds the register state of a thread in a 32-bit intel
     41 /// process.
     42 class _LIBUNWIND_HIDDEN Registers_x86 {
     43 public:
     44   Registers_x86();
     45   Registers_x86(const void *registers);
     46 
     47   bool        validRegister(int num) const;
     48   uint32_t    getRegister(int num) const;
     49   void        setRegister(int num, uint32_t value);
     50   bool        validFloatRegister(int) const { return false; }
     51   double      getFloatRegister(int num) const;
     52   void        setFloatRegister(int num, double value);
     53   bool        validVectorRegister(int) const { return false; }
     54   v128        getVectorRegister(int num) const;
     55   void        setVectorRegister(int num, v128 value);
     56   static const char *getRegisterName(int num);
     57   void        jumpto();
     58   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
     59   static int  getArch() { return REGISTERS_X86; }
     60 
     61   uint32_t  getSP() const          { return _registers.__esp; }
     62   void      setSP(uint32_t value)  { _registers.__esp = value; }
     63   uint32_t  getIP() const          { return _registers.__eip; }
     64   void      setIP(uint32_t value)  { _registers.__eip = value; }
     65   uint32_t  getEBP() const         { return _registers.__ebp; }
     66   void      setEBP(uint32_t value) { _registers.__ebp = value; }
     67   uint32_t  getEBX() const         { return _registers.__ebx; }
     68   void      setEBX(uint32_t value) { _registers.__ebx = value; }
     69   uint32_t  getECX() const         { return _registers.__ecx; }
     70   void      setECX(uint32_t value) { _registers.__ecx = value; }
     71   uint32_t  getEDX() const         { return _registers.__edx; }
     72   void      setEDX(uint32_t value) { _registers.__edx = value; }
     73   uint32_t  getESI() const         { return _registers.__esi; }
     74   void      setESI(uint32_t value) { _registers.__esi = value; }
     75   uint32_t  getEDI() const         { return _registers.__edi; }
     76   void      setEDI(uint32_t value) { _registers.__edi = value; }
     77 
     78 private:
     79   struct GPRs {
     80     unsigned int __eax;
     81     unsigned int __ebx;
     82     unsigned int __ecx;
     83     unsigned int __edx;
     84     unsigned int __edi;
     85     unsigned int __esi;
     86     unsigned int __ebp;
     87     unsigned int __esp;
     88     unsigned int __ss;
     89     unsigned int __eflags;
     90     unsigned int __eip;
     91     unsigned int __cs;
     92     unsigned int __ds;
     93     unsigned int __es;
     94     unsigned int __fs;
     95     unsigned int __gs;
     96   };
     97 
     98   GPRs _registers;
     99 };
    100 
    101 inline Registers_x86::Registers_x86(const void *registers) {
    102   static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
    103                 "x86 registers do not fit into unw_context_t");
    104   memcpy(&_registers, registers, sizeof(_registers));
    105 }
    106 
    107 inline Registers_x86::Registers_x86() {
    108   memset(&_registers, 0, sizeof(_registers));
    109 }
    110 
    111 inline bool Registers_x86::validRegister(int regNum) const {
    112   if (regNum == UNW_REG_IP)
    113     return true;
    114   if (regNum == UNW_REG_SP)
    115     return true;
    116   if (regNum < 0)
    117     return false;
    118   if (regNum > 7)
    119     return false;
    120   return true;
    121 }
    122 
    123 inline uint32_t Registers_x86::getRegister(int regNum) const {
    124   switch (regNum) {
    125   case UNW_REG_IP:
    126     return _registers.__eip;
    127   case UNW_REG_SP:
    128     return _registers.__esp;
    129   case UNW_X86_EAX:
    130     return _registers.__eax;
    131   case UNW_X86_ECX:
    132     return _registers.__ecx;
    133   case UNW_X86_EDX:
    134     return _registers.__edx;
    135   case UNW_X86_EBX:
    136     return _registers.__ebx;
    137 #if !defined(__APPLE__)
    138   case UNW_X86_ESP:
    139 #else
    140   case UNW_X86_EBP:
    141 #endif
    142     return _registers.__ebp;
    143 #if !defined(__APPLE__)
    144   case UNW_X86_EBP:
    145 #else
    146   case UNW_X86_ESP:
    147 #endif
    148     return _registers.__esp;
    149   case UNW_X86_ESI:
    150     return _registers.__esi;
    151   case UNW_X86_EDI:
    152     return _registers.__edi;
    153   }
    154   _LIBUNWIND_ABORT("unsupported x86 register");
    155 }
    156 
    157 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
    158   switch (regNum) {
    159   case UNW_REG_IP:
    160     _registers.__eip = value;
    161     return;
    162   case UNW_REG_SP:
    163     _registers.__esp = value;
    164     return;
    165   case UNW_X86_EAX:
    166     _registers.__eax = value;
    167     return;
    168   case UNW_X86_ECX:
    169     _registers.__ecx = value;
    170     return;
    171   case UNW_X86_EDX:
    172     _registers.__edx = value;
    173     return;
    174   case UNW_X86_EBX:
    175     _registers.__ebx = value;
    176     return;
    177 #if !defined(__APPLE__)
    178   case UNW_X86_ESP:
    179 #else
    180   case UNW_X86_EBP:
    181 #endif
    182     _registers.__ebp = value;
    183     return;
    184 #if !defined(__APPLE__)
    185   case UNW_X86_EBP:
    186 #else
    187   case UNW_X86_ESP:
    188 #endif
    189     _registers.__esp = value;
    190     return;
    191   case UNW_X86_ESI:
    192     _registers.__esi = value;
    193     return;
    194   case UNW_X86_EDI:
    195     _registers.__edi = value;
    196     return;
    197   }
    198   _LIBUNWIND_ABORT("unsupported x86 register");
    199 }
    200 
    201 inline const char *Registers_x86::getRegisterName(int regNum) {
    202   switch (regNum) {
    203   case UNW_REG_IP:
    204     return "ip";
    205   case UNW_REG_SP:
    206     return "esp";
    207   case UNW_X86_EAX:
    208     return "eax";
    209   case UNW_X86_ECX:
    210     return "ecx";
    211   case UNW_X86_EDX:
    212     return "edx";
    213   case UNW_X86_EBX:
    214     return "ebx";
    215   case UNW_X86_EBP:
    216     return "ebp";
    217   case UNW_X86_ESP:
    218     return "esp";
    219   case UNW_X86_ESI:
    220     return "esi";
    221   case UNW_X86_EDI:
    222     return "edi";
    223   default:
    224     return "unknown register";
    225   }
    226 }
    227 
    228 inline double Registers_x86::getFloatRegister(int) const {
    229   _LIBUNWIND_ABORT("no x86 float registers");
    230 }
    231 
    232 inline void Registers_x86::setFloatRegister(int, double) {
    233   _LIBUNWIND_ABORT("no x86 float registers");
    234 }
    235 
    236 inline v128 Registers_x86::getVectorRegister(int) const {
    237   _LIBUNWIND_ABORT("no x86 vector registers");
    238 }
    239 
    240 inline void Registers_x86::setVectorRegister(int, v128) {
    241   _LIBUNWIND_ABORT("no x86 vector registers");
    242 }
    243 #endif // _LIBUNWIND_TARGET_I386
    244 
    245 
    246 #if defined(_LIBUNWIND_TARGET_X86_64)
    247 /// Registers_x86_64  holds the register state of a thread in a 64-bit intel
    248 /// process.
    249 class _LIBUNWIND_HIDDEN Registers_x86_64 {
    250 public:
    251   Registers_x86_64();
    252   Registers_x86_64(const void *registers);
    253 
    254   bool        validRegister(int num) const;
    255   uint64_t    getRegister(int num) const;
    256   void        setRegister(int num, uint64_t value);
    257   bool        validFloatRegister(int) const { return false; }
    258   double      getFloatRegister(int num) const;
    259   void        setFloatRegister(int num, double value);
    260   bool        validVectorRegister(int) const;
    261   v128        getVectorRegister(int num) const;
    262   void        setVectorRegister(int num, v128 value);
    263   static const char *getRegisterName(int num);
    264   void        jumpto();
    265   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
    266   static int  getArch() { return REGISTERS_X86_64; }
    267 
    268   uint64_t  getSP() const          { return _registers.__rsp; }
    269   void      setSP(uint64_t value)  { _registers.__rsp = value; }
    270   uint64_t  getIP() const          { return _registers.__rip; }
    271   void      setIP(uint64_t value)  { _registers.__rip = value; }
    272   uint64_t  getRBP() const         { return _registers.__rbp; }
    273   void      setRBP(uint64_t value) { _registers.__rbp = value; }
    274   uint64_t  getRBX() const         { return _registers.__rbx; }
    275   void      setRBX(uint64_t value) { _registers.__rbx = value; }
    276   uint64_t  getR12() const         { return _registers.__r12; }
    277   void      setR12(uint64_t value) { _registers.__r12 = value; }
    278   uint64_t  getR13() const         { return _registers.__r13; }
    279   void      setR13(uint64_t value) { _registers.__r13 = value; }
    280   uint64_t  getR14() const         { return _registers.__r14; }
    281   void      setR14(uint64_t value) { _registers.__r14 = value; }
    282   uint64_t  getR15() const         { return _registers.__r15; }
    283   void      setR15(uint64_t value) { _registers.__r15 = value; }
    284 
    285 private:
    286   struct GPRs {
    287     uint64_t __rax;
    288     uint64_t __rbx;
    289     uint64_t __rcx;
    290     uint64_t __rdx;
    291     uint64_t __rdi;
    292     uint64_t __rsi;
    293     uint64_t __rbp;
    294     uint64_t __rsp;
    295     uint64_t __r8;
    296     uint64_t __r9;
    297     uint64_t __r10;
    298     uint64_t __r11;
    299     uint64_t __r12;
    300     uint64_t __r13;
    301     uint64_t __r14;
    302     uint64_t __r15;
    303     uint64_t __rip;
    304     uint64_t __rflags;
    305     uint64_t __cs;
    306     uint64_t __fs;
    307     uint64_t __gs;
    308 #if defined(_WIN64)
    309     uint64_t __padding; // 16-byte align
    310 #endif
    311   };
    312   GPRs _registers;
    313 #if defined(_WIN64)
    314   v128 _xmm[16];
    315 #endif
    316 };
    317 
    318 inline Registers_x86_64::Registers_x86_64(const void *registers) {
    319   static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
    320                 "x86_64 registers do not fit into unw_context_t");
    321   memcpy(&_registers, registers, sizeof(_registers));
    322 }
    323 
    324 inline Registers_x86_64::Registers_x86_64() {
    325   memset(&_registers, 0, sizeof(_registers));
    326 }
    327 
    328 inline bool Registers_x86_64::validRegister(int regNum) const {
    329   if (regNum == UNW_REG_IP)
    330     return true;
    331   if (regNum == UNW_REG_SP)
    332     return true;
    333   if (regNum < 0)
    334     return false;
    335   if (regNum > 15)
    336     return false;
    337   return true;
    338 }
    339 
    340 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
    341   switch (regNum) {
    342   case UNW_REG_IP:
    343     return _registers.__rip;
    344   case UNW_REG_SP:
    345     return _registers.__rsp;
    346   case UNW_X86_64_RAX:
    347     return _registers.__rax;
    348   case UNW_X86_64_RDX:
    349     return _registers.__rdx;
    350   case UNW_X86_64_RCX:
    351     return _registers.__rcx;
    352   case UNW_X86_64_RBX:
    353     return _registers.__rbx;
    354   case UNW_X86_64_RSI:
    355     return _registers.__rsi;
    356   case UNW_X86_64_RDI:
    357     return _registers.__rdi;
    358   case UNW_X86_64_RBP:
    359     return _registers.__rbp;
    360   case UNW_X86_64_RSP:
    361     return _registers.__rsp;
    362   case UNW_X86_64_R8:
    363     return _registers.__r8;
    364   case UNW_X86_64_R9:
    365     return _registers.__r9;
    366   case UNW_X86_64_R10:
    367     return _registers.__r10;
    368   case UNW_X86_64_R11:
    369     return _registers.__r11;
    370   case UNW_X86_64_R12:
    371     return _registers.__r12;
    372   case UNW_X86_64_R13:
    373     return _registers.__r13;
    374   case UNW_X86_64_R14:
    375     return _registers.__r14;
    376   case UNW_X86_64_R15:
    377     return _registers.__r15;
    378   }
    379   _LIBUNWIND_ABORT("unsupported x86_64 register");
    380 }
    381 
    382 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
    383   switch (regNum) {
    384   case UNW_REG_IP:
    385     _registers.__rip = value;
    386     return;
    387   case UNW_REG_SP:
    388     _registers.__rsp = value;
    389     return;
    390   case UNW_X86_64_RAX:
    391     _registers.__rax = value;
    392     return;
    393   case UNW_X86_64_RDX:
    394     _registers.__rdx = value;
    395     return;
    396   case UNW_X86_64_RCX:
    397     _registers.__rcx = value;
    398     return;
    399   case UNW_X86_64_RBX:
    400     _registers.__rbx = value;
    401     return;
    402   case UNW_X86_64_RSI:
    403     _registers.__rsi = value;
    404     return;
    405   case UNW_X86_64_RDI:
    406     _registers.__rdi = value;
    407     return;
    408   case UNW_X86_64_RBP:
    409     _registers.__rbp = value;
    410     return;
    411   case UNW_X86_64_RSP:
    412     _registers.__rsp = value;
    413     return;
    414   case UNW_X86_64_R8:
    415     _registers.__r8 = value;
    416     return;
    417   case UNW_X86_64_R9:
    418     _registers.__r9 = value;
    419     return;
    420   case UNW_X86_64_R10:
    421     _registers.__r10 = value;
    422     return;
    423   case UNW_X86_64_R11:
    424     _registers.__r11 = value;
    425     return;
    426   case UNW_X86_64_R12:
    427     _registers.__r12 = value;
    428     return;
    429   case UNW_X86_64_R13:
    430     _registers.__r13 = value;
    431     return;
    432   case UNW_X86_64_R14:
    433     _registers.__r14 = value;
    434     return;
    435   case UNW_X86_64_R15:
    436     _registers.__r15 = value;
    437     return;
    438   }
    439   _LIBUNWIND_ABORT("unsupported x86_64 register");
    440 }
    441 
    442 inline const char *Registers_x86_64::getRegisterName(int regNum) {
    443   switch (regNum) {
    444   case UNW_REG_IP:
    445     return "rip";
    446   case UNW_REG_SP:
    447     return "rsp";
    448   case UNW_X86_64_RAX:
    449     return "rax";
    450   case UNW_X86_64_RDX:
    451     return "rdx";
    452   case UNW_X86_64_RCX:
    453     return "rcx";
    454   case UNW_X86_64_RBX:
    455     return "rbx";
    456   case UNW_X86_64_RSI:
    457     return "rsi";
    458   case UNW_X86_64_RDI:
    459     return "rdi";
    460   case UNW_X86_64_RBP:
    461     return "rbp";
    462   case UNW_X86_64_RSP:
    463     return "rsp";
    464   case UNW_X86_64_R8:
    465     return "r8";
    466   case UNW_X86_64_R9:
    467     return "r9";
    468   case UNW_X86_64_R10:
    469     return "r10";
    470   case UNW_X86_64_R11:
    471     return "r11";
    472   case UNW_X86_64_R12:
    473     return "r12";
    474   case UNW_X86_64_R13:
    475     return "r13";
    476   case UNW_X86_64_R14:
    477     return "r14";
    478   case UNW_X86_64_R15:
    479     return "r15";
    480   case UNW_X86_64_XMM0:
    481     return "xmm0";
    482   case UNW_X86_64_XMM1:
    483     return "xmm1";
    484   case UNW_X86_64_XMM2:
    485     return "xmm2";
    486   case UNW_X86_64_XMM3:
    487     return "xmm3";
    488   case UNW_X86_64_XMM4:
    489     return "xmm4";
    490   case UNW_X86_64_XMM5:
    491     return "xmm5";
    492   case UNW_X86_64_XMM6:
    493     return "xmm6";
    494   case UNW_X86_64_XMM7:
    495     return "xmm7";
    496   case UNW_X86_64_XMM8:
    497     return "xmm8";
    498   case UNW_X86_64_XMM9:
    499     return "xmm9";
    500   case UNW_X86_64_XMM10:
    501     return "xmm10";
    502   case UNW_X86_64_XMM11:
    503     return "xmm11";
    504   case UNW_X86_64_XMM12:
    505     return "xmm12";
    506   case UNW_X86_64_XMM13:
    507     return "xmm13";
    508   case UNW_X86_64_XMM14:
    509     return "xmm14";
    510   case UNW_X86_64_XMM15:
    511     return "xmm15";
    512   default:
    513     return "unknown register";
    514   }
    515 }
    516 
    517 inline double Registers_x86_64::getFloatRegister(int) const {
    518   _LIBUNWIND_ABORT("no x86_64 float registers");
    519 }
    520 
    521 inline void Registers_x86_64::setFloatRegister(int, double) {
    522   _LIBUNWIND_ABORT("no x86_64 float registers");
    523 }
    524 
    525 inline bool Registers_x86_64::validVectorRegister(int regNum) const {
    526 #if defined(_WIN64)
    527   if (regNum < UNW_X86_64_XMM0)
    528     return false;
    529   if (regNum > UNW_X86_64_XMM15)
    530     return false;
    531   return true;
    532 #else
    533   (void)regNum; // suppress unused parameter warning
    534   return false;
    535 #endif
    536 }
    537 
    538 inline v128 Registers_x86_64::getVectorRegister(int regNum) const {
    539 #if defined(_WIN64)
    540   assert(validVectorRegister(regNum));
    541   return _xmm[regNum - UNW_X86_64_XMM0];
    542 #else
    543   (void)regNum; // suppress unused parameter warning
    544   _LIBUNWIND_ABORT("no x86_64 vector registers");
    545 #endif
    546 }
    547 
    548 inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {
    549 #if defined(_WIN64)
    550   assert(validVectorRegister(regNum));
    551   _xmm[regNum - UNW_X86_64_XMM0] = value;
    552 #else
    553   (void)regNum; (void)value; // suppress unused parameter warnings
    554   _LIBUNWIND_ABORT("no x86_64 vector registers");
    555 #endif
    556 }
    557 #endif // _LIBUNWIND_TARGET_X86_64
    558 
    559 
    560 #if defined(_LIBUNWIND_TARGET_PPC)
    561 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
    562 /// process.
    563 class _LIBUNWIND_HIDDEN Registers_ppc {
    564 public:
    565   Registers_ppc();
    566   Registers_ppc(const void *registers);
    567 
    568   bool        validRegister(int num) const;
    569   uint32_t    getRegister(int num) const;
    570   void        setRegister(int num, uint32_t value);
    571   bool        validFloatRegister(int num) const;
    572   double      getFloatRegister(int num) const;
    573   void        setFloatRegister(int num, double value);
    574   bool        validVectorRegister(int num) const;
    575   v128        getVectorRegister(int num) const;
    576   void        setVectorRegister(int num, v128 value);
    577   static const char *getRegisterName(int num);
    578   void        jumpto();
    579   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; }
    580   static int  getArch() { return REGISTERS_PPC; }
    581 
    582   uint64_t  getSP() const         { return _registers.__r1; }
    583   void      setSP(uint32_t value) { _registers.__r1 = value; }
    584   uint64_t  getIP() const         { return _registers.__srr0; }
    585   void      setIP(uint32_t value) { _registers.__srr0 = value; }
    586 
    587 private:
    588   struct ppc_thread_state_t {
    589     unsigned int __srr0; /* Instruction address register (PC) */
    590     unsigned int __srr1; /* Machine state register (supervisor) */
    591     unsigned int __r0;
    592     unsigned int __r1;
    593     unsigned int __r2;
    594     unsigned int __r3;
    595     unsigned int __r4;
    596     unsigned int __r5;
    597     unsigned int __r6;
    598     unsigned int __r7;
    599     unsigned int __r8;
    600     unsigned int __r9;
    601     unsigned int __r10;
    602     unsigned int __r11;
    603     unsigned int __r12;
    604     unsigned int __r13;
    605     unsigned int __r14;
    606     unsigned int __r15;
    607     unsigned int __r16;
    608     unsigned int __r17;
    609     unsigned int __r18;
    610     unsigned int __r19;
    611     unsigned int __r20;
    612     unsigned int __r21;
    613     unsigned int __r22;
    614     unsigned int __r23;
    615     unsigned int __r24;
    616     unsigned int __r25;
    617     unsigned int __r26;
    618     unsigned int __r27;
    619     unsigned int __r28;
    620     unsigned int __r29;
    621     unsigned int __r30;
    622     unsigned int __r31;
    623     unsigned int __cr;     /* Condition register */
    624     unsigned int __xer;    /* User's integer exception register */
    625     unsigned int __lr;     /* Link register */
    626     unsigned int __ctr;    /* Count register */
    627     unsigned int __mq;     /* MQ register (601 only) */
    628     unsigned int __vrsave; /* Vector Save Register */
    629   };
    630 
    631   struct ppc_float_state_t {
    632     double __fpregs[32];
    633 
    634     unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
    635     unsigned int __fpscr;     /* floating point status register */
    636   };
    637 
    638   ppc_thread_state_t _registers;
    639   ppc_float_state_t  _floatRegisters;
    640   v128               _vectorRegisters[32]; // offset 424
    641 };
    642 
    643 inline Registers_ppc::Registers_ppc(const void *registers) {
    644   static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
    645                 "ppc registers do not fit into unw_context_t");
    646   memcpy(&_registers, static_cast<const uint8_t *>(registers),
    647          sizeof(_registers));
    648   static_assert(sizeof(ppc_thread_state_t) == 160,
    649                 "expected float register offset to be 160");
    650   memcpy(&_floatRegisters,
    651          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
    652          sizeof(_floatRegisters));
    653   static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
    654                 "expected vector register offset to be 424 bytes");
    655   memcpy(_vectorRegisters,
    656          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
    657              sizeof(ppc_float_state_t),
    658          sizeof(_vectorRegisters));
    659 }
    660 
    661 inline Registers_ppc::Registers_ppc() {
    662   memset(&_registers, 0, sizeof(_registers));
    663   memset(&_floatRegisters, 0, sizeof(_floatRegisters));
    664   memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
    665 }
    666 
    667 inline bool Registers_ppc::validRegister(int regNum) const {
    668   if (regNum == UNW_REG_IP)
    669     return true;
    670   if (regNum == UNW_REG_SP)
    671     return true;
    672   if (regNum == UNW_PPC_VRSAVE)
    673     return true;
    674   if (regNum < 0)
    675     return false;
    676   if (regNum <= UNW_PPC_R31)
    677     return true;
    678   if (regNum == UNW_PPC_MQ)
    679     return true;
    680   if (regNum == UNW_PPC_LR)
    681     return true;
    682   if (regNum == UNW_PPC_CTR)
    683     return true;
    684   if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
    685     return true;
    686   return false;
    687 }
    688 
    689 inline uint32_t Registers_ppc::getRegister(int regNum) const {
    690   switch (regNum) {
    691   case UNW_REG_IP:
    692     return _registers.__srr0;
    693   case UNW_REG_SP:
    694     return _registers.__r1;
    695   case UNW_PPC_R0:
    696     return _registers.__r0;
    697   case UNW_PPC_R1:
    698     return _registers.__r1;
    699   case UNW_PPC_R2:
    700     return _registers.__r2;
    701   case UNW_PPC_R3:
    702     return _registers.__r3;
    703   case UNW_PPC_R4:
    704     return _registers.__r4;
    705   case UNW_PPC_R5:
    706     return _registers.__r5;
    707   case UNW_PPC_R6:
    708     return _registers.__r6;
    709   case UNW_PPC_R7:
    710     return _registers.__r7;
    711   case UNW_PPC_R8:
    712     return _registers.__r8;
    713   case UNW_PPC_R9:
    714     return _registers.__r9;
    715   case UNW_PPC_R10:
    716     return _registers.__r10;
    717   case UNW_PPC_R11:
    718     return _registers.__r11;
    719   case UNW_PPC_R12:
    720     return _registers.__r12;
    721   case UNW_PPC_R13:
    722     return _registers.__r13;
    723   case UNW_PPC_R14:
    724     return _registers.__r14;
    725   case UNW_PPC_R15:
    726     return _registers.__r15;
    727   case UNW_PPC_R16:
    728     return _registers.__r16;
    729   case UNW_PPC_R17:
    730     return _registers.__r17;
    731   case UNW_PPC_R18:
    732     return _registers.__r18;
    733   case UNW_PPC_R19:
    734     return _registers.__r19;
    735   case UNW_PPC_R20:
    736     return _registers.__r20;
    737   case UNW_PPC_R21:
    738     return _registers.__r21;
    739   case UNW_PPC_R22:
    740     return _registers.__r22;
    741   case UNW_PPC_R23:
    742     return _registers.__r23;
    743   case UNW_PPC_R24:
    744     return _registers.__r24;
    745   case UNW_PPC_R25:
    746     return _registers.__r25;
    747   case UNW_PPC_R26:
    748     return _registers.__r26;
    749   case UNW_PPC_R27:
    750     return _registers.__r27;
    751   case UNW_PPC_R28:
    752     return _registers.__r28;
    753   case UNW_PPC_R29:
    754     return _registers.__r29;
    755   case UNW_PPC_R30:
    756     return _registers.__r30;
    757   case UNW_PPC_R31:
    758     return _registers.__r31;
    759   case UNW_PPC_LR:
    760     return _registers.__lr;
    761   case UNW_PPC_CR0:
    762     return (_registers.__cr & 0xF0000000);
    763   case UNW_PPC_CR1:
    764     return (_registers.__cr & 0x0F000000);
    765   case UNW_PPC_CR2:
    766     return (_registers.__cr & 0x00F00000);
    767   case UNW_PPC_CR3:
    768     return (_registers.__cr & 0x000F0000);
    769   case UNW_PPC_CR4:
    770     return (_registers.__cr & 0x0000F000);
    771   case UNW_PPC_CR5:
    772     return (_registers.__cr & 0x00000F00);
    773   case UNW_PPC_CR6:
    774     return (_registers.__cr & 0x000000F0);
    775   case UNW_PPC_CR7:
    776     return (_registers.__cr & 0x0000000F);
    777   case UNW_PPC_VRSAVE:
    778     return _registers.__vrsave;
    779   }
    780   _LIBUNWIND_ABORT("unsupported ppc register");
    781 }
    782 
    783 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
    784   //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
    785   switch (regNum) {
    786   case UNW_REG_IP:
    787     _registers.__srr0 = value;
    788     return;
    789   case UNW_REG_SP:
    790     _registers.__r1 = value;
    791     return;
    792   case UNW_PPC_R0:
    793     _registers.__r0 = value;
    794     return;
    795   case UNW_PPC_R1:
    796     _registers.__r1 = value;
    797     return;
    798   case UNW_PPC_R2:
    799     _registers.__r2 = value;
    800     return;
    801   case UNW_PPC_R3:
    802     _registers.__r3 = value;
    803     return;
    804   case UNW_PPC_R4:
    805     _registers.__r4 = value;
    806     return;
    807   case UNW_PPC_R5:
    808     _registers.__r5 = value;
    809     return;
    810   case UNW_PPC_R6:
    811     _registers.__r6 = value;
    812     return;
    813   case UNW_PPC_R7:
    814     _registers.__r7 = value;
    815     return;
    816   case UNW_PPC_R8:
    817     _registers.__r8 = value;
    818     return;
    819   case UNW_PPC_R9:
    820     _registers.__r9 = value;
    821     return;
    822   case UNW_PPC_R10:
    823     _registers.__r10 = value;
    824     return;
    825   case UNW_PPC_R11:
    826     _registers.__r11 = value;
    827     return;
    828   case UNW_PPC_R12:
    829     _registers.__r12 = value;
    830     return;
    831   case UNW_PPC_R13:
    832     _registers.__r13 = value;
    833     return;
    834   case UNW_PPC_R14:
    835     _registers.__r14 = value;
    836     return;
    837   case UNW_PPC_R15:
    838     _registers.__r15 = value;
    839     return;
    840   case UNW_PPC_R16:
    841     _registers.__r16 = value;
    842     return;
    843   case UNW_PPC_R17:
    844     _registers.__r17 = value;
    845     return;
    846   case UNW_PPC_R18:
    847     _registers.__r18 = value;
    848     return;
    849   case UNW_PPC_R19:
    850     _registers.__r19 = value;
    851     return;
    852   case UNW_PPC_R20:
    853     _registers.__r20 = value;
    854     return;
    855   case UNW_PPC_R21:
    856     _registers.__r21 = value;
    857     return;
    858   case UNW_PPC_R22:
    859     _registers.__r22 = value;
    860     return;
    861   case UNW_PPC_R23:
    862     _registers.__r23 = value;
    863     return;
    864   case UNW_PPC_R24:
    865     _registers.__r24 = value;
    866     return;
    867   case UNW_PPC_R25:
    868     _registers.__r25 = value;
    869     return;
    870   case UNW_PPC_R26:
    871     _registers.__r26 = value;
    872     return;
    873   case UNW_PPC_R27:
    874     _registers.__r27 = value;
    875     return;
    876   case UNW_PPC_R28:
    877     _registers.__r28 = value;
    878     return;
    879   case UNW_PPC_R29:
    880     _registers.__r29 = value;
    881     return;
    882   case UNW_PPC_R30:
    883     _registers.__r30 = value;
    884     return;
    885   case UNW_PPC_R31:
    886     _registers.__r31 = value;
    887     return;
    888   case UNW_PPC_MQ:
    889     _registers.__mq = value;
    890     return;
    891   case UNW_PPC_LR:
    892     _registers.__lr = value;
    893     return;
    894   case UNW_PPC_CTR:
    895     _registers.__ctr = value;
    896     return;
    897   case UNW_PPC_CR0:
    898     _registers.__cr &= 0x0FFFFFFF;
    899     _registers.__cr |= (value & 0xF0000000);
    900     return;
    901   case UNW_PPC_CR1:
    902     _registers.__cr &= 0xF0FFFFFF;
    903     _registers.__cr |= (value & 0x0F000000);
    904     return;
    905   case UNW_PPC_CR2:
    906     _registers.__cr &= 0xFF0FFFFF;
    907     _registers.__cr |= (value & 0x00F00000);
    908     return;
    909   case UNW_PPC_CR3:
    910     _registers.__cr &= 0xFFF0FFFF;
    911     _registers.__cr |= (value & 0x000F0000);
    912     return;
    913   case UNW_PPC_CR4:
    914     _registers.__cr &= 0xFFFF0FFF;
    915     _registers.__cr |= (value & 0x0000F000);
    916     return;
    917   case UNW_PPC_CR5:
    918     _registers.__cr &= 0xFFFFF0FF;
    919     _registers.__cr |= (value & 0x00000F00);
    920     return;
    921   case UNW_PPC_CR6:
    922     _registers.__cr &= 0xFFFFFF0F;
    923     _registers.__cr |= (value & 0x000000F0);
    924     return;
    925   case UNW_PPC_CR7:
    926     _registers.__cr &= 0xFFFFFFF0;
    927     _registers.__cr |= (value & 0x0000000F);
    928     return;
    929   case UNW_PPC_VRSAVE:
    930     _registers.__vrsave = value;
    931     return;
    932     // not saved
    933     return;
    934   case UNW_PPC_XER:
    935     _registers.__xer = value;
    936     return;
    937   case UNW_PPC_AP:
    938   case UNW_PPC_VSCR:
    939   case UNW_PPC_SPEFSCR:
    940     // not saved
    941     return;
    942   }
    943   _LIBUNWIND_ABORT("unsupported ppc register");
    944 }
    945 
    946 inline bool Registers_ppc::validFloatRegister(int regNum) const {
    947   if (regNum < UNW_PPC_F0)
    948     return false;
    949   if (regNum > UNW_PPC_F31)
    950     return false;
    951   return true;
    952 }
    953 
    954 inline double Registers_ppc::getFloatRegister(int regNum) const {
    955   assert(validFloatRegister(regNum));
    956   return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
    957 }
    958 
    959 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
    960   assert(validFloatRegister(regNum));
    961   _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
    962 }
    963 
    964 inline bool Registers_ppc::validVectorRegister(int regNum) const {
    965   if (regNum < UNW_PPC_V0)
    966     return false;
    967   if (regNum > UNW_PPC_V31)
    968     return false;
    969   return true;
    970 }
    971 
    972 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
    973   assert(validVectorRegister(regNum));
    974   v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
    975   return result;
    976 }
    977 
    978 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
    979   assert(validVectorRegister(regNum));
    980   _vectorRegisters[regNum - UNW_PPC_V0] = value;
    981 }
    982 
    983 inline const char *Registers_ppc::getRegisterName(int regNum) {
    984   switch (regNum) {
    985   case UNW_REG_IP:
    986     return "ip";
    987   case UNW_REG_SP:
    988     return "sp";
    989   case UNW_PPC_R0:
    990     return "r0";
    991   case UNW_PPC_R1:
    992     return "r1";
    993   case UNW_PPC_R2:
    994     return "r2";
    995   case UNW_PPC_R3:
    996     return "r3";
    997   case UNW_PPC_R4:
    998     return "r4";
    999   case UNW_PPC_R5:
   1000     return "r5";
   1001   case UNW_PPC_R6:
   1002     return "r6";
   1003   case UNW_PPC_R7:
   1004     return "r7";
   1005   case UNW_PPC_R8:
   1006     return "r8";
   1007   case UNW_PPC_R9:
   1008     return "r9";
   1009   case UNW_PPC_R10:
   1010     return "r10";
   1011   case UNW_PPC_R11:
   1012     return "r11";
   1013   case UNW_PPC_R12:
   1014     return "r12";
   1015   case UNW_PPC_R13:
   1016     return "r13";
   1017   case UNW_PPC_R14:
   1018     return "r14";
   1019   case UNW_PPC_R15:
   1020     return "r15";
   1021   case UNW_PPC_R16:
   1022     return "r16";
   1023   case UNW_PPC_R17:
   1024     return "r17";
   1025   case UNW_PPC_R18:
   1026     return "r18";
   1027   case UNW_PPC_R19:
   1028     return "r19";
   1029   case UNW_PPC_R20:
   1030     return "r20";
   1031   case UNW_PPC_R21:
   1032     return "r21";
   1033   case UNW_PPC_R22:
   1034     return "r22";
   1035   case UNW_PPC_R23:
   1036     return "r23";
   1037   case UNW_PPC_R24:
   1038     return "r24";
   1039   case UNW_PPC_R25:
   1040     return "r25";
   1041   case UNW_PPC_R26:
   1042     return "r26";
   1043   case UNW_PPC_R27:
   1044     return "r27";
   1045   case UNW_PPC_R28:
   1046     return "r28";
   1047   case UNW_PPC_R29:
   1048     return "r29";
   1049   case UNW_PPC_R30:
   1050     return "r30";
   1051   case UNW_PPC_R31:
   1052     return "r31";
   1053   case UNW_PPC_F0:
   1054     return "fp0";
   1055   case UNW_PPC_F1:
   1056     return "fp1";
   1057   case UNW_PPC_F2:
   1058     return "fp2";
   1059   case UNW_PPC_F3:
   1060     return "fp3";
   1061   case UNW_PPC_F4:
   1062     return "fp4";
   1063   case UNW_PPC_F5:
   1064     return "fp5";
   1065   case UNW_PPC_F6:
   1066     return "fp6";
   1067   case UNW_PPC_F7:
   1068     return "fp7";
   1069   case UNW_PPC_F8:
   1070     return "fp8";
   1071   case UNW_PPC_F9:
   1072     return "fp9";
   1073   case UNW_PPC_F10:
   1074     return "fp10";
   1075   case UNW_PPC_F11:
   1076     return "fp11";
   1077   case UNW_PPC_F12:
   1078     return "fp12";
   1079   case UNW_PPC_F13:
   1080     return "fp13";
   1081   case UNW_PPC_F14:
   1082     return "fp14";
   1083   case UNW_PPC_F15:
   1084     return "fp15";
   1085   case UNW_PPC_F16:
   1086     return "fp16";
   1087   case UNW_PPC_F17:
   1088     return "fp17";
   1089   case UNW_PPC_F18:
   1090     return "fp18";
   1091   case UNW_PPC_F19:
   1092     return "fp19";
   1093   case UNW_PPC_F20:
   1094     return "fp20";
   1095   case UNW_PPC_F21:
   1096     return "fp21";
   1097   case UNW_PPC_F22:
   1098     return "fp22";
   1099   case UNW_PPC_F23:
   1100     return "fp23";
   1101   case UNW_PPC_F24:
   1102     return "fp24";
   1103   case UNW_PPC_F25:
   1104     return "fp25";
   1105   case UNW_PPC_F26:
   1106     return "fp26";
   1107   case UNW_PPC_F27:
   1108     return "fp27";
   1109   case UNW_PPC_F28:
   1110     return "fp28";
   1111   case UNW_PPC_F29:
   1112     return "fp29";
   1113   case UNW_PPC_F30:
   1114     return "fp30";
   1115   case UNW_PPC_F31:
   1116     return "fp31";
   1117   case UNW_PPC_LR:
   1118     return "lr";
   1119   default:
   1120     return "unknown register";
   1121   }
   1122 
   1123 }
   1124 #endif // _LIBUNWIND_TARGET_PPC
   1125 
   1126 #if defined(_LIBUNWIND_TARGET_PPC64)
   1127 /// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC
   1128 /// process.
   1129 class _LIBUNWIND_HIDDEN Registers_ppc64 {
   1130 public:
   1131   Registers_ppc64();
   1132   Registers_ppc64(const void *registers);
   1133 
   1134   bool        validRegister(int num) const;
   1135   uint64_t    getRegister(int num) const;
   1136   void        setRegister(int num, uint64_t value);
   1137   bool        validFloatRegister(int num) const;
   1138   double      getFloatRegister(int num) const;
   1139   void        setFloatRegister(int num, double value);
   1140   bool        validVectorRegister(int num) const;
   1141   v128        getVectorRegister(int num) const;
   1142   void        setVectorRegister(int num, v128 value);
   1143   static const char *getRegisterName(int num);
   1144   void        jumpto();
   1145   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64; }
   1146   static int  getArch() { return REGISTERS_PPC64; }
   1147 
   1148   uint64_t  getSP() const         { return _registers.__r1; }
   1149   void      setSP(uint64_t value) { _registers.__r1 = value; }
   1150   uint64_t  getIP() const         { return _registers.__srr0; }
   1151   void      setIP(uint64_t value) { _registers.__srr0 = value; }
   1152 
   1153 private:
   1154   struct ppc64_thread_state_t {
   1155     uint64_t __srr0;    // Instruction address register (PC)
   1156     uint64_t __srr1;    // Machine state register (supervisor)
   1157     uint64_t __r0;
   1158     uint64_t __r1;
   1159     uint64_t __r2;
   1160     uint64_t __r3;
   1161     uint64_t __r4;
   1162     uint64_t __r5;
   1163     uint64_t __r6;
   1164     uint64_t __r7;
   1165     uint64_t __r8;
   1166     uint64_t __r9;
   1167     uint64_t __r10;
   1168     uint64_t __r11;
   1169     uint64_t __r12;
   1170     uint64_t __r13;
   1171     uint64_t __r14;
   1172     uint64_t __r15;
   1173     uint64_t __r16;
   1174     uint64_t __r17;
   1175     uint64_t __r18;
   1176     uint64_t __r19;
   1177     uint64_t __r20;
   1178     uint64_t __r21;
   1179     uint64_t __r22;
   1180     uint64_t __r23;
   1181     uint64_t __r24;
   1182     uint64_t __r25;
   1183     uint64_t __r26;
   1184     uint64_t __r27;
   1185     uint64_t __r28;
   1186     uint64_t __r29;
   1187     uint64_t __r30;
   1188     uint64_t __r31;
   1189     uint64_t __cr;      // Condition register
   1190     uint64_t __xer;     // User's integer exception register
   1191     uint64_t __lr;      // Link register
   1192     uint64_t __ctr;     // Count register
   1193     uint64_t __vrsave;  // Vector Save Register
   1194   };
   1195 
   1196   union ppc64_vsr_t {
   1197     struct asfloat_s {
   1198       double f;
   1199       uint64_t v2;
   1200     } asfloat;
   1201     v128 v;
   1202   };
   1203 
   1204   ppc64_thread_state_t _registers;
   1205   ppc64_vsr_t          _vectorScalarRegisters[64];
   1206 
   1207   static int getVectorRegNum(int num);
   1208 };
   1209 
   1210 inline Registers_ppc64::Registers_ppc64(const void *registers) {
   1211   static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit),
   1212                 "ppc64 registers do not fit into unw_context_t");
   1213   memcpy(&_registers, static_cast<const uint8_t *>(registers),
   1214          sizeof(_registers));
   1215   static_assert(sizeof(_registers) == 312,
   1216                 "expected vector scalar register offset to be 312");
   1217   memcpy(&_vectorScalarRegisters,
   1218          static_cast<const uint8_t *>(registers) + sizeof(_registers),
   1219          sizeof(_vectorScalarRegisters));
   1220   static_assert(sizeof(_registers) +
   1221                 sizeof(_vectorScalarRegisters) == 1336,
   1222                 "expected vector register offset to be 1336 bytes");
   1223 }
   1224 
   1225 inline Registers_ppc64::Registers_ppc64() {
   1226   memset(&_registers, 0, sizeof(_registers));
   1227   memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters));
   1228 }
   1229 
   1230 inline bool Registers_ppc64::validRegister(int regNum) const {
   1231   switch (regNum) {
   1232   case UNW_REG_IP:
   1233   case UNW_REG_SP:
   1234   case UNW_PPC64_XER:
   1235   case UNW_PPC64_LR:
   1236   case UNW_PPC64_CTR:
   1237   case UNW_PPC64_VRSAVE:
   1238       return true;
   1239   }
   1240 
   1241   if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31)
   1242     return true;
   1243   if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7)
   1244     return true;
   1245 
   1246   return false;
   1247 }
   1248 
   1249 inline uint64_t Registers_ppc64::getRegister(int regNum) const {
   1250   switch (regNum) {
   1251   case UNW_REG_IP:
   1252     return _registers.__srr0;
   1253   case UNW_PPC64_R0:
   1254     return _registers.__r0;
   1255   case UNW_PPC64_R1:
   1256   case UNW_REG_SP:
   1257     return _registers.__r1;
   1258   case UNW_PPC64_R2:
   1259     return _registers.__r2;
   1260   case UNW_PPC64_R3:
   1261     return _registers.__r3;
   1262   case UNW_PPC64_R4:
   1263     return _registers.__r4;
   1264   case UNW_PPC64_R5:
   1265     return _registers.__r5;
   1266   case UNW_PPC64_R6:
   1267     return _registers.__r6;
   1268   case UNW_PPC64_R7:
   1269     return _registers.__r7;
   1270   case UNW_PPC64_R8:
   1271     return _registers.__r8;
   1272   case UNW_PPC64_R9:
   1273     return _registers.__r9;
   1274   case UNW_PPC64_R10:
   1275     return _registers.__r10;
   1276   case UNW_PPC64_R11:
   1277     return _registers.__r11;
   1278   case UNW_PPC64_R12:
   1279     return _registers.__r12;
   1280   case UNW_PPC64_R13:
   1281     return _registers.__r13;
   1282   case UNW_PPC64_R14:
   1283     return _registers.__r14;
   1284   case UNW_PPC64_R15:
   1285     return _registers.__r15;
   1286   case UNW_PPC64_R16:
   1287     return _registers.__r16;
   1288   case UNW_PPC64_R17:
   1289     return _registers.__r17;
   1290   case UNW_PPC64_R18:
   1291     return _registers.__r18;
   1292   case UNW_PPC64_R19:
   1293     return _registers.__r19;
   1294   case UNW_PPC64_R20:
   1295     return _registers.__r20;
   1296   case UNW_PPC64_R21:
   1297     return _registers.__r21;
   1298   case UNW_PPC64_R22:
   1299     return _registers.__r22;
   1300   case UNW_PPC64_R23:
   1301     return _registers.__r23;
   1302   case UNW_PPC64_R24:
   1303     return _registers.__r24;
   1304   case UNW_PPC64_R25:
   1305     return _registers.__r25;
   1306   case UNW_PPC64_R26:
   1307     return _registers.__r26;
   1308   case UNW_PPC64_R27:
   1309     return _registers.__r27;
   1310   case UNW_PPC64_R28:
   1311     return _registers.__r28;
   1312   case UNW_PPC64_R29:
   1313     return _registers.__r29;
   1314   case UNW_PPC64_R30:
   1315     return _registers.__r30;
   1316   case UNW_PPC64_R31:
   1317     return _registers.__r31;
   1318   case UNW_PPC64_CR0:
   1319     return (_registers.__cr & 0xF0000000);
   1320   case UNW_PPC64_CR1:
   1321     return (_registers.__cr & 0x0F000000);
   1322   case UNW_PPC64_CR2:
   1323     return (_registers.__cr & 0x00F00000);
   1324   case UNW_PPC64_CR3:
   1325     return (_registers.__cr & 0x000F0000);
   1326   case UNW_PPC64_CR4:
   1327     return (_registers.__cr & 0x0000F000);
   1328   case UNW_PPC64_CR5:
   1329     return (_registers.__cr & 0x00000F00);
   1330   case UNW_PPC64_CR6:
   1331     return (_registers.__cr & 0x000000F0);
   1332   case UNW_PPC64_CR7:
   1333     return (_registers.__cr & 0x0000000F);
   1334   case UNW_PPC64_XER:
   1335     return _registers.__xer;
   1336   case UNW_PPC64_LR:
   1337     return _registers.__lr;
   1338   case UNW_PPC64_CTR:
   1339     return _registers.__ctr;
   1340   case UNW_PPC64_VRSAVE:
   1341     return _registers.__vrsave;
   1342   }
   1343   _LIBUNWIND_ABORT("unsupported ppc64 register");
   1344 }
   1345 
   1346 inline void Registers_ppc64::setRegister(int regNum, uint64_t value) {
   1347   switch (regNum) {
   1348   case UNW_REG_IP:
   1349     _registers.__srr0 = value;
   1350     return;
   1351   case UNW_PPC64_R0:
   1352     _registers.__r0 = value;
   1353     return;
   1354   case UNW_PPC64_R1:
   1355   case UNW_REG_SP:
   1356     _registers.__r1 = value;
   1357     return;
   1358   case UNW_PPC64_R2:
   1359     _registers.__r2 = value;
   1360     return;
   1361   case UNW_PPC64_R3:
   1362     _registers.__r3 = value;
   1363     return;
   1364   case UNW_PPC64_R4:
   1365     _registers.__r4 = value;
   1366     return;
   1367   case UNW_PPC64_R5:
   1368     _registers.__r5 = value;
   1369     return;
   1370   case UNW_PPC64_R6:
   1371     _registers.__r6 = value;
   1372     return;
   1373   case UNW_PPC64_R7:
   1374     _registers.__r7 = value;
   1375     return;
   1376   case UNW_PPC64_R8:
   1377     _registers.__r8 = value;
   1378     return;
   1379   case UNW_PPC64_R9:
   1380     _registers.__r9 = value;
   1381     return;
   1382   case UNW_PPC64_R10:
   1383     _registers.__r10 = value;
   1384     return;
   1385   case UNW_PPC64_R11:
   1386     _registers.__r11 = value;
   1387     return;
   1388   case UNW_PPC64_R12:
   1389     _registers.__r12 = value;
   1390     return;
   1391   case UNW_PPC64_R13:
   1392     _registers.__r13 = value;
   1393     return;
   1394   case UNW_PPC64_R14:
   1395     _registers.__r14 = value;
   1396     return;
   1397   case UNW_PPC64_R15:
   1398     _registers.__r15 = value;
   1399     return;
   1400   case UNW_PPC64_R16:
   1401     _registers.__r16 = value;
   1402     return;
   1403   case UNW_PPC64_R17:
   1404     _registers.__r17 = value;
   1405     return;
   1406   case UNW_PPC64_R18:
   1407     _registers.__r18 = value;
   1408     return;
   1409   case UNW_PPC64_R19:
   1410     _registers.__r19 = value;
   1411     return;
   1412   case UNW_PPC64_R20:
   1413     _registers.__r20 = value;
   1414     return;
   1415   case UNW_PPC64_R21:
   1416     _registers.__r21 = value;
   1417     return;
   1418   case UNW_PPC64_R22:
   1419     _registers.__r22 = value;
   1420     return;
   1421   case UNW_PPC64_R23:
   1422     _registers.__r23 = value;
   1423     return;
   1424   case UNW_PPC64_R24:
   1425     _registers.__r24 = value;
   1426     return;
   1427   case UNW_PPC64_R25:
   1428     _registers.__r25 = value;
   1429     return;
   1430   case UNW_PPC64_R26:
   1431     _registers.__r26 = value;
   1432     return;
   1433   case UNW_PPC64_R27:
   1434     _registers.__r27 = value;
   1435     return;
   1436   case UNW_PPC64_R28:
   1437     _registers.__r28 = value;
   1438     return;
   1439   case UNW_PPC64_R29:
   1440     _registers.__r29 = value;
   1441     return;
   1442   case UNW_PPC64_R30:
   1443     _registers.__r30 = value;
   1444     return;
   1445   case UNW_PPC64_R31:
   1446     _registers.__r31 = value;
   1447     return;
   1448   case UNW_PPC64_CR0:
   1449     _registers.__cr &= 0x0FFFFFFF;
   1450     _registers.__cr |= (value & 0xF0000000);
   1451     return;
   1452   case UNW_PPC64_CR1:
   1453     _registers.__cr &= 0xF0FFFFFF;
   1454     _registers.__cr |= (value & 0x0F000000);
   1455     return;
   1456   case UNW_PPC64_CR2:
   1457     _registers.__cr &= 0xFF0FFFFF;
   1458     _registers.__cr |= (value & 0x00F00000);
   1459     return;
   1460   case UNW_PPC64_CR3:
   1461     _registers.__cr &= 0xFFF0FFFF;
   1462     _registers.__cr |= (value & 0x000F0000);
   1463     return;
   1464   case UNW_PPC64_CR4:
   1465     _registers.__cr &= 0xFFFF0FFF;
   1466     _registers.__cr |= (value & 0x0000F000);
   1467     return;
   1468   case UNW_PPC64_CR5:
   1469     _registers.__cr &= 0xFFFFF0FF;
   1470     _registers.__cr |= (value & 0x00000F00);
   1471     return;
   1472   case UNW_PPC64_CR6:
   1473     _registers.__cr &= 0xFFFFFF0F;
   1474     _registers.__cr |= (value & 0x000000F0);
   1475     return;
   1476   case UNW_PPC64_CR7:
   1477     _registers.__cr &= 0xFFFFFFF0;
   1478     _registers.__cr |= (value & 0x0000000F);
   1479     return;
   1480   case UNW_PPC64_XER:
   1481     _registers.__xer = value;
   1482     return;
   1483   case UNW_PPC64_LR:
   1484     _registers.__lr = value;
   1485     return;
   1486   case UNW_PPC64_CTR:
   1487     _registers.__ctr = value;
   1488     return;
   1489   case UNW_PPC64_VRSAVE:
   1490     _registers.__vrsave = value;
   1491     return;
   1492   }
   1493   _LIBUNWIND_ABORT("unsupported ppc64 register");
   1494 }
   1495 
   1496 inline bool Registers_ppc64::validFloatRegister(int regNum) const {
   1497   return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31;
   1498 }
   1499 
   1500 inline double Registers_ppc64::getFloatRegister(int regNum) const {
   1501   assert(validFloatRegister(regNum));
   1502   return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f;
   1503 }
   1504 
   1505 inline void Registers_ppc64::setFloatRegister(int regNum, double value) {
   1506   assert(validFloatRegister(regNum));
   1507   _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value;
   1508 }
   1509 
   1510 inline bool Registers_ppc64::validVectorRegister(int regNum) const {
   1511 #ifdef PPC64_HAS_VMX
   1512   if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)
   1513     return true;
   1514   if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)
   1515     return true;
   1516 #else
   1517   if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)
   1518     return true;
   1519 #endif
   1520   return false;
   1521 }
   1522 
   1523 inline int Registers_ppc64::getVectorRegNum(int num)
   1524 {
   1525   if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31)
   1526     return num - UNW_PPC64_VS0;
   1527   else
   1528     return num - UNW_PPC64_VS32 + 32;
   1529 }
   1530 
   1531 inline v128 Registers_ppc64::getVectorRegister(int regNum) const {
   1532   assert(validVectorRegister(regNum));
   1533   return _vectorScalarRegisters[getVectorRegNum(regNum)].v;
   1534 }
   1535 
   1536 inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) {
   1537   assert(validVectorRegister(regNum));
   1538   _vectorScalarRegisters[getVectorRegNum(regNum)].v = value;
   1539 }
   1540 
   1541 inline const char *Registers_ppc64::getRegisterName(int regNum) {
   1542   switch (regNum) {
   1543   case UNW_REG_IP:
   1544     return "ip";
   1545   case UNW_REG_SP:
   1546     return "sp";
   1547   case UNW_PPC64_R0:
   1548     return "r0";
   1549   case UNW_PPC64_R1:
   1550     return "r1";
   1551   case UNW_PPC64_R2:
   1552     return "r2";
   1553   case UNW_PPC64_R3:
   1554     return "r3";
   1555   case UNW_PPC64_R4:
   1556     return "r4";
   1557   case UNW_PPC64_R5:
   1558     return "r5";
   1559   case UNW_PPC64_R6:
   1560     return "r6";
   1561   case UNW_PPC64_R7:
   1562     return "r7";
   1563   case UNW_PPC64_R8:
   1564     return "r8";
   1565   case UNW_PPC64_R9:
   1566     return "r9";
   1567   case UNW_PPC64_R10:
   1568     return "r10";
   1569   case UNW_PPC64_R11:
   1570     return "r11";
   1571   case UNW_PPC64_R12:
   1572     return "r12";
   1573   case UNW_PPC64_R13:
   1574     return "r13";
   1575   case UNW_PPC64_R14:
   1576     return "r14";
   1577   case UNW_PPC64_R15:
   1578     return "r15";
   1579   case UNW_PPC64_R16:
   1580     return "r16";
   1581   case UNW_PPC64_R17:
   1582     return "r17";
   1583   case UNW_PPC64_R18:
   1584     return "r18";
   1585   case UNW_PPC64_R19:
   1586     return "r19";
   1587   case UNW_PPC64_R20:
   1588     return "r20";
   1589   case UNW_PPC64_R21:
   1590     return "r21";
   1591   case UNW_PPC64_R22:
   1592     return "r22";
   1593   case UNW_PPC64_R23:
   1594     return "r23";
   1595   case UNW_PPC64_R24:
   1596     return "r24";
   1597   case UNW_PPC64_R25:
   1598     return "r25";
   1599   case UNW_PPC64_R26:
   1600     return "r26";
   1601   case UNW_PPC64_R27:
   1602     return "r27";
   1603   case UNW_PPC64_R28:
   1604     return "r28";
   1605   case UNW_PPC64_R29:
   1606     return "r29";
   1607   case UNW_PPC64_R30:
   1608     return "r30";
   1609   case UNW_PPC64_R31:
   1610     return "r31";
   1611   case UNW_PPC64_CR0:
   1612     return "cr0";
   1613   case UNW_PPC64_CR1:
   1614     return "cr1";
   1615   case UNW_PPC64_CR2:
   1616     return "cr2";
   1617   case UNW_PPC64_CR3:
   1618     return "cr3";
   1619   case UNW_PPC64_CR4:
   1620     return "cr4";
   1621   case UNW_PPC64_CR5:
   1622     return "cr5";
   1623   case UNW_PPC64_CR6:
   1624     return "cr6";
   1625   case UNW_PPC64_CR7:
   1626     return "cr7";
   1627   case UNW_PPC64_XER:
   1628     return "xer";
   1629   case UNW_PPC64_LR:
   1630     return "lr";
   1631   case UNW_PPC64_CTR:
   1632     return "ctr";
   1633   case UNW_PPC64_VRSAVE:
   1634     return "vrsave";
   1635   case UNW_PPC64_F0:
   1636     return "fp0";
   1637   case UNW_PPC64_F1:
   1638     return "fp1";
   1639   case UNW_PPC64_F2:
   1640     return "fp2";
   1641   case UNW_PPC64_F3:
   1642     return "fp3";
   1643   case UNW_PPC64_F4:
   1644     return "fp4";
   1645   case UNW_PPC64_F5:
   1646     return "fp5";
   1647   case UNW_PPC64_F6:
   1648     return "fp6";
   1649   case UNW_PPC64_F7:
   1650     return "fp7";
   1651   case UNW_PPC64_F8:
   1652     return "fp8";
   1653   case UNW_PPC64_F9:
   1654     return "fp9";
   1655   case UNW_PPC64_F10:
   1656     return "fp10";
   1657   case UNW_PPC64_F11:
   1658     return "fp11";
   1659   case UNW_PPC64_F12:
   1660     return "fp12";
   1661   case UNW_PPC64_F13:
   1662     return "fp13";
   1663   case UNW_PPC64_F14:
   1664     return "fp14";
   1665   case UNW_PPC64_F15:
   1666     return "fp15";
   1667   case UNW_PPC64_F16:
   1668     return "fp16";
   1669   case UNW_PPC64_F17:
   1670     return "fp17";
   1671   case UNW_PPC64_F18:
   1672     return "fp18";
   1673   case UNW_PPC64_F19:
   1674     return "fp19";
   1675   case UNW_PPC64_F20:
   1676     return "fp20";
   1677   case UNW_PPC64_F21:
   1678     return "fp21";
   1679   case UNW_PPC64_F22:
   1680     return "fp22";
   1681   case UNW_PPC64_F23:
   1682     return "fp23";
   1683   case UNW_PPC64_F24:
   1684     return "fp24";
   1685   case UNW_PPC64_F25:
   1686     return "fp25";
   1687   case UNW_PPC64_F26:
   1688     return "fp26";
   1689   case UNW_PPC64_F27:
   1690     return "fp27";
   1691   case UNW_PPC64_F28:
   1692     return "fp28";
   1693   case UNW_PPC64_F29:
   1694     return "fp29";
   1695   case UNW_PPC64_F30:
   1696     return "fp30";
   1697   case UNW_PPC64_F31:
   1698     return "fp31";
   1699   case UNW_PPC64_V0:
   1700     return "v0";
   1701   case UNW_PPC64_V1:
   1702     return "v1";
   1703   case UNW_PPC64_V2:
   1704     return "v2";
   1705   case UNW_PPC64_V3:
   1706     return "v3";
   1707   case UNW_PPC64_V4:
   1708     return "v4";
   1709   case UNW_PPC64_V5:
   1710     return "v5";
   1711   case UNW_PPC64_V6:
   1712     return "v6";
   1713   case UNW_PPC64_V7:
   1714     return "v7";
   1715   case UNW_PPC64_V8:
   1716     return "v8";
   1717   case UNW_PPC64_V9:
   1718     return "v9";
   1719   case UNW_PPC64_V10:
   1720     return "v10";
   1721   case UNW_PPC64_V11:
   1722     return "v11";
   1723   case UNW_PPC64_V12:
   1724     return "v12";
   1725   case UNW_PPC64_V13:
   1726     return "v13";
   1727   case UNW_PPC64_V14:
   1728     return "v14";
   1729   case UNW_PPC64_V15:
   1730     return "v15";
   1731   case UNW_PPC64_V16:
   1732     return "v16";
   1733   case UNW_PPC64_V17:
   1734     return "v17";
   1735   case UNW_PPC64_V18:
   1736     return "v18";
   1737   case UNW_PPC64_V19:
   1738     return "v19";
   1739   case UNW_PPC64_V20:
   1740     return "v20";
   1741   case UNW_PPC64_V21:
   1742     return "v21";
   1743   case UNW_PPC64_V22:
   1744     return "v22";
   1745   case UNW_PPC64_V23:
   1746     return "v23";
   1747   case UNW_PPC64_V24:
   1748     return "v24";
   1749   case UNW_PPC64_V25:
   1750     return "v25";
   1751   case UNW_PPC64_V26:
   1752     return "v26";
   1753   case UNW_PPC64_V27:
   1754     return "v27";
   1755   case UNW_PPC64_V28:
   1756     return "v28";
   1757   case UNW_PPC64_V29:
   1758     return "v29";
   1759   case UNW_PPC64_V30:
   1760     return "v30";
   1761   case UNW_PPC64_V31:
   1762     return "v31";
   1763   }
   1764   return "unknown register";
   1765 }
   1766 #endif // _LIBUNWIND_TARGET_PPC64
   1767 
   1768 
   1769 #if defined(_LIBUNWIND_TARGET_AARCH64)
   1770 /// Registers_arm64  holds the register state of a thread in a 64-bit arm
   1771 /// process.
   1772 class _LIBUNWIND_HIDDEN Registers_arm64 {
   1773 public:
   1774   Registers_arm64();
   1775   Registers_arm64(const void *registers);
   1776 
   1777   bool        validRegister(int num) const;
   1778   uint64_t    getRegister(int num) const;
   1779   void        setRegister(int num, uint64_t value);
   1780   bool        validFloatRegister(int num) const;
   1781   double      getFloatRegister(int num) const;
   1782   void        setFloatRegister(int num, double value);
   1783   bool        validVectorRegister(int num) const;
   1784   v128        getVectorRegister(int num) const;
   1785   void        setVectorRegister(int num, v128 value);
   1786   static const char *getRegisterName(int num);
   1787   void        jumpto();
   1788   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
   1789   static int  getArch() { return REGISTERS_ARM64; }
   1790 
   1791   uint64_t  getSP() const         { return _registers.__sp; }
   1792   void      setSP(uint64_t value) { _registers.__sp = value; }
   1793   uint64_t  getIP() const         { return _registers.__pc; }
   1794   void      setIP(uint64_t value) { _registers.__pc = value; }
   1795   uint64_t  getFP() const         { return _registers.__fp; }
   1796   void      setFP(uint64_t value) { _registers.__fp = value; }
   1797 
   1798 private:
   1799   struct GPRs {
   1800     uint64_t __x[29]; // x0-x28
   1801     uint64_t __fp;    // Frame pointer x29
   1802     uint64_t __lr;    // Link register x30
   1803     uint64_t __sp;    // Stack pointer x31
   1804     uint64_t __pc;    // Program counter
   1805     uint64_t __ra_sign_state; // RA sign state register
   1806   };
   1807 
   1808   GPRs    _registers;
   1809   double  _vectorHalfRegisters[32];
   1810   // Currently only the lower double in 128-bit vectore registers
   1811   // is perserved during unwinding.  We could define new register
   1812   // numbers (> 96) which mean whole vector registers, then this
   1813   // struct would need to change to contain whole vector registers.
   1814 };
   1815 
   1816 inline Registers_arm64::Registers_arm64(const void *registers) {
   1817   static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
   1818                 "arm64 registers do not fit into unw_context_t");
   1819   memcpy(&_registers, registers, sizeof(_registers));
   1820   static_assert(sizeof(GPRs) == 0x110,
   1821                 "expected VFP registers to be at offset 272");
   1822   memcpy(_vectorHalfRegisters,
   1823          static_cast<const uint8_t *>(registers) + sizeof(GPRs),
   1824          sizeof(_vectorHalfRegisters));
   1825 }
   1826 
   1827 inline Registers_arm64::Registers_arm64() {
   1828   memset(&_registers, 0, sizeof(_registers));
   1829   memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
   1830 }
   1831 
   1832 inline bool Registers_arm64::validRegister(int regNum) const {
   1833   if (regNum == UNW_REG_IP)
   1834     return true;
   1835   if (regNum == UNW_REG_SP)
   1836     return true;
   1837   if (regNum < 0)
   1838     return false;
   1839   if (regNum > 95)
   1840     return false;
   1841   if (regNum == UNW_ARM64_RA_SIGN_STATE)
   1842     return true;
   1843   if ((regNum > 31) && (regNum < 64))
   1844     return false;
   1845   return true;
   1846 }
   1847 
   1848 inline uint64_t Registers_arm64::getRegister(int regNum) const {
   1849   if (regNum == UNW_REG_IP)
   1850     return _registers.__pc;
   1851   if (regNum == UNW_REG_SP)
   1852     return _registers.__sp;
   1853   if (regNum == UNW_ARM64_RA_SIGN_STATE)
   1854     return _registers.__ra_sign_state;
   1855   if ((regNum >= 0) && (regNum < 32))
   1856     return _registers.__x[regNum];
   1857   _LIBUNWIND_ABORT("unsupported arm64 register");
   1858 }
   1859 
   1860 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
   1861   if (regNum == UNW_REG_IP)
   1862     _registers.__pc = value;
   1863   else if (regNum == UNW_REG_SP)
   1864     _registers.__sp = value;
   1865   else if (regNum == UNW_ARM64_RA_SIGN_STATE)
   1866     _registers.__ra_sign_state = value;
   1867   else if ((regNum >= 0) && (regNum < 32))
   1868     _registers.__x[regNum] = value;
   1869   else
   1870     _LIBUNWIND_ABORT("unsupported arm64 register");
   1871 }
   1872 
   1873 inline const char *Registers_arm64::getRegisterName(int regNum) {
   1874   switch (regNum) {
   1875   case UNW_REG_IP:
   1876     return "pc";
   1877   case UNW_REG_SP:
   1878     return "sp";
   1879   case UNW_ARM64_X0:
   1880     return "x0";
   1881   case UNW_ARM64_X1:
   1882     return "x1";
   1883   case UNW_ARM64_X2:
   1884     return "x2";
   1885   case UNW_ARM64_X3:
   1886     return "x3";
   1887   case UNW_ARM64_X4:
   1888     return "x4";
   1889   case UNW_ARM64_X5:
   1890     return "x5";
   1891   case UNW_ARM64_X6:
   1892     return "x6";
   1893   case UNW_ARM64_X7:
   1894     return "x7";
   1895   case UNW_ARM64_X8:
   1896     return "x8";
   1897   case UNW_ARM64_X9:
   1898     return "x9";
   1899   case UNW_ARM64_X10:
   1900     return "x10";
   1901   case UNW_ARM64_X11:
   1902     return "x11";
   1903   case UNW_ARM64_X12:
   1904     return "x12";
   1905   case UNW_ARM64_X13:
   1906     return "x13";
   1907   case UNW_ARM64_X14:
   1908     return "x14";
   1909   case UNW_ARM64_X15:
   1910     return "x15";
   1911   case UNW_ARM64_X16:
   1912     return "x16";
   1913   case UNW_ARM64_X17:
   1914     return "x17";
   1915   case UNW_ARM64_X18:
   1916     return "x18";
   1917   case UNW_ARM64_X19:
   1918     return "x19";
   1919   case UNW_ARM64_X20:
   1920     return "x20";
   1921   case UNW_ARM64_X21:
   1922     return "x21";
   1923   case UNW_ARM64_X22:
   1924     return "x22";
   1925   case UNW_ARM64_X23:
   1926     return "x23";
   1927   case UNW_ARM64_X24:
   1928     return "x24";
   1929   case UNW_ARM64_X25:
   1930     return "x25";
   1931   case UNW_ARM64_X26:
   1932     return "x26";
   1933   case UNW_ARM64_X27:
   1934     return "x27";
   1935   case UNW_ARM64_X28:
   1936     return "x28";
   1937   case UNW_ARM64_X29:
   1938     return "fp";
   1939   case UNW_ARM64_X30:
   1940     return "lr";
   1941   case UNW_ARM64_X31:
   1942     return "sp";
   1943   case UNW_ARM64_D0:
   1944     return "d0";
   1945   case UNW_ARM64_D1:
   1946     return "d1";
   1947   case UNW_ARM64_D2:
   1948     return "d2";
   1949   case UNW_ARM64_D3:
   1950     return "d3";
   1951   case UNW_ARM64_D4:
   1952     return "d4";
   1953   case UNW_ARM64_D5:
   1954     return "d5";
   1955   case UNW_ARM64_D6:
   1956     return "d6";
   1957   case UNW_ARM64_D7:
   1958     return "d7";
   1959   case UNW_ARM64_D8:
   1960     return "d8";
   1961   case UNW_ARM64_D9:
   1962     return "d9";
   1963   case UNW_ARM64_D10:
   1964     return "d10";
   1965   case UNW_ARM64_D11:
   1966     return "d11";
   1967   case UNW_ARM64_D12:
   1968     return "d12";
   1969   case UNW_ARM64_D13:
   1970     return "d13";
   1971   case UNW_ARM64_D14:
   1972     return "d14";
   1973   case UNW_ARM64_D15:
   1974     return "d15";
   1975   case UNW_ARM64_D16:
   1976     return "d16";
   1977   case UNW_ARM64_D17:
   1978     return "d17";
   1979   case UNW_ARM64_D18:
   1980     return "d18";
   1981   case UNW_ARM64_D19:
   1982     return "d19";
   1983   case UNW_ARM64_D20:
   1984     return "d20";
   1985   case UNW_ARM64_D21:
   1986     return "d21";
   1987   case UNW_ARM64_D22:
   1988     return "d22";
   1989   case UNW_ARM64_D23:
   1990     return "d23";
   1991   case UNW_ARM64_D24:
   1992     return "d24";
   1993   case UNW_ARM64_D25:
   1994     return "d25";
   1995   case UNW_ARM64_D26:
   1996     return "d26";
   1997   case UNW_ARM64_D27:
   1998     return "d27";
   1999   case UNW_ARM64_D28:
   2000     return "d28";
   2001   case UNW_ARM64_D29:
   2002     return "d29";
   2003   case UNW_ARM64_D30:
   2004     return "d30";
   2005   case UNW_ARM64_D31:
   2006     return "d31";
   2007   default:
   2008     return "unknown register";
   2009   }
   2010 }
   2011 
   2012 inline bool Registers_arm64::validFloatRegister(int regNum) const {
   2013   if (regNum < UNW_ARM64_D0)
   2014     return false;
   2015   if (regNum > UNW_ARM64_D31)
   2016     return false;
   2017   return true;
   2018 }
   2019 
   2020 inline double Registers_arm64::getFloatRegister(int regNum) const {
   2021   assert(validFloatRegister(regNum));
   2022   return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
   2023 }
   2024 
   2025 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
   2026   assert(validFloatRegister(regNum));
   2027   _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
   2028 }
   2029 
   2030 inline bool Registers_arm64::validVectorRegister(int) const {
   2031   return false;
   2032 }
   2033 
   2034 inline v128 Registers_arm64::getVectorRegister(int) const {
   2035   _LIBUNWIND_ABORT("no arm64 vector register support yet");
   2036 }
   2037 
   2038 inline void Registers_arm64::setVectorRegister(int, v128) {
   2039   _LIBUNWIND_ABORT("no arm64 vector register support yet");
   2040 }
   2041 #endif // _LIBUNWIND_TARGET_AARCH64
   2042 
   2043 #if defined(_LIBUNWIND_TARGET_ARM)
   2044 /// Registers_arm holds the register state of a thread in a 32-bit arm
   2045 /// process.
   2046 ///
   2047 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
   2048 /// this uses more memory than required.
   2049 class _LIBUNWIND_HIDDEN Registers_arm {
   2050 public:
   2051   Registers_arm();
   2052   Registers_arm(const void *registers);
   2053 
   2054   bool        validRegister(int num) const;
   2055   uint32_t    getRegister(int num) const;
   2056   void        setRegister(int num, uint32_t value);
   2057   bool        validFloatRegister(int num) const;
   2058   unw_fpreg_t getFloatRegister(int num);
   2059   void        setFloatRegister(int num, unw_fpreg_t value);
   2060   bool        validVectorRegister(int num) const;
   2061   v128        getVectorRegister(int num) const;
   2062   void        setVectorRegister(int num, v128 value);
   2063   static const char *getRegisterName(int num);
   2064   void        jumpto() {
   2065     restoreSavedFloatRegisters();
   2066     restoreCoreAndJumpTo();
   2067   }
   2068   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; }
   2069   static int  getArch() { return REGISTERS_ARM; }
   2070 
   2071   uint32_t  getSP() const         { return _registers.__sp; }
   2072   void      setSP(uint32_t value) { _registers.__sp = value; }
   2073   uint32_t  getIP() const         { return _registers.__pc; }
   2074   void      setIP(uint32_t value) { _registers.__pc = value; }
   2075 
   2076   void saveVFPAsX() {
   2077     assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
   2078     _use_X_for_vfp_save = true;
   2079   }
   2080 
   2081   void restoreSavedFloatRegisters() {
   2082     if (_saved_vfp_d0_d15) {
   2083       if (_use_X_for_vfp_save)
   2084         restoreVFPWithFLDMX(_vfp_d0_d15_pad);
   2085       else
   2086         restoreVFPWithFLDMD(_vfp_d0_d15_pad);
   2087     }
   2088     if (_saved_vfp_d16_d31)
   2089       restoreVFPv3(_vfp_d16_d31);
   2090 #if defined(__ARM_WMMX)
   2091     if (_saved_iwmmx)
   2092       restoreiWMMX(_iwmmx);
   2093     if (_saved_iwmmx_control)
   2094       restoreiWMMXControl(_iwmmx_control);
   2095 #endif
   2096   }
   2097 
   2098 private:
   2099   struct GPRs {
   2100     uint32_t __r[13]; // r0-r12
   2101     uint32_t __sp;    // Stack pointer r13
   2102     uint32_t __lr;    // Link register r14
   2103     uint32_t __pc;    // Program counter r15
   2104   };
   2105 
   2106   static void saveVFPWithFSTMD(void*);
   2107   static void saveVFPWithFSTMX(void*);
   2108   static void saveVFPv3(void*);
   2109   static void restoreVFPWithFLDMD(void*);
   2110   static void restoreVFPWithFLDMX(void*);
   2111   static void restoreVFPv3(void*);
   2112 #if defined(__ARM_WMMX)
   2113   static void saveiWMMX(void*);
   2114   static void saveiWMMXControl(uint32_t*);
   2115   static void restoreiWMMX(void*);
   2116   static void restoreiWMMXControl(uint32_t*);
   2117 #endif
   2118   void restoreCoreAndJumpTo();
   2119 
   2120   // ARM registers
   2121   GPRs _registers;
   2122 
   2123   // We save floating point registers lazily because we can't know ahead of
   2124   // time which ones are used. See EHABI #4.7.
   2125 
   2126   // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
   2127   //
   2128   // See EHABI #7.5 that explains how matching instruction sequences for load
   2129   // and store need to be used to correctly restore the exact register bits.
   2130   bool _use_X_for_vfp_save;
   2131   // Whether VFP D0-D15 are saved.
   2132   bool _saved_vfp_d0_d15;
   2133   // Whether VFPv3 D16-D31 are saved.
   2134   bool _saved_vfp_d16_d31;
   2135   // VFP registers D0-D15, + padding if saved using FSTMX
   2136   unw_fpreg_t _vfp_d0_d15_pad[17];
   2137   // VFPv3 registers D16-D31, always saved using FSTMD
   2138   unw_fpreg_t _vfp_d16_d31[16];
   2139 #if defined(__ARM_WMMX)
   2140   // Whether iWMMX data registers are saved.
   2141   bool _saved_iwmmx;
   2142   // Whether iWMMX control registers are saved.
   2143   mutable bool _saved_iwmmx_control;
   2144   // iWMMX registers
   2145   unw_fpreg_t _iwmmx[16];
   2146   // iWMMX control registers
   2147   mutable uint32_t _iwmmx_control[4];
   2148 #endif
   2149 };
   2150 
   2151 inline Registers_arm::Registers_arm(const void *registers)
   2152   : _use_X_for_vfp_save(false),
   2153     _saved_vfp_d0_d15(false),
   2154     _saved_vfp_d16_d31(false) {
   2155   static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
   2156                 "arm registers do not fit into unw_context_t");
   2157   // See unw_getcontext() note about data.
   2158   memcpy(&_registers, registers, sizeof(_registers));
   2159   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
   2160   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
   2161 #if defined(__ARM_WMMX)
   2162   _saved_iwmmx = false;
   2163   _saved_iwmmx_control = false;
   2164   memset(&_iwmmx, 0, sizeof(_iwmmx));
   2165   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
   2166 #endif
   2167 }
   2168 
   2169 inline Registers_arm::Registers_arm()
   2170   : _use_X_for_vfp_save(false),
   2171     _saved_vfp_d0_d15(false),
   2172     _saved_vfp_d16_d31(false) {
   2173   memset(&_registers, 0, sizeof(_registers));
   2174   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
   2175   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
   2176 #if defined(__ARM_WMMX)
   2177   _saved_iwmmx = false;
   2178   _saved_iwmmx_control = false;
   2179   memset(&_iwmmx, 0, sizeof(_iwmmx));
   2180   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
   2181 #endif
   2182 }
   2183 
   2184 inline bool Registers_arm::validRegister(int regNum) const {
   2185   // Returns true for all non-VFP registers supported by the EHABI
   2186   // virtual register set (VRS).
   2187   if (regNum == UNW_REG_IP)
   2188     return true;
   2189 
   2190   if (regNum == UNW_REG_SP)
   2191     return true;
   2192 
   2193   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
   2194     return true;
   2195 
   2196 #if defined(__ARM_WMMX)
   2197   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
   2198     return true;
   2199 #endif
   2200 
   2201   return false;
   2202 }
   2203 
   2204 inline uint32_t Registers_arm::getRegister(int regNum) const {
   2205   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
   2206     return _registers.__sp;
   2207 
   2208   if (regNum == UNW_ARM_LR)
   2209     return _registers.__lr;
   2210 
   2211   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
   2212     return _registers.__pc;
   2213 
   2214   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
   2215     return _registers.__r[regNum];
   2216 
   2217 #if defined(__ARM_WMMX)
   2218   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
   2219     if (!_saved_iwmmx_control) {
   2220       _saved_iwmmx_control = true;
   2221       saveiWMMXControl(_iwmmx_control);
   2222     }
   2223     return _iwmmx_control[regNum - UNW_ARM_WC0];
   2224   }
   2225 #endif
   2226 
   2227   _LIBUNWIND_ABORT("unsupported arm register");
   2228 }
   2229 
   2230 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
   2231   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
   2232     _registers.__sp = value;
   2233     return;
   2234   }
   2235 
   2236   if (regNum == UNW_ARM_LR) {
   2237     _registers.__lr = value;
   2238     return;
   2239   }
   2240 
   2241   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
   2242     _registers.__pc = value;
   2243     return;
   2244   }
   2245 
   2246   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
   2247     _registers.__r[regNum] = value;
   2248     return;
   2249   }
   2250 
   2251 #if defined(__ARM_WMMX)
   2252   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
   2253     if (!_saved_iwmmx_control) {
   2254       _saved_iwmmx_control = true;
   2255       saveiWMMXControl(_iwmmx_control);
   2256     }
   2257     _iwmmx_control[regNum - UNW_ARM_WC0] = value;
   2258     return;
   2259   }
   2260 #endif
   2261 
   2262   _LIBUNWIND_ABORT("unsupported arm register");
   2263 }
   2264 
   2265 inline const char *Registers_arm::getRegisterName(int regNum) {
   2266   switch (regNum) {
   2267   case UNW_REG_IP:
   2268   case UNW_ARM_IP: // UNW_ARM_R15 is alias
   2269     return "pc";
   2270   case UNW_ARM_LR: // UNW_ARM_R14 is alias
   2271     return "lr";
   2272   case UNW_REG_SP:
   2273   case UNW_ARM_SP: // UNW_ARM_R13 is alias
   2274     return "sp";
   2275   case UNW_ARM_R0:
   2276     return "r0";
   2277   case UNW_ARM_R1:
   2278     return "r1";
   2279   case UNW_ARM_R2:
   2280     return "r2";
   2281   case UNW_ARM_R3:
   2282     return "r3";
   2283   case UNW_ARM_R4:
   2284     return "r4";
   2285   case UNW_ARM_R5:
   2286     return "r5";
   2287   case UNW_ARM_R6:
   2288     return "r6";
   2289   case UNW_ARM_R7:
   2290     return "r7";
   2291   case UNW_ARM_R8:
   2292     return "r8";
   2293   case UNW_ARM_R9:
   2294     return "r9";
   2295   case UNW_ARM_R10:
   2296     return "r10";
   2297   case UNW_ARM_R11:
   2298     return "r11";
   2299   case UNW_ARM_R12:
   2300     return "r12";
   2301   case UNW_ARM_S0:
   2302     return "s0";
   2303   case UNW_ARM_S1:
   2304     return "s1";
   2305   case UNW_ARM_S2:
   2306     return "s2";
   2307   case UNW_ARM_S3:
   2308     return "s3";
   2309   case UNW_ARM_S4:
   2310     return "s4";
   2311   case UNW_ARM_S5:
   2312     return "s5";
   2313   case UNW_ARM_S6:
   2314     return "s6";
   2315   case UNW_ARM_S7:
   2316     return "s7";
   2317   case UNW_ARM_S8:
   2318     return "s8";
   2319   case UNW_ARM_S9:
   2320     return "s9";
   2321   case UNW_ARM_S10:
   2322     return "s10";
   2323   case UNW_ARM_S11:
   2324     return "s11";
   2325   case UNW_ARM_S12:
   2326     return "s12";
   2327   case UNW_ARM_S13:
   2328     return "s13";
   2329   case UNW_ARM_S14:
   2330     return "s14";
   2331   case UNW_ARM_S15:
   2332     return "s15";
   2333   case UNW_ARM_S16:
   2334     return "s16";
   2335   case UNW_ARM_S17:
   2336     return "s17";
   2337   case UNW_ARM_S18:
   2338     return "s18";
   2339   case UNW_ARM_S19:
   2340     return "s19";
   2341   case UNW_ARM_S20:
   2342     return "s20";
   2343   case UNW_ARM_S21:
   2344     return "s21";
   2345   case UNW_ARM_S22:
   2346     return "s22";
   2347   case UNW_ARM_S23:
   2348     return "s23";
   2349   case UNW_ARM_S24:
   2350     return "s24";
   2351   case UNW_ARM_S25:
   2352     return "s25";
   2353   case UNW_ARM_S26:
   2354     return "s26";
   2355   case UNW_ARM_S27:
   2356     return "s27";
   2357   case UNW_ARM_S28:
   2358     return "s28";
   2359   case UNW_ARM_S29:
   2360     return "s29";
   2361   case UNW_ARM_S30:
   2362     return "s30";
   2363   case UNW_ARM_S31:
   2364     return "s31";
   2365   case UNW_ARM_D0:
   2366     return "d0";
   2367   case UNW_ARM_D1:
   2368     return "d1";
   2369   case UNW_ARM_D2:
   2370     return "d2";
   2371   case UNW_ARM_D3:
   2372     return "d3";
   2373   case UNW_ARM_D4:
   2374     return "d4";
   2375   case UNW_ARM_D5:
   2376     return "d5";
   2377   case UNW_ARM_D6:
   2378     return "d6";
   2379   case UNW_ARM_D7:
   2380     return "d7";
   2381   case UNW_ARM_D8:
   2382     return "d8";
   2383   case UNW_ARM_D9:
   2384     return "d9";
   2385   case UNW_ARM_D10:
   2386     return "d10";
   2387   case UNW_ARM_D11:
   2388     return "d11";
   2389   case UNW_ARM_D12:
   2390     return "d12";
   2391   case UNW_ARM_D13:
   2392     return "d13";
   2393   case UNW_ARM_D14:
   2394     return "d14";
   2395   case UNW_ARM_D15:
   2396     return "d15";
   2397   case UNW_ARM_D16:
   2398     return "d16";
   2399   case UNW_ARM_D17:
   2400     return "d17";
   2401   case UNW_ARM_D18:
   2402     return "d18";
   2403   case UNW_ARM_D19:
   2404     return "d19";
   2405   case UNW_ARM_D20:
   2406     return "d20";
   2407   case UNW_ARM_D21:
   2408     return "d21";
   2409   case UNW_ARM_D22:
   2410     return "d22";
   2411   case UNW_ARM_D23:
   2412     return "d23";
   2413   case UNW_ARM_D24:
   2414     return "d24";
   2415   case UNW_ARM_D25:
   2416     return "d25";
   2417   case UNW_ARM_D26:
   2418     return "d26";
   2419   case UNW_ARM_D27:
   2420     return "d27";
   2421   case UNW_ARM_D28:
   2422     return "d28";
   2423   case UNW_ARM_D29:
   2424     return "d29";
   2425   case UNW_ARM_D30:
   2426     return "d30";
   2427   case UNW_ARM_D31:
   2428     return "d31";
   2429   default:
   2430     return "unknown register";
   2431   }
   2432 }
   2433 
   2434 inline bool Registers_arm::validFloatRegister(int regNum) const {
   2435   // NOTE: Consider the intel MMX registers floating points so the
   2436   // unw_get_fpreg can be used to transmit the 64-bit data back.
   2437   return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
   2438 #if defined(__ARM_WMMX)
   2439       || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
   2440 #endif
   2441       ;
   2442 }
   2443 
   2444 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
   2445   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
   2446     if (!_saved_vfp_d0_d15) {
   2447       _saved_vfp_d0_d15 = true;
   2448       if (_use_X_for_vfp_save)
   2449         saveVFPWithFSTMX(_vfp_d0_d15_pad);
   2450       else
   2451         saveVFPWithFSTMD(_vfp_d0_d15_pad);
   2452     }
   2453     return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
   2454   }
   2455 
   2456   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
   2457     if (!_saved_vfp_d16_d31) {
   2458       _saved_vfp_d16_d31 = true;
   2459       saveVFPv3(_vfp_d16_d31);
   2460     }
   2461     return _vfp_d16_d31[regNum - UNW_ARM_D16];
   2462   }
   2463 
   2464 #if defined(__ARM_WMMX)
   2465   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
   2466     if (!_saved_iwmmx) {
   2467       _saved_iwmmx = true;
   2468       saveiWMMX(_iwmmx);
   2469     }
   2470     return _iwmmx[regNum - UNW_ARM_WR0];
   2471   }
   2472 #endif
   2473 
   2474   _LIBUNWIND_ABORT("Unknown ARM float register");
   2475 }
   2476 
   2477 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
   2478   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
   2479     if (!_saved_vfp_d0_d15) {
   2480       _saved_vfp_d0_d15 = true;
   2481       if (_use_X_for_vfp_save)
   2482         saveVFPWithFSTMX(_vfp_d0_d15_pad);
   2483       else
   2484         saveVFPWithFSTMD(_vfp_d0_d15_pad);
   2485     }
   2486     _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
   2487     return;
   2488   }
   2489 
   2490   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
   2491     if (!_saved_vfp_d16_d31) {
   2492       _saved_vfp_d16_d31 = true;
   2493       saveVFPv3(_vfp_d16_d31);
   2494     }
   2495     _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
   2496     return;
   2497   }
   2498 
   2499 #if defined(__ARM_WMMX)
   2500   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
   2501     if (!_saved_iwmmx) {
   2502       _saved_iwmmx = true;
   2503       saveiWMMX(_iwmmx);
   2504     }
   2505     _iwmmx[regNum - UNW_ARM_WR0] = value;
   2506     return;
   2507   }
   2508 #endif
   2509 
   2510   _LIBUNWIND_ABORT("Unknown ARM float register");
   2511 }
   2512 
   2513 inline bool Registers_arm::validVectorRegister(int) const {
   2514   return false;
   2515 }
   2516 
   2517 inline v128 Registers_arm::getVectorRegister(int) const {
   2518   _LIBUNWIND_ABORT("ARM vector support not implemented");
   2519 }
   2520 
   2521 inline void Registers_arm::setVectorRegister(int, v128) {
   2522   _LIBUNWIND_ABORT("ARM vector support not implemented");
   2523 }
   2524 #endif // _LIBUNWIND_TARGET_ARM
   2525 
   2526 
   2527 #if defined(_LIBUNWIND_TARGET_OR1K)
   2528 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
   2529 /// process.
   2530 class _LIBUNWIND_HIDDEN Registers_or1k {
   2531 public:
   2532   Registers_or1k();
   2533   Registers_or1k(const void *registers);
   2534 
   2535   bool        validRegister(int num) const;
   2536   uint32_t    getRegister(int num) const;
   2537   void        setRegister(int num, uint32_t value);
   2538   bool        validFloatRegister(int num) const;
   2539   double      getFloatRegister(int num) const;
   2540   void        setFloatRegister(int num, double value);
   2541   bool        validVectorRegister(int num) const;
   2542   v128        getVectorRegister(int num) const;
   2543   void        setVectorRegister(int num, v128 value);
   2544   static const char *getRegisterName(int num);
   2545   void        jumpto();
   2546   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; }
   2547   static int  getArch() { return REGISTERS_OR1K; }
   2548 
   2549   uint64_t  getSP() const         { return _registers.__r[1]; }
   2550   void      setSP(uint32_t value) { _registers.__r[1] = value; }
   2551   uint64_t  getIP() const         { return _registers.__pc; }
   2552   void      setIP(uint32_t value) { _registers.__pc = value; }
   2553 
   2554 private:
   2555   struct or1k_thread_state_t {
   2556     unsigned int __r[32]; // r0-r31
   2557     unsigned int __pc;    // Program counter
   2558     unsigned int __epcr;  // Program counter at exception
   2559   };
   2560 
   2561   or1k_thread_state_t _registers;
   2562 };
   2563 
   2564 inline Registers_or1k::Registers_or1k(const void *registers) {
   2565   static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
   2566                 "or1k registers do not fit into unw_context_t");
   2567   memcpy(&_registers, static_cast<const uint8_t *>(registers),
   2568          sizeof(_registers));
   2569 }
   2570 
   2571 inline Registers_or1k::Registers_or1k() {
   2572   memset(&_registers, 0, sizeof(_registers));
   2573 }
   2574 
   2575 inline bool Registers_or1k::validRegister(int regNum) const {
   2576   if (regNum == UNW_REG_IP)
   2577     return true;
   2578   if (regNum == UNW_REG_SP)
   2579     return true;
   2580   if (regNum < 0)
   2581     return false;
   2582   if (regNum <= UNW_OR1K_R31)
   2583     return true;
   2584   if (regNum == UNW_OR1K_EPCR)
   2585     return true;
   2586   return false;
   2587 }
   2588 
   2589 inline uint32_t Registers_or1k::getRegister(int regNum) const {
   2590   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
   2591     return _registers.__r[regNum - UNW_OR1K_R0];
   2592 
   2593   switch (regNum) {
   2594   case UNW_REG_IP:
   2595     return _registers.__pc;
   2596   case UNW_REG_SP:
   2597     return _registers.__r[1];
   2598   case UNW_OR1K_EPCR:
   2599     return _registers.__epcr;
   2600   }
   2601   _LIBUNWIND_ABORT("unsupported or1k register");
   2602 }
   2603 
   2604 inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
   2605   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
   2606     _registers.__r[regNum - UNW_OR1K_R0] = value;
   2607     return;
   2608   }
   2609 
   2610   switch (regNum) {
   2611   case UNW_REG_IP:
   2612     _registers.__pc = value;
   2613     return;
   2614   case UNW_REG_SP:
   2615     _registers.__r[1] = value;
   2616     return;
   2617   case UNW_OR1K_EPCR:
   2618     _registers.__epcr = value;
   2619     return;
   2620   }
   2621   _LIBUNWIND_ABORT("unsupported or1k register");
   2622 }
   2623 
   2624 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
   2625   return false;
   2626 }
   2627 
   2628 inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
   2629   _LIBUNWIND_ABORT("or1k float support not implemented");
   2630 }
   2631 
   2632 inline void Registers_or1k::setFloatRegister(int /* regNum */,
   2633                                              double /* value */) {
   2634   _LIBUNWIND_ABORT("or1k float support not implemented");
   2635 }
   2636 
   2637 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
   2638   return false;
   2639 }
   2640 
   2641 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
   2642   _LIBUNWIND_ABORT("or1k vector support not implemented");
   2643 }
   2644 
   2645 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
   2646   _LIBUNWIND_ABORT("or1k vector support not implemented");
   2647 }
   2648 
   2649 inline const char *Registers_or1k::getRegisterName(int regNum) {
   2650   switch (regNum) {
   2651   case UNW_OR1K_R0:
   2652     return "r0";
   2653   case UNW_OR1K_R1:
   2654     return "r1";
   2655   case UNW_OR1K_R2:
   2656     return "r2";
   2657   case UNW_OR1K_R3:
   2658     return "r3";
   2659   case UNW_OR1K_R4:
   2660     return "r4";
   2661   case UNW_OR1K_R5:
   2662     return "r5";
   2663   case UNW_OR1K_R6:
   2664     return "r6";
   2665   case UNW_OR1K_R7:
   2666     return "r7";
   2667   case UNW_OR1K_R8:
   2668     return "r8";
   2669   case UNW_OR1K_R9:
   2670     return "r9";
   2671   case UNW_OR1K_R10:
   2672     return "r10";
   2673   case UNW_OR1K_R11:
   2674     return "r11";
   2675   case UNW_OR1K_R12:
   2676     return "r12";
   2677   case UNW_OR1K_R13:
   2678     return "r13";
   2679   case UNW_OR1K_R14:
   2680     return "r14";
   2681   case UNW_OR1K_R15:
   2682     return "r15";
   2683   case UNW_OR1K_R16:
   2684     return "r16";
   2685   case UNW_OR1K_R17:
   2686     return "r17";
   2687   case UNW_OR1K_R18:
   2688     return "r18";
   2689   case UNW_OR1K_R19:
   2690     return "r19";
   2691   case UNW_OR1K_R20:
   2692     return "r20";
   2693   case UNW_OR1K_R21:
   2694     return "r21";
   2695   case UNW_OR1K_R22:
   2696     return "r22";
   2697   case UNW_OR1K_R23:
   2698     return "r23";
   2699   case UNW_OR1K_R24:
   2700     return "r24";
   2701   case UNW_OR1K_R25:
   2702     return "r25";
   2703   case UNW_OR1K_R26:
   2704     return "r26";
   2705   case UNW_OR1K_R27:
   2706     return "r27";
   2707   case UNW_OR1K_R28:
   2708     return "r28";
   2709   case UNW_OR1K_R29:
   2710     return "r29";
   2711   case UNW_OR1K_R30:
   2712     return "r30";
   2713   case UNW_OR1K_R31:
   2714     return "r31";
   2715   case UNW_OR1K_EPCR:
   2716     return "EPCR";
   2717   default:
   2718     return "unknown register";
   2719   }
   2720 
   2721 }
   2722 #endif // _LIBUNWIND_TARGET_OR1K
   2723 
   2724 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
   2725 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
   2726 /// process.
   2727 class _LIBUNWIND_HIDDEN Registers_mips_o32 {
   2728 public:
   2729   Registers_mips_o32();
   2730   Registers_mips_o32(const void *registers);
   2731 
   2732   bool        validRegister(int num) const;
   2733   uint32_t    getRegister(int num) const;
   2734   void        setRegister(int num, uint32_t value);
   2735   bool        validFloatRegister(int num) const;
   2736   double      getFloatRegister(int num) const;
   2737   void        setFloatRegister(int num, double value);
   2738   bool        validVectorRegister(int num) const;
   2739   v128        getVectorRegister(int num) const;
   2740   void        setVectorRegister(int num, v128 value);
   2741   static const char *getRegisterName(int num);
   2742   void        jumpto();
   2743   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
   2744   static int  getArch() { return REGISTERS_MIPS_O32; }
   2745 
   2746   uint32_t  getSP() const         { return _registers.__r[29]; }
   2747   void      setSP(uint32_t value) { _registers.__r[29] = value; }
   2748   uint32_t  getIP() const         { return _registers.__pc; }
   2749   void      setIP(uint32_t value) { _registers.__pc = value; }
   2750 
   2751 private:
   2752   struct mips_o32_thread_state_t {
   2753     uint32_t __r[32];
   2754     uint32_t __pc;
   2755     uint32_t __hi;
   2756     uint32_t __lo;
   2757   };
   2758 
   2759   mips_o32_thread_state_t _registers;
   2760 #ifdef __mips_hard_float
   2761   /// O32 with 32-bit floating point registers only uses half of this
   2762   /// space.  However, using the same layout for 32-bit vs 64-bit
   2763   /// floating point registers results in a single context size for
   2764   /// O32 with hard float.
   2765   uint32_t _padding;
   2766   double _floats[32];
   2767 #endif
   2768 };
   2769 
   2770 inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
   2771   static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
   2772                 "mips_o32 registers do not fit into unw_context_t");
   2773   memcpy(&_registers, static_cast<const uint8_t *>(registers),
   2774          sizeof(_registers));
   2775 }
   2776 
   2777 inline Registers_mips_o32::Registers_mips_o32() {
   2778   memset(&_registers, 0, sizeof(_registers));
   2779 }
   2780 
   2781 inline bool Registers_mips_o32::validRegister(int regNum) const {
   2782   if (regNum == UNW_REG_IP)
   2783     return true;
   2784   if (regNum == UNW_REG_SP)
   2785     return true;
   2786   if (regNum < 0)
   2787     return false;
   2788   if (regNum <= UNW_MIPS_R31)
   2789     return true;
   2790 #if __mips_isa_rev != 6
   2791   if (regNum == UNW_MIPS_HI)
   2792     return true;
   2793   if (regNum == UNW_MIPS_LO)
   2794     return true;
   2795 #endif
   2796 #if defined(__mips_hard_float) && __mips_fpr == 32
   2797   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
   2798     return true;
   2799 #endif
   2800   // FIXME: DSP accumulator registers, MSA registers
   2801   return false;
   2802 }
   2803 
   2804 inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
   2805   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
   2806     return _registers.__r[regNum - UNW_MIPS_R0];
   2807 #if defined(__mips_hard_float) && __mips_fpr == 32
   2808   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
   2809     uint32_t *p;
   2810 
   2811     if (regNum % 2 == 0)
   2812       p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
   2813     else
   2814       p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
   2815     return *p;
   2816   }
   2817 #endif
   2818 
   2819   switch (regNum) {
   2820   case UNW_REG_IP:
   2821     return _registers.__pc;
   2822   case UNW_REG_SP:
   2823     return _registers.__r[29];
   2824   case UNW_MIPS_HI:
   2825     return _registers.__hi;
   2826   case UNW_MIPS_LO:
   2827     return _registers.__lo;
   2828   }
   2829   _LIBUNWIND_ABORT("unsupported mips_o32 register");
   2830 }
   2831 
   2832 inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
   2833   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
   2834     _registers.__r[regNum - UNW_MIPS_R0] = value;
   2835     return;
   2836   }
   2837 #if defined(__mips_hard_float) && __mips_fpr == 32
   2838   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
   2839     uint32_t *p;
   2840 
   2841     if (regNum % 2 == 0)
   2842       p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
   2843     else
   2844       p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
   2845     *p = value;
   2846     return;
   2847   }
   2848 #endif
   2849 
   2850   switch (regNum) {
   2851   case UNW_REG_IP:
   2852     _registers.__pc = value;
   2853     return;
   2854   case UNW_REG_SP:
   2855     _registers.__r[29] = value;
   2856     return;
   2857   case UNW_MIPS_HI:
   2858     _registers.__hi = value;
   2859     return;
   2860   case UNW_MIPS_LO:
   2861     _registers.__lo = value;
   2862     return;
   2863   }
   2864   _LIBUNWIND_ABORT("unsupported mips_o32 register");
   2865 }
   2866 
   2867 inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
   2868 #if defined(__mips_hard_float) && __mips_fpr == 64
   2869   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
   2870     return true;
   2871 #endif
   2872   return false;
   2873 }
   2874 
   2875 inline double Registers_mips_o32::getFloatRegister(int regNum) const {
   2876 #if defined(__mips_hard_float) && __mips_fpr == 64
   2877   assert(validFloatRegister(regNum));
   2878   return _floats[regNum - UNW_MIPS_F0];
   2879 #else
   2880   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
   2881 #endif
   2882 }
   2883 
   2884 inline void Registers_mips_o32::setFloatRegister(int regNum,
   2885                                                  double value) {
   2886 #if defined(__mips_hard_float) && __mips_fpr == 64
   2887   assert(validFloatRegister(regNum));
   2888   _floats[regNum - UNW_MIPS_F0] = value;
   2889 #else
   2890   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
   2891 #endif
   2892 }
   2893 
   2894 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
   2895   return false;
   2896 }
   2897 
   2898 inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
   2899   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
   2900 }
   2901 
   2902 inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
   2903   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
   2904 }
   2905 
   2906 inline const char *Registers_mips_o32::getRegisterName(int regNum) {
   2907   switch (regNum) {
   2908   case UNW_MIPS_R0:
   2909     return "$0";
   2910   case UNW_MIPS_R1:
   2911     return "$1";
   2912   case UNW_MIPS_R2:
   2913     return "$2";
   2914   case UNW_MIPS_R3:
   2915     return "$3";
   2916   case UNW_MIPS_R4:
   2917     return "$4";
   2918   case UNW_MIPS_R5:
   2919     return "$5";
   2920   case UNW_MIPS_R6:
   2921     return "$6";
   2922   case UNW_MIPS_R7:
   2923     return "$7";
   2924   case UNW_MIPS_R8:
   2925     return "$8";
   2926   case UNW_MIPS_R9:
   2927     return "$9";
   2928   case UNW_MIPS_R10:
   2929     return "$10";
   2930   case UNW_MIPS_R11:
   2931     return "$11";
   2932   case UNW_MIPS_R12:
   2933     return "$12";
   2934   case UNW_MIPS_R13:
   2935     return "$13";
   2936   case UNW_MIPS_R14:
   2937     return "$14";
   2938   case UNW_MIPS_R15:
   2939     return "$15";
   2940   case UNW_MIPS_R16:
   2941     return "$16";
   2942   case UNW_MIPS_R17:
   2943     return "$17";
   2944   case UNW_MIPS_R18:
   2945     return "$18";
   2946   case UNW_MIPS_R19:
   2947     return "$19";
   2948   case UNW_MIPS_R20:
   2949     return "$20";
   2950   case UNW_MIPS_R21:
   2951     return "$21";
   2952   case UNW_MIPS_R22:
   2953     return "$22";
   2954   case UNW_MIPS_R23:
   2955     return "$23";
   2956   case UNW_MIPS_R24:
   2957     return "$24";
   2958   case UNW_MIPS_R25:
   2959     return "$25";
   2960   case UNW_MIPS_R26:
   2961     return "$26";
   2962   case UNW_MIPS_R27:
   2963     return "$27";
   2964   case UNW_MIPS_R28:
   2965     return "$28";
   2966   case UNW_MIPS_R29:
   2967     return "$29";
   2968   case UNW_MIPS_R30:
   2969     return "$30";
   2970   case UNW_MIPS_R31:
   2971     return "$31";
   2972   case UNW_MIPS_F0:
   2973     return "$f0";
   2974   case UNW_MIPS_F1:
   2975     return "$f1";
   2976   case UNW_MIPS_F2:
   2977     return "$f2";
   2978   case UNW_MIPS_F3:
   2979     return "$f3";
   2980   case UNW_MIPS_F4:
   2981     return "$f4";
   2982   case UNW_MIPS_F5:
   2983     return "$f5";
   2984   case UNW_MIPS_F6:
   2985     return "$f6";
   2986   case UNW_MIPS_F7:
   2987     return "$f7";
   2988   case UNW_MIPS_F8:
   2989     return "$f8";
   2990   case UNW_MIPS_F9:
   2991     return "$f9";
   2992   case UNW_MIPS_F10:
   2993     return "$f10";
   2994   case UNW_MIPS_F11:
   2995     return "$f11";
   2996   case UNW_MIPS_F12:
   2997     return "$f12";
   2998   case UNW_MIPS_F13:
   2999     return "$f13";
   3000   case UNW_MIPS_F14:
   3001     return "$f14";
   3002   case UNW_MIPS_F15:
   3003     return "$f15";
   3004   case UNW_MIPS_F16:
   3005     return "$f16";
   3006   case UNW_MIPS_F17:
   3007     return "$f17";
   3008   case UNW_MIPS_F18:
   3009     return "$f18";
   3010   case UNW_MIPS_F19:
   3011     return "$f19";
   3012   case UNW_MIPS_F20:
   3013     return "$f20";
   3014   case UNW_MIPS_F21:
   3015     return "$f21";
   3016   case UNW_MIPS_F22:
   3017     return "$f22";
   3018   case UNW_MIPS_F23:
   3019     return "$f23";
   3020   case UNW_MIPS_F24:
   3021     return "$f24";
   3022   case UNW_MIPS_F25:
   3023     return "$f25";
   3024   case UNW_MIPS_F26:
   3025     return "$f26";
   3026   case UNW_MIPS_F27:
   3027     return "$f27";
   3028   case UNW_MIPS_F28:
   3029     return "$f28";
   3030   case UNW_MIPS_F29:
   3031     return "$f29";
   3032   case UNW_MIPS_F30:
   3033     return "$f30";
   3034   case UNW_MIPS_F31:
   3035     return "$f31";
   3036   case UNW_MIPS_HI:
   3037     return "$hi";
   3038   case UNW_MIPS_LO:
   3039     return "$lo";
   3040   default:
   3041     return "unknown register";
   3042   }
   3043 }
   3044 #endif // _LIBUNWIND_TARGET_MIPS_O32
   3045 
   3046 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
   3047 /// Registers_mips_newabi holds the register state of a thread in a
   3048 /// MIPS process using NEWABI (the N32 or N64 ABIs).
   3049 class _LIBUNWIND_HIDDEN Registers_mips_newabi {
   3050 public:
   3051   Registers_mips_newabi();
   3052   Registers_mips_newabi(const void *registers);
   3053 
   3054   bool        validRegister(int num) const;
   3055   uint64_t    getRegister(int num) const;
   3056   void        setRegister(int num, uint64_t value);
   3057   bool        validFloatRegister(int num) const;
   3058   double      getFloatRegister(int num) const;
   3059   void        setFloatRegister(int num, double value);
   3060   bool        validVectorRegister(int num) const;
   3061   v128        getVectorRegister(int num) const;
   3062   void        setVectorRegister(int num, v128 value);
   3063   static const char *getRegisterName(int num);
   3064   void        jumpto();
   3065   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
   3066   static int  getArch() { return REGISTERS_MIPS_NEWABI; }
   3067 
   3068   uint64_t  getSP() const         { return _registers.__r[29]; }
   3069   void      setSP(uint64_t value) { _registers.__r[29] = value; }
   3070   uint64_t  getIP() const         { return _registers.__pc; }
   3071   void      setIP(uint64_t value) { _registers.__pc = value; }
   3072 
   3073 private:
   3074   struct mips_newabi_thread_state_t {
   3075     uint64_t __r[32];
   3076     uint64_t __pc;
   3077     uint64_t __hi;
   3078     uint64_t __lo;
   3079   };
   3080 
   3081   mips_newabi_thread_state_t _registers;
   3082 #ifdef __mips_hard_float
   3083   double _floats[32];
   3084 #endif
   3085 };
   3086 
   3087 inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {
   3088   static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),
   3089                 "mips_newabi registers do not fit into unw_context_t");
   3090   memcpy(&_registers, static_cast<const uint8_t *>(registers),
   3091          sizeof(_registers));
   3092 }
   3093 
   3094 inline Registers_mips_newabi::Registers_mips_newabi() {
   3095   memset(&_registers, 0, sizeof(_registers));
   3096 }
   3097 
   3098 inline bool Registers_mips_newabi::validRegister(int regNum) const {
   3099   if (regNum == UNW_REG_IP)
   3100     return true;
   3101   if (regNum == UNW_REG_SP)
   3102     return true;
   3103   if (regNum < 0)
   3104     return false;
   3105   if (regNum <= UNW_MIPS_R31)
   3106     return true;
   3107 #if __mips_isa_rev != 6
   3108   if (regNum == UNW_MIPS_HI)
   3109     return true;
   3110   if (regNum == UNW_MIPS_LO)
   3111     return true;
   3112 #endif
   3113   // FIXME: Hard float, DSP accumulator registers, MSA registers
   3114   return false;
   3115 }
   3116 
   3117 inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
   3118   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
   3119     return _registers.__r[regNum - UNW_MIPS_R0];
   3120 
   3121   switch (regNum) {
   3122   case UNW_REG_IP:
   3123     return _registers.__pc;
   3124   case UNW_REG_SP:
   3125     return _registers.__r[29];
   3126   case UNW_MIPS_HI:
   3127     return _registers.__hi;
   3128   case UNW_MIPS_LO:
   3129     return _registers.__lo;
   3130   }
   3131   _LIBUNWIND_ABORT("unsupported mips_newabi register");
   3132 }
   3133 
   3134 inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
   3135   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
   3136     _registers.__r[regNum - UNW_MIPS_R0] = value;
   3137     return;
   3138   }
   3139 
   3140   switch (regNum) {
   3141   case UNW_REG_IP:
   3142     _registers.__pc = value;
   3143     return;
   3144   case UNW_REG_SP:
   3145     _registers.__r[29] = value;
   3146     return;
   3147   case UNW_MIPS_HI:
   3148     _registers.__hi = value;
   3149     return;
   3150   case UNW_MIPS_LO:
   3151     _registers.__lo = value;
   3152     return;
   3153   }
   3154   _LIBUNWIND_ABORT("unsupported mips_newabi register");
   3155 }
   3156 
   3157 inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {
   3158 #ifdef __mips_hard_float
   3159   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
   3160     return true;
   3161 #endif
   3162   return false;
   3163 }
   3164 
   3165 inline double Registers_mips_newabi::getFloatRegister(int regNum) const {
   3166 #ifdef __mips_hard_float
   3167   assert(validFloatRegister(regNum));
   3168   return _floats[regNum - UNW_MIPS_F0];
   3169 #else
   3170   _LIBUNWIND_ABORT("mips_newabi float support not implemented");
   3171 #endif
   3172 }
   3173 
   3174 inline void Registers_mips_newabi::setFloatRegister(int regNum,
   3175                                                     double value) {
   3176 #ifdef __mips_hard_float
   3177   assert(validFloatRegister(regNum));
   3178   _floats[regNum - UNW_MIPS_F0] = value;
   3179 #else
   3180   _LIBUNWIND_ABORT("mips_newabi float support not implemented");
   3181 #endif
   3182 }
   3183 
   3184 inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {
   3185   return false;
   3186 }
   3187 
   3188 inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {
   3189   _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
   3190 }
   3191 
   3192 inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {
   3193   _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
   3194 }
   3195 
   3196 inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
   3197   switch (regNum) {
   3198   case UNW_MIPS_R0:
   3199     return "$0";
   3200   case UNW_MIPS_R1:
   3201     return "$1";
   3202   case UNW_MIPS_R2:
   3203     return "$2";
   3204   case UNW_MIPS_R3:
   3205     return "$3";
   3206   case UNW_MIPS_R4:
   3207     return "$4";
   3208   case UNW_MIPS_R5:
   3209     return "$5";
   3210   case UNW_MIPS_R6:
   3211     return "$6";
   3212   case UNW_MIPS_R7:
   3213     return "$7";
   3214   case UNW_MIPS_R8:
   3215     return "$8";
   3216   case UNW_MIPS_R9:
   3217     return "$9";
   3218   case UNW_MIPS_R10:
   3219     return "$10";
   3220   case UNW_MIPS_R11:
   3221     return "$11";
   3222   case UNW_MIPS_R12:
   3223     return "$12";
   3224   case UNW_MIPS_R13:
   3225     return "$13";
   3226   case UNW_MIPS_R14:
   3227     return "$14";
   3228   case UNW_MIPS_R15:
   3229     return "$15";
   3230   case UNW_MIPS_R16:
   3231     return "$16";
   3232   case UNW_MIPS_R17:
   3233     return "$17";
   3234   case UNW_MIPS_R18:
   3235     return "$18";
   3236   case UNW_MIPS_R19:
   3237     return "$19";
   3238   case UNW_MIPS_R20:
   3239     return "$20";
   3240   case UNW_MIPS_R21:
   3241     return "$21";
   3242   case UNW_MIPS_R22:
   3243     return "$22";
   3244   case UNW_MIPS_R23:
   3245     return "$23";
   3246   case UNW_MIPS_R24:
   3247     return "$24";
   3248   case UNW_MIPS_R25:
   3249     return "$25";
   3250   case UNW_MIPS_R26:
   3251     return "$26";
   3252   case UNW_MIPS_R27:
   3253     return "$27";
   3254   case UNW_MIPS_R28:
   3255     return "$28";
   3256   case UNW_MIPS_R29:
   3257     return "$29";
   3258   case UNW_MIPS_R30:
   3259     return "$30";
   3260   case UNW_MIPS_R31:
   3261     return "$31";
   3262   case UNW_MIPS_F0:
   3263     return "$f0";
   3264   case UNW_MIPS_F1:
   3265     return "$f1";
   3266   case UNW_MIPS_F2:
   3267     return "$f2";
   3268   case UNW_MIPS_F3:
   3269     return "$f3";
   3270   case UNW_MIPS_F4:
   3271     return "$f4";
   3272   case UNW_MIPS_F5:
   3273     return "$f5";
   3274   case UNW_MIPS_F6:
   3275     return "$f6";
   3276   case UNW_MIPS_F7:
   3277     return "$f7";
   3278   case UNW_MIPS_F8:
   3279     return "$f8";
   3280   case UNW_MIPS_F9:
   3281     return "$f9";
   3282   case UNW_MIPS_F10:
   3283     return "$f10";
   3284   case UNW_MIPS_F11:
   3285     return "$f11";
   3286   case UNW_MIPS_F12:
   3287     return "$f12";
   3288   case UNW_MIPS_F13:
   3289     return "$f13";
   3290   case UNW_MIPS_F14:
   3291     return "$f14";
   3292   case UNW_MIPS_F15:
   3293     return "$f15";
   3294   case UNW_MIPS_F16:
   3295     return "$f16";
   3296   case UNW_MIPS_F17:
   3297     return "$f17";
   3298   case UNW_MIPS_F18:
   3299     return "$f18";
   3300   case UNW_MIPS_F19:
   3301     return "$f19";
   3302   case UNW_MIPS_F20:
   3303     return "$f20";
   3304   case UNW_MIPS_F21:
   3305     return "$f21";
   3306   case UNW_MIPS_F22:
   3307     return "$f22";
   3308   case UNW_MIPS_F23:
   3309     return "$f23";
   3310   case UNW_MIPS_F24:
   3311     return "$f24";
   3312   case UNW_MIPS_F25:
   3313     return "$f25";
   3314   case UNW_MIPS_F26:
   3315     return "$f26";
   3316   case UNW_MIPS_F27:
   3317     return "$f27";
   3318   case UNW_MIPS_F28:
   3319     return "$f28";
   3320   case UNW_MIPS_F29:
   3321     return "$f29";
   3322   case UNW_MIPS_F30:
   3323     return "$f30";
   3324   case UNW_MIPS_F31:
   3325     return "$f31";
   3326   case UNW_MIPS_HI:
   3327     return "$hi";
   3328   case UNW_MIPS_LO:
   3329     return "$lo";
   3330   default:
   3331     return "unknown register";
   3332   }
   3333 }
   3334 #endif // _LIBUNWIND_TARGET_MIPS_NEWABI
   3335 
   3336 #if defined(_LIBUNWIND_TARGET_SPARC)
   3337 /// Registers_sparc holds the register state of a thread in a 32-bit Sparc
   3338 /// process.
   3339 class _LIBUNWIND_HIDDEN Registers_sparc {
   3340 public:
   3341   Registers_sparc();
   3342   Registers_sparc(const void *registers);
   3343 
   3344   bool        validRegister(int num) const;
   3345   uint32_t    getRegister(int num) const;
   3346   void        setRegister(int num, uint32_t value);
   3347   bool        validFloatRegister(int num) const;
   3348   double      getFloatRegister(int num) const;
   3349   void        setFloatRegister(int num, double value);
   3350   bool        validVectorRegister(int num) const;
   3351   v128        getVectorRegister(int num) const;
   3352   void        setVectorRegister(int num, v128 value);
   3353   static const char *getRegisterName(int num);
   3354   void        jumpto();
   3355   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC; }
   3356   static int  getArch() { return REGISTERS_SPARC; }
   3357 
   3358   uint64_t  getSP() const         { return _registers.__regs[UNW_SPARC_O6]; }
   3359   void      setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; }
   3360   uint64_t  getIP() const         { return _registers.__regs[UNW_SPARC_O7]; }
   3361   void      setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
   3362 
   3363 private:
   3364   struct sparc_thread_state_t {
   3365     unsigned int __regs[32];
   3366   };
   3367 
   3368   sparc_thread_state_t _registers;
   3369 };
   3370 
   3371 inline Registers_sparc::Registers_sparc(const void *registers) {
   3372   static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit),
   3373                 "sparc registers do not fit into unw_context_t");
   3374   memcpy(&_registers, static_cast<const uint8_t *>(registers),
   3375          sizeof(_registers));
   3376 }
   3377 
   3378 inline Registers_sparc::Registers_sparc() {
   3379   memset(&_registers, 0, sizeof(_registers));
   3380 }
   3381 
   3382 inline bool Registers_sparc::validRegister(int regNum) const {
   3383   if (regNum == UNW_REG_IP)
   3384     return true;
   3385   if (regNum == UNW_REG_SP)
   3386     return true;
   3387   if (regNum < 0)
   3388     return false;
   3389   if (regNum <= UNW_SPARC_I7)
   3390     return true;
   3391   return false;
   3392 }
   3393 
   3394 inline uint32_t Registers_sparc::getRegister(int regNum) const {
   3395   if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
   3396     return _registers.__regs[regNum];
   3397   }
   3398 
   3399   switch (regNum) {
   3400   case UNW_REG_IP:
   3401     return _registers.__regs[UNW_SPARC_O7];
   3402   case UNW_REG_SP:
   3403     return _registers.__regs[UNW_SPARC_O6];
   3404   }
   3405   _LIBUNWIND_ABORT("unsupported sparc register");
   3406 }
   3407 
   3408 inline void Registers_sparc::setRegister(int regNum, uint32_t value) {
   3409   if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
   3410     _registers.__regs[regNum] = value;
   3411     return;
   3412   }
   3413 
   3414   switch (regNum) {
   3415   case UNW_REG_IP:
   3416     _registers.__regs[UNW_SPARC_O7] = value;
   3417     return;
   3418   case UNW_REG_SP:
   3419     _registers.__regs[UNW_SPARC_O6] = value;
   3420     return;
   3421   }
   3422   _LIBUNWIND_ABORT("unsupported sparc register");
   3423 }
   3424 
   3425 inline bool Registers_sparc::validFloatRegister(int) const { return false; }
   3426 
   3427 inline double Registers_sparc::getFloatRegister(int) const {
   3428   _LIBUNWIND_ABORT("no Sparc float registers");
   3429 }
   3430 
   3431 inline void Registers_sparc::setFloatRegister(int, double) {
   3432   _LIBUNWIND_ABORT("no Sparc float registers");
   3433 }
   3434 
   3435 inline bool Registers_sparc::validVectorRegister(int) const { return false; }
   3436 
   3437 inline v128 Registers_sparc::getVectorRegister(int) const {
   3438   _LIBUNWIND_ABORT("no Sparc vector registers");
   3439 }
   3440 
   3441 inline void Registers_sparc::setVectorRegister(int, v128) {
   3442   _LIBUNWIND_ABORT("no Sparc vector registers");
   3443 }
   3444 
   3445 inline const char *Registers_sparc::getRegisterName(int regNum) {
   3446   switch (regNum) {
   3447   case UNW_REG_IP:
   3448     return "pc";
   3449   case UNW_SPARC_G0:
   3450     return "g0";
   3451   case UNW_SPARC_G1:
   3452     return "g1";
   3453   case UNW_SPARC_G2:
   3454     return "g2";
   3455   case UNW_SPARC_G3:
   3456     return "g3";
   3457   case UNW_SPARC_G4:
   3458     return "g4";
   3459   case UNW_SPARC_G5:
   3460     return "g5";
   3461   case UNW_SPARC_G6:
   3462     return "g6";
   3463   case UNW_SPARC_G7:
   3464     return "g7";
   3465   case UNW_SPARC_O0:
   3466     return "o0";
   3467   case UNW_SPARC_O1:
   3468     return "o1";
   3469   case UNW_SPARC_O2:
   3470     return "o2";
   3471   case UNW_SPARC_O3:
   3472     return "o3";
   3473   case UNW_SPARC_O4:
   3474     return "o4";
   3475   case UNW_SPARC_O5:
   3476     return "o5";
   3477   case UNW_REG_SP:
   3478   case UNW_SPARC_O6:
   3479     return "sp";
   3480   case UNW_SPARC_O7:
   3481     return "o7";
   3482   case UNW_SPARC_L0:
   3483     return "l0";
   3484   case UNW_SPARC_L1:
   3485     return "l1";
   3486   case UNW_SPARC_L2:
   3487     return "l2";
   3488   case UNW_SPARC_L3:
   3489     return "l3";
   3490   case UNW_SPARC_L4:
   3491     return "l4";
   3492   case UNW_SPARC_L5:
   3493     return "l5";
   3494   case UNW_SPARC_L6:
   3495     return "l6";
   3496   case UNW_SPARC_L7:
   3497     return "l7";
   3498   case UNW_SPARC_I0:
   3499     return "i0";
   3500   case UNW_SPARC_I1:
   3501     return "i1";
   3502   case UNW_SPARC_I2:
   3503     return "i2";
   3504   case UNW_SPARC_I3:
   3505     return "i3";
   3506   case UNW_SPARC_I4:
   3507     return "i4";
   3508   case UNW_SPARC_I5:
   3509     return "i5";
   3510   case UNW_SPARC_I6:
   3511     return "fp";
   3512   case UNW_SPARC_I7:
   3513     return "i7";
   3514   default:
   3515     return "unknown register";
   3516   }
   3517 }
   3518 #endif // _LIBUNWIND_TARGET_SPARC
   3519 
   3520 } // namespace libunwind
   3521 
   3522 #endif // __REGISTERS_HPP__
   3523