Home | History | Annotate | Download | only in Unwind
      1 //===----------------------------- Registers.hpp --------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //
      9 //  Models register sets for supported processors.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #ifndef __REGISTERS_HPP__
     14 #define __REGISTERS_HPP__
     15 
     16 #include <stdint.h>
     17 #include <strings.h>
     18 #include <string.h>
     19 
     20 #include "libunwind.h"
     21 #include "config.h"
     22 
     23 namespace libunwind {
     24 
     25 // For emulating 128-bit registers
     26 struct v128 { uint32_t vec[4]; };
     27 
     28 
     29 /// Registers_x86 holds the register state of a thread in a 32-bit intel
     30 /// process.
     31 class _LIBUNWIND_HIDDEN Registers_x86 {
     32 public:
     33   Registers_x86();
     34   Registers_x86(const void *registers);
     35 
     36   bool        validRegister(int num) const;
     37   uint32_t    getRegister(int num) const;
     38   void        setRegister(int num, uint32_t value);
     39   bool        validFloatRegister(int) const { return false; }
     40   double      getFloatRegister(int num) const;
     41   void        setFloatRegister(int num, double value);
     42   bool        validVectorRegister(int) const { return false; }
     43   v128        getVectorRegister(int num) const;
     44   void        setVectorRegister(int num, v128 value);
     45   const char *getRegisterName(int num);
     46   void        jumpto();
     47   static int  lastDwarfRegNum() { return 8; }
     48 
     49   uint32_t  getSP() const          { return _registers.__esp; }
     50   void      setSP(uint32_t value)  { _registers.__esp = value; }
     51   uint32_t  getIP() const          { return _registers.__eip; }
     52   void      setIP(uint32_t value)  { _registers.__eip = value; }
     53   uint32_t  getEBP() const         { return _registers.__ebp; }
     54   void      setEBP(uint32_t value) { _registers.__ebp = value; }
     55   uint32_t  getEBX() const         { return _registers.__ebx; }
     56   void      setEBX(uint32_t value) { _registers.__ebx = value; }
     57   uint32_t  getECX() const         { return _registers.__ecx; }
     58   void      setECX(uint32_t value) { _registers.__ecx = value; }
     59   uint32_t  getEDX() const         { return _registers.__edx; }
     60   void      setEDX(uint32_t value) { _registers.__edx = value; }
     61   uint32_t  getESI() const         { return _registers.__esi; }
     62   void      setESI(uint32_t value) { _registers.__esi = value; }
     63   uint32_t  getEDI() const         { return _registers.__edi; }
     64   void      setEDI(uint32_t value) { _registers.__edi = value; }
     65 
     66 private:
     67   struct GPRs {
     68     unsigned int __eax;
     69     unsigned int __ebx;
     70     unsigned int __ecx;
     71     unsigned int __edx;
     72     unsigned int __edi;
     73     unsigned int __esi;
     74     unsigned int __ebp;
     75     unsigned int __esp;
     76     unsigned int __ss;
     77     unsigned int __eflags;
     78     unsigned int __eip;
     79     unsigned int __cs;
     80     unsigned int __ds;
     81     unsigned int __es;
     82     unsigned int __fs;
     83     unsigned int __gs;
     84   };
     85 
     86   GPRs _registers;
     87 };
     88 
     89 inline Registers_x86::Registers_x86(const void *registers) {
     90   static_assert(sizeof(Registers_x86) < sizeof(unw_context_t),
     91                     "x86 registers do not fit into unw_context_t");
     92   _registers = *((GPRs *)registers);
     93 }
     94 
     95 inline Registers_x86::Registers_x86() {
     96   memset(&_registers, 0, sizeof(_registers));
     97 }
     98 
     99 inline bool Registers_x86::validRegister(int regNum) const {
    100   if (regNum == UNW_REG_IP)
    101     return true;
    102   if (regNum == UNW_REG_SP)
    103     return true;
    104   if (regNum < 0)
    105     return false;
    106   if (regNum > 7)
    107     return false;
    108   return true;
    109 }
    110 
    111 inline uint32_t Registers_x86::getRegister(int regNum) const {
    112   switch (regNum) {
    113   case UNW_REG_IP:
    114     return _registers.__eip;
    115   case UNW_REG_SP:
    116     return _registers.__esp;
    117   case UNW_X86_EAX:
    118     return _registers.__eax;
    119   case UNW_X86_ECX:
    120     return _registers.__ecx;
    121   case UNW_X86_EDX:
    122     return _registers.__edx;
    123   case UNW_X86_EBX:
    124     return _registers.__ebx;
    125   case UNW_X86_EBP:
    126     return _registers.__ebp;
    127   case UNW_X86_ESP:
    128     return _registers.__esp;
    129   case UNW_X86_ESI:
    130     return _registers.__esi;
    131   case UNW_X86_EDI:
    132     return _registers.__edi;
    133   }
    134   _LIBUNWIND_ABORT("unsupported x86 register");
    135 }
    136 
    137 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
    138   switch (regNum) {
    139   case UNW_REG_IP:
    140     _registers.__eip = value;
    141     return;
    142   case UNW_REG_SP:
    143     _registers.__esp = value;
    144     return;
    145   case UNW_X86_EAX:
    146     _registers.__eax = value;
    147     return;
    148   case UNW_X86_ECX:
    149     _registers.__ecx = value;
    150     return;
    151   case UNW_X86_EDX:
    152     _registers.__edx = value;
    153     return;
    154   case UNW_X86_EBX:
    155     _registers.__ebx = value;
    156     return;
    157   case UNW_X86_EBP:
    158     _registers.__ebp = value;
    159     return;
    160   case UNW_X86_ESP:
    161     _registers.__esp = value;
    162     return;
    163   case UNW_X86_ESI:
    164     _registers.__esi = value;
    165     return;
    166   case UNW_X86_EDI:
    167     _registers.__edi = value;
    168     return;
    169   }
    170   _LIBUNWIND_ABORT("unsupported x86 register");
    171 }
    172 
    173 inline const char *Registers_x86::getRegisterName(int regNum) {
    174   switch (regNum) {
    175   case UNW_REG_IP:
    176     return "ip";
    177   case UNW_REG_SP:
    178     return "esp";
    179   case UNW_X86_EAX:
    180     return "eax";
    181   case UNW_X86_ECX:
    182     return "ecx";
    183   case UNW_X86_EDX:
    184     return "edx";
    185   case UNW_X86_EBX:
    186     return "ebx";
    187   case UNW_X86_EBP:
    188     return "ebp";
    189   case UNW_X86_ESP:
    190     return "esp";
    191   case UNW_X86_ESI:
    192     return "esi";
    193   case UNW_X86_EDI:
    194     return "edi";
    195   default:
    196     return "unknown register";
    197   }
    198 }
    199 
    200 inline double Registers_x86::getFloatRegister(int) const {
    201   _LIBUNWIND_ABORT("no x86 float registers");
    202 }
    203 
    204 inline void Registers_x86::setFloatRegister(int, double) {
    205   _LIBUNWIND_ABORT("no x86 float registers");
    206 }
    207 
    208 inline v128 Registers_x86::getVectorRegister(int) const {
    209   _LIBUNWIND_ABORT("no x86 vector registers");
    210 }
    211 
    212 inline void Registers_x86::setVectorRegister(int, v128) {
    213   _LIBUNWIND_ABORT("no x86 vector registers");
    214 }
    215 
    216 
    217 /// Registers_x86_64  holds the register state of a thread in a 64-bit intel
    218 /// process.
    219 class _LIBUNWIND_HIDDEN Registers_x86_64 {
    220 public:
    221   Registers_x86_64();
    222   Registers_x86_64(const void *registers);
    223 
    224   bool        validRegister(int num) const;
    225   uint64_t    getRegister(int num) const;
    226   void        setRegister(int num, uint64_t value);
    227   bool        validFloatRegister(int) const { return false; }
    228   double      getFloatRegister(int num) const;
    229   void        setFloatRegister(int num, double value);
    230   bool        validVectorRegister(int) const { return false; }
    231   v128        getVectorRegister(int num) const;
    232   void        setVectorRegister(int num, v128 value);
    233   const char *getRegisterName(int num);
    234   void        jumpto();
    235   static int  lastDwarfRegNum() { return 16; }
    236 
    237   uint64_t  getSP() const          { return _registers.__rsp; }
    238   void      setSP(uint64_t value)  { _registers.__rsp = value; }
    239   uint64_t  getIP() const          { return _registers.__rip; }
    240   void      setIP(uint64_t value)  { _registers.__rip = value; }
    241   uint64_t  getRBP() const         { return _registers.__rbp; }
    242   void      setRBP(uint64_t value) { _registers.__rbp = value; }
    243   uint64_t  getRBX() const         { return _registers.__rbx; }
    244   void      setRBX(uint64_t value) { _registers.__rbx = value; }
    245   uint64_t  getR12() const         { return _registers.__r12; }
    246   void      setR12(uint64_t value) { _registers.__r12 = value; }
    247   uint64_t  getR13() const         { return _registers.__r13; }
    248   void      setR13(uint64_t value) { _registers.__r13 = value; }
    249   uint64_t  getR14() const         { return _registers.__r14; }
    250   void      setR14(uint64_t value) { _registers.__r14 = value; }
    251   uint64_t  getR15() const         { return _registers.__r15; }
    252   void      setR15(uint64_t value) { _registers.__r15 = value; }
    253 
    254 private:
    255   struct GPRs {
    256     uint64_t __rax;
    257     uint64_t __rbx;
    258     uint64_t __rcx;
    259     uint64_t __rdx;
    260     uint64_t __rdi;
    261     uint64_t __rsi;
    262     uint64_t __rbp;
    263     uint64_t __rsp;
    264     uint64_t __r8;
    265     uint64_t __r9;
    266     uint64_t __r10;
    267     uint64_t __r11;
    268     uint64_t __r12;
    269     uint64_t __r13;
    270     uint64_t __r14;
    271     uint64_t __r15;
    272     uint64_t __rip;
    273     uint64_t __rflags;
    274     uint64_t __cs;
    275     uint64_t __fs;
    276     uint64_t __gs;
    277   };
    278   GPRs _registers;
    279 };
    280 
    281 inline Registers_x86_64::Registers_x86_64(const void *registers) {
    282   static_assert(sizeof(Registers_x86_64) < sizeof(unw_context_t),
    283                     "x86_64 registers do not fit into unw_context_t");
    284   _registers = *((GPRs *)registers);
    285 }
    286 
    287 inline Registers_x86_64::Registers_x86_64() {
    288   memset(&_registers, 0, sizeof(_registers));
    289 }
    290 
    291 inline bool Registers_x86_64::validRegister(int regNum) const {
    292   if (regNum == UNW_REG_IP)
    293     return true;
    294   if (regNum == UNW_REG_SP)
    295     return true;
    296   if (regNum < 0)
    297     return false;
    298   if (regNum > 15)
    299     return false;
    300   return true;
    301 }
    302 
    303 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
    304   switch (regNum) {
    305   case UNW_REG_IP:
    306     return _registers.__rip;
    307   case UNW_REG_SP:
    308     return _registers.__rsp;
    309   case UNW_X86_64_RAX:
    310     return _registers.__rax;
    311   case UNW_X86_64_RDX:
    312     return _registers.__rdx;
    313   case UNW_X86_64_RCX:
    314     return _registers.__rcx;
    315   case UNW_X86_64_RBX:
    316     return _registers.__rbx;
    317   case UNW_X86_64_RSI:
    318     return _registers.__rsi;
    319   case UNW_X86_64_RDI:
    320     return _registers.__rdi;
    321   case UNW_X86_64_RBP:
    322     return _registers.__rbp;
    323   case UNW_X86_64_RSP:
    324     return _registers.__rsp;
    325   case UNW_X86_64_R8:
    326     return _registers.__r8;
    327   case UNW_X86_64_R9:
    328     return _registers.__r9;
    329   case UNW_X86_64_R10:
    330     return _registers.__r10;
    331   case UNW_X86_64_R11:
    332     return _registers.__r11;
    333   case UNW_X86_64_R12:
    334     return _registers.__r12;
    335   case UNW_X86_64_R13:
    336     return _registers.__r13;
    337   case UNW_X86_64_R14:
    338     return _registers.__r14;
    339   case UNW_X86_64_R15:
    340     return _registers.__r15;
    341   }
    342   _LIBUNWIND_ABORT("unsupported x86_64 register");
    343 }
    344 
    345 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
    346   switch (regNum) {
    347   case UNW_REG_IP:
    348     _registers.__rip = value;
    349     return;
    350   case UNW_REG_SP:
    351     _registers.__rsp = value;
    352     return;
    353   case UNW_X86_64_RAX:
    354     _registers.__rax = value;
    355     return;
    356   case UNW_X86_64_RDX:
    357     _registers.__rdx = value;
    358     return;
    359   case UNW_X86_64_RCX:
    360     _registers.__rcx = value;
    361     return;
    362   case UNW_X86_64_RBX:
    363     _registers.__rbx = value;
    364     return;
    365   case UNW_X86_64_RSI:
    366     _registers.__rsi = value;
    367     return;
    368   case UNW_X86_64_RDI:
    369     _registers.__rdi = value;
    370     return;
    371   case UNW_X86_64_RBP:
    372     _registers.__rbp = value;
    373     return;
    374   case UNW_X86_64_RSP:
    375     _registers.__rsp = value;
    376     return;
    377   case UNW_X86_64_R8:
    378     _registers.__r8 = value;
    379     return;
    380   case UNW_X86_64_R9:
    381     _registers.__r9 = value;
    382     return;
    383   case UNW_X86_64_R10:
    384     _registers.__r10 = value;
    385     return;
    386   case UNW_X86_64_R11:
    387     _registers.__r11 = value;
    388     return;
    389   case UNW_X86_64_R12:
    390     _registers.__r12 = value;
    391     return;
    392   case UNW_X86_64_R13:
    393     _registers.__r13 = value;
    394     return;
    395   case UNW_X86_64_R14:
    396     _registers.__r14 = value;
    397     return;
    398   case UNW_X86_64_R15:
    399     _registers.__r15 = value;
    400     return;
    401   }
    402   _LIBUNWIND_ABORT("unsupported x86_64 register");
    403 }
    404 
    405 inline const char *Registers_x86_64::getRegisterName(int regNum) {
    406   switch (regNum) {
    407   case UNW_REG_IP:
    408     return "rip";
    409   case UNW_REG_SP:
    410     return "rsp";
    411   case UNW_X86_64_RAX:
    412     return "rax";
    413   case UNW_X86_64_RDX:
    414     return "rdx";
    415   case UNW_X86_64_RCX:
    416     return "rcx";
    417   case UNW_X86_64_RBX:
    418     return "rbx";
    419   case UNW_X86_64_RSI:
    420     return "rsi";
    421   case UNW_X86_64_RDI:
    422     return "rdi";
    423   case UNW_X86_64_RBP:
    424     return "rbp";
    425   case UNW_X86_64_RSP:
    426     return "rsp";
    427   case UNW_X86_64_R8:
    428     return "r8";
    429   case UNW_X86_64_R9:
    430     return "r9";
    431   case UNW_X86_64_R10:
    432     return "r10";
    433   case UNW_X86_64_R11:
    434     return "r11";
    435   case UNW_X86_64_R12:
    436     return "r12";
    437   case UNW_X86_64_R13:
    438     return "r13";
    439   case UNW_X86_64_R14:
    440     return "r14";
    441   case UNW_X86_64_R15:
    442     return "r15";
    443   default:
    444     return "unknown register";
    445   }
    446 }
    447 
    448 inline double Registers_x86_64::getFloatRegister(int) const {
    449   _LIBUNWIND_ABORT("no x86_64 float registers");
    450 }
    451 
    452 inline void Registers_x86_64::setFloatRegister(int, double) {
    453   _LIBUNWIND_ABORT("no x86_64 float registers");
    454 }
    455 
    456 inline v128 Registers_x86_64::getVectorRegister(int) const {
    457   _LIBUNWIND_ABORT("no x86_64 vector registers");
    458 }
    459 
    460 inline void Registers_x86_64::setVectorRegister(int, v128) {
    461   _LIBUNWIND_ABORT("no x86_64 vector registers");
    462 }
    463 
    464 
    465 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
    466 /// process.
    467 class _LIBUNWIND_HIDDEN Registers_ppc {
    468 public:
    469   Registers_ppc();
    470   Registers_ppc(const void *registers);
    471 
    472   bool        validRegister(int num) const;
    473   uint32_t    getRegister(int num) const;
    474   void        setRegister(int num, uint32_t value);
    475   bool        validFloatRegister(int num) const;
    476   double      getFloatRegister(int num) const;
    477   void        setFloatRegister(int num, double value);
    478   bool        validVectorRegister(int num) const;
    479   v128        getVectorRegister(int num) const;
    480   void        setVectorRegister(int num, v128 value);
    481   const char *getRegisterName(int num);
    482   void        jumpto();
    483   static int  lastDwarfRegNum() { return 112; }
    484 
    485   uint64_t  getSP() const         { return _registers.__r1; }
    486   void      setSP(uint32_t value) { _registers.__r1 = value; }
    487   uint64_t  getIP() const         { return _registers.__srr0; }
    488   void      setIP(uint32_t value) { _registers.__srr0 = value; }
    489 
    490 private:
    491   struct ppc_thread_state_t {
    492     unsigned int __srr0; /* Instruction address register (PC) */
    493     unsigned int __srr1; /* Machine state register (supervisor) */
    494     unsigned int __r0;
    495     unsigned int __r1;
    496     unsigned int __r2;
    497     unsigned int __r3;
    498     unsigned int __r4;
    499     unsigned int __r5;
    500     unsigned int __r6;
    501     unsigned int __r7;
    502     unsigned int __r8;
    503     unsigned int __r9;
    504     unsigned int __r10;
    505     unsigned int __r11;
    506     unsigned int __r12;
    507     unsigned int __r13;
    508     unsigned int __r14;
    509     unsigned int __r15;
    510     unsigned int __r16;
    511     unsigned int __r17;
    512     unsigned int __r18;
    513     unsigned int __r19;
    514     unsigned int __r20;
    515     unsigned int __r21;
    516     unsigned int __r22;
    517     unsigned int __r23;
    518     unsigned int __r24;
    519     unsigned int __r25;
    520     unsigned int __r26;
    521     unsigned int __r27;
    522     unsigned int __r28;
    523     unsigned int __r29;
    524     unsigned int __r30;
    525     unsigned int __r31;
    526     unsigned int __cr;     /* Condition register */
    527     unsigned int __xer;    /* User's integer exception register */
    528     unsigned int __lr;     /* Link register */
    529     unsigned int __ctr;    /* Count register */
    530     unsigned int __mq;     /* MQ register (601 only) */
    531     unsigned int __vrsave; /* Vector Save Register */
    532   };
    533 
    534   struct ppc_float_state_t {
    535     double __fpregs[32];
    536 
    537     unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
    538     unsigned int __fpscr;     /* floating point status register */
    539   };
    540 
    541   ppc_thread_state_t _registers;
    542   ppc_float_state_t  _floatRegisters;
    543   v128               _vectorRegisters[32]; // offset 424
    544 };
    545 
    546 inline Registers_ppc::Registers_ppc(const void *registers) {
    547   static_assert(sizeof(Registers_ppc) < sizeof(unw_context_t),
    548                     "ppc registers do not fit into unw_context_t");
    549   _registers = *((ppc_thread_state_t *)registers);
    550   _floatRegisters = *((ppc_float_state_t *)((char *)registers + 160));
    551   memcpy(_vectorRegisters, ((char *)registers + 424), sizeof(_vectorRegisters));
    552 }
    553 
    554 inline Registers_ppc::Registers_ppc() {
    555   memset(&_registers, 0, sizeof(_registers));
    556   memset(&_floatRegisters, 0, sizeof(_floatRegisters));
    557   memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
    558 }
    559 
    560 inline bool Registers_ppc::validRegister(int regNum) const {
    561   if (regNum == UNW_REG_IP)
    562     return true;
    563   if (regNum == UNW_REG_SP)
    564     return true;
    565   if (regNum == UNW_PPC_VRSAVE)
    566     return true;
    567   if (regNum < 0)
    568     return false;
    569   if (regNum <= UNW_PPC_R31)
    570     return true;
    571   if (regNum == UNW_PPC_MQ)
    572     return true;
    573   if (regNum == UNW_PPC_LR)
    574     return true;
    575   if (regNum == UNW_PPC_CTR)
    576     return true;
    577   if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
    578     return true;
    579   return false;
    580 }
    581 
    582 inline uint32_t Registers_ppc::getRegister(int regNum) const {
    583   switch (regNum) {
    584   case UNW_REG_IP:
    585     return _registers.__srr0;
    586   case UNW_REG_SP:
    587     return _registers.__r1;
    588   case UNW_PPC_R0:
    589     return _registers.__r0;
    590   case UNW_PPC_R1:
    591     return _registers.__r1;
    592   case UNW_PPC_R2:
    593     return _registers.__r2;
    594   case UNW_PPC_R3:
    595     return _registers.__r3;
    596   case UNW_PPC_R4:
    597     return _registers.__r4;
    598   case UNW_PPC_R5:
    599     return _registers.__r5;
    600   case UNW_PPC_R6:
    601     return _registers.__r6;
    602   case UNW_PPC_R7:
    603     return _registers.__r7;
    604   case UNW_PPC_R8:
    605     return _registers.__r8;
    606   case UNW_PPC_R9:
    607     return _registers.__r9;
    608   case UNW_PPC_R10:
    609     return _registers.__r10;
    610   case UNW_PPC_R11:
    611     return _registers.__r11;
    612   case UNW_PPC_R12:
    613     return _registers.__r12;
    614   case UNW_PPC_R13:
    615     return _registers.__r13;
    616   case UNW_PPC_R14:
    617     return _registers.__r14;
    618   case UNW_PPC_R15:
    619     return _registers.__r15;
    620   case UNW_PPC_R16:
    621     return _registers.__r16;
    622   case UNW_PPC_R17:
    623     return _registers.__r17;
    624   case UNW_PPC_R18:
    625     return _registers.__r18;
    626   case UNW_PPC_R19:
    627     return _registers.__r19;
    628   case UNW_PPC_R20:
    629     return _registers.__r20;
    630   case UNW_PPC_R21:
    631     return _registers.__r21;
    632   case UNW_PPC_R22:
    633     return _registers.__r22;
    634   case UNW_PPC_R23:
    635     return _registers.__r23;
    636   case UNW_PPC_R24:
    637     return _registers.__r24;
    638   case UNW_PPC_R25:
    639     return _registers.__r25;
    640   case UNW_PPC_R26:
    641     return _registers.__r26;
    642   case UNW_PPC_R27:
    643     return _registers.__r27;
    644   case UNW_PPC_R28:
    645     return _registers.__r28;
    646   case UNW_PPC_R29:
    647     return _registers.__r29;
    648   case UNW_PPC_R30:
    649     return _registers.__r30;
    650   case UNW_PPC_R31:
    651     return _registers.__r31;
    652   case UNW_PPC_LR:
    653     return _registers.__lr;
    654   case UNW_PPC_CR0:
    655     return (_registers.__cr & 0xF0000000);
    656   case UNW_PPC_CR1:
    657     return (_registers.__cr & 0x0F000000);
    658   case UNW_PPC_CR2:
    659     return (_registers.__cr & 0x00F00000);
    660   case UNW_PPC_CR3:
    661     return (_registers.__cr & 0x000F0000);
    662   case UNW_PPC_CR4:
    663     return (_registers.__cr & 0x0000F000);
    664   case UNW_PPC_CR5:
    665     return (_registers.__cr & 0x00000F00);
    666   case UNW_PPC_CR6:
    667     return (_registers.__cr & 0x000000F0);
    668   case UNW_PPC_CR7:
    669     return (_registers.__cr & 0x0000000F);
    670   case UNW_PPC_VRSAVE:
    671     return _registers.__vrsave;
    672   }
    673   _LIBUNWIND_ABORT("unsupported ppc register");
    674 }
    675 
    676 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
    677   //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
    678   switch (regNum) {
    679   case UNW_REG_IP:
    680     _registers.__srr0 = value;
    681     return;
    682   case UNW_REG_SP:
    683     _registers.__r1 = value;
    684     return;
    685   case UNW_PPC_R0:
    686     _registers.__r0 = value;
    687     return;
    688   case UNW_PPC_R1:
    689     _registers.__r1 = value;
    690     return;
    691   case UNW_PPC_R2:
    692     _registers.__r2 = value;
    693     return;
    694   case UNW_PPC_R3:
    695     _registers.__r3 = value;
    696     return;
    697   case UNW_PPC_R4:
    698     _registers.__r4 = value;
    699     return;
    700   case UNW_PPC_R5:
    701     _registers.__r5 = value;
    702     return;
    703   case UNW_PPC_R6:
    704     _registers.__r6 = value;
    705     return;
    706   case UNW_PPC_R7:
    707     _registers.__r7 = value;
    708     return;
    709   case UNW_PPC_R8:
    710     _registers.__r8 = value;
    711     return;
    712   case UNW_PPC_R9:
    713     _registers.__r9 = value;
    714     return;
    715   case UNW_PPC_R10:
    716     _registers.__r10 = value;
    717     return;
    718   case UNW_PPC_R11:
    719     _registers.__r11 = value;
    720     return;
    721   case UNW_PPC_R12:
    722     _registers.__r12 = value;
    723     return;
    724   case UNW_PPC_R13:
    725     _registers.__r13 = value;
    726     return;
    727   case UNW_PPC_R14:
    728     _registers.__r14 = value;
    729     return;
    730   case UNW_PPC_R15:
    731     _registers.__r15 = value;
    732     return;
    733   case UNW_PPC_R16:
    734     _registers.__r16 = value;
    735     return;
    736   case UNW_PPC_R17:
    737     _registers.__r17 = value;
    738     return;
    739   case UNW_PPC_R18:
    740     _registers.__r18 = value;
    741     return;
    742   case UNW_PPC_R19:
    743     _registers.__r19 = value;
    744     return;
    745   case UNW_PPC_R20:
    746     _registers.__r20 = value;
    747     return;
    748   case UNW_PPC_R21:
    749     _registers.__r21 = value;
    750     return;
    751   case UNW_PPC_R22:
    752     _registers.__r22 = value;
    753     return;
    754   case UNW_PPC_R23:
    755     _registers.__r23 = value;
    756     return;
    757   case UNW_PPC_R24:
    758     _registers.__r24 = value;
    759     return;
    760   case UNW_PPC_R25:
    761     _registers.__r25 = value;
    762     return;
    763   case UNW_PPC_R26:
    764     _registers.__r26 = value;
    765     return;
    766   case UNW_PPC_R27:
    767     _registers.__r27 = value;
    768     return;
    769   case UNW_PPC_R28:
    770     _registers.__r28 = value;
    771     return;
    772   case UNW_PPC_R29:
    773     _registers.__r29 = value;
    774     return;
    775   case UNW_PPC_R30:
    776     _registers.__r30 = value;
    777     return;
    778   case UNW_PPC_R31:
    779     _registers.__r31 = value;
    780     return;
    781   case UNW_PPC_MQ:
    782     _registers.__mq = value;
    783     return;
    784   case UNW_PPC_LR:
    785     _registers.__lr = value;
    786     return;
    787   case UNW_PPC_CTR:
    788     _registers.__ctr = value;
    789     return;
    790   case UNW_PPC_CR0:
    791     _registers.__cr &= 0x0FFFFFFF;
    792     _registers.__cr |= (value & 0xF0000000);
    793     return;
    794   case UNW_PPC_CR1:
    795     _registers.__cr &= 0xF0FFFFFF;
    796     _registers.__cr |= (value & 0x0F000000);
    797     return;
    798   case UNW_PPC_CR2:
    799     _registers.__cr &= 0xFF0FFFFF;
    800     _registers.__cr |= (value & 0x00F00000);
    801     return;
    802   case UNW_PPC_CR3:
    803     _registers.__cr &= 0xFFF0FFFF;
    804     _registers.__cr |= (value & 0x000F0000);
    805     return;
    806   case UNW_PPC_CR4:
    807     _registers.__cr &= 0xFFFF0FFF;
    808     _registers.__cr |= (value & 0x0000F000);
    809     return;
    810   case UNW_PPC_CR5:
    811     _registers.__cr &= 0xFFFFF0FF;
    812     _registers.__cr |= (value & 0x00000F00);
    813     return;
    814   case UNW_PPC_CR6:
    815     _registers.__cr &= 0xFFFFFF0F;
    816     _registers.__cr |= (value & 0x000000F0);
    817     return;
    818   case UNW_PPC_CR7:
    819     _registers.__cr &= 0xFFFFFFF0;
    820     _registers.__cr |= (value & 0x0000000F);
    821     return;
    822   case UNW_PPC_VRSAVE:
    823     _registers.__vrsave = value;
    824     return;
    825     // not saved
    826     return;
    827   case UNW_PPC_XER:
    828     _registers.__xer = value;
    829     return;
    830   case UNW_PPC_AP:
    831   case UNW_PPC_VSCR:
    832   case UNW_PPC_SPEFSCR:
    833     // not saved
    834     return;
    835   }
    836   _LIBUNWIND_ABORT("unsupported ppc register");
    837 }
    838 
    839 inline bool Registers_ppc::validFloatRegister(int regNum) const {
    840   if (regNum < UNW_PPC_F0)
    841     return false;
    842   if (regNum > UNW_PPC_F31)
    843     return false;
    844   return true;
    845 }
    846 
    847 inline double Registers_ppc::getFloatRegister(int regNum) const {
    848   assert(validFloatRegister(regNum));
    849   return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
    850 }
    851 
    852 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
    853   assert(validFloatRegister(regNum));
    854   _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
    855 }
    856 
    857 inline bool Registers_ppc::validVectorRegister(int regNum) const {
    858   if (regNum < UNW_PPC_V0)
    859     return false;
    860   if (regNum > UNW_PPC_V31)
    861     return false;
    862   return true;
    863 }
    864 
    865 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
    866   assert(validVectorRegister(regNum));
    867   v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
    868   return result;
    869 }
    870 
    871 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
    872   assert(validVectorRegister(regNum));
    873   _vectorRegisters[regNum - UNW_PPC_V0] = value;
    874 }
    875 
    876 inline const char *Registers_ppc::getRegisterName(int regNum) {
    877   switch (regNum) {
    878   case UNW_REG_IP:
    879     return "ip";
    880   case UNW_REG_SP:
    881     return "sp";
    882   case UNW_PPC_R0:
    883     return "r0";
    884   case UNW_PPC_R1:
    885     return "r1";
    886   case UNW_PPC_R2:
    887     return "r2";
    888   case UNW_PPC_R3:
    889     return "r3";
    890   case UNW_PPC_R4:
    891     return "r4";
    892   case UNW_PPC_R5:
    893     return "r5";
    894   case UNW_PPC_R6:
    895     return "r6";
    896   case UNW_PPC_R7:
    897     return "r7";
    898   case UNW_PPC_R8:
    899     return "r8";
    900   case UNW_PPC_R9:
    901     return "r9";
    902   case UNW_PPC_R10:
    903     return "r10";
    904   case UNW_PPC_R11:
    905     return "r11";
    906   case UNW_PPC_R12:
    907     return "r12";
    908   case UNW_PPC_R13:
    909     return "r13";
    910   case UNW_PPC_R14:
    911     return "r14";
    912   case UNW_PPC_R15:
    913     return "r15";
    914   case UNW_PPC_R16:
    915     return "r16";
    916   case UNW_PPC_R17:
    917     return "r17";
    918   case UNW_PPC_R18:
    919     return "r18";
    920   case UNW_PPC_R19:
    921     return "r19";
    922   case UNW_PPC_R20:
    923     return "r20";
    924   case UNW_PPC_R21:
    925     return "r21";
    926   case UNW_PPC_R22:
    927     return "r22";
    928   case UNW_PPC_R23:
    929     return "r23";
    930   case UNW_PPC_R24:
    931     return "r24";
    932   case UNW_PPC_R25:
    933     return "r25";
    934   case UNW_PPC_R26:
    935     return "r26";
    936   case UNW_PPC_R27:
    937     return "r27";
    938   case UNW_PPC_R28:
    939     return "r28";
    940   case UNW_PPC_R29:
    941     return "r29";
    942   case UNW_PPC_R30:
    943     return "r30";
    944   case UNW_PPC_R31:
    945     return "r31";
    946   case UNW_PPC_F0:
    947     return "fp0";
    948   case UNW_PPC_F1:
    949     return "fp1";
    950   case UNW_PPC_F2:
    951     return "fp2";
    952   case UNW_PPC_F3:
    953     return "fp3";
    954   case UNW_PPC_F4:
    955     return "fp4";
    956   case UNW_PPC_F5:
    957     return "fp5";
    958   case UNW_PPC_F6:
    959     return "fp6";
    960   case UNW_PPC_F7:
    961     return "fp7";
    962   case UNW_PPC_F8:
    963     return "fp8";
    964   case UNW_PPC_F9:
    965     return "fp9";
    966   case UNW_PPC_F10:
    967     return "fp10";
    968   case UNW_PPC_F11:
    969     return "fp11";
    970   case UNW_PPC_F12:
    971     return "fp12";
    972   case UNW_PPC_F13:
    973     return "fp13";
    974   case UNW_PPC_F14:
    975     return "fp14";
    976   case UNW_PPC_F15:
    977     return "fp15";
    978   case UNW_PPC_F16:
    979     return "fp16";
    980   case UNW_PPC_F17:
    981     return "fp17";
    982   case UNW_PPC_F18:
    983     return "fp18";
    984   case UNW_PPC_F19:
    985     return "fp19";
    986   case UNW_PPC_F20:
    987     return "fp20";
    988   case UNW_PPC_F21:
    989     return "fp21";
    990   case UNW_PPC_F22:
    991     return "fp22";
    992   case UNW_PPC_F23:
    993     return "fp23";
    994   case UNW_PPC_F24:
    995     return "fp24";
    996   case UNW_PPC_F25:
    997     return "fp25";
    998   case UNW_PPC_F26:
    999     return "fp26";
   1000   case UNW_PPC_F27:
   1001     return "fp27";
   1002   case UNW_PPC_F28:
   1003     return "fp28";
   1004   case UNW_PPC_F29:
   1005     return "fp29";
   1006   case UNW_PPC_F30:
   1007     return "fp30";
   1008   case UNW_PPC_F31:
   1009     return "fp31";
   1010   case UNW_PPC_LR:
   1011     return "lr";
   1012   default:
   1013     return "unknown register";
   1014   }
   1015 
   1016 }
   1017 
   1018 
   1019 /// Registers_arm64  holds the register state of a thread in a 64-bit arm
   1020 /// process.
   1021 class _LIBUNWIND_HIDDEN Registers_arm64 {
   1022 public:
   1023   Registers_arm64();
   1024   Registers_arm64(const void *registers);
   1025 
   1026   bool        validRegister(int num) const;
   1027   uint64_t    getRegister(int num) const;
   1028   void        setRegister(int num, uint64_t value);
   1029   bool        validFloatRegister(int num) const;
   1030   double      getFloatRegister(int num) const;
   1031   void        setFloatRegister(int num, double value);
   1032   bool        validVectorRegister(int num) const;
   1033   v128        getVectorRegister(int num) const;
   1034   void        setVectorRegister(int num, v128 value);
   1035   const char *getRegisterName(int num);
   1036   void        jumpto();
   1037   static int  lastDwarfRegNum() { return 95; }
   1038 
   1039   uint64_t  getSP() const         { return _registers.__sp; }
   1040   void      setSP(uint64_t value) { _registers.__sp = value; }
   1041   uint64_t  getIP() const         { return _registers.__pc; }
   1042   void      setIP(uint64_t value) { _registers.__pc = value; }
   1043   uint64_t  getFP() const         { return _registers.__fp; }
   1044   void      setFP(uint64_t value) { _registers.__fp = value; }
   1045 
   1046 private:
   1047   struct GPRs {
   1048     uint64_t __x[29]; // x0-x28
   1049     uint64_t __fp;    // Frame pointer x29
   1050     uint64_t __lr;    // Link register x30
   1051     uint64_t __sp;    // Stack pointer x31
   1052     uint64_t __pc;    // Program counter
   1053     uint64_t padding; // 16-byte align
   1054   };
   1055 
   1056   GPRs    _registers;
   1057   double  _vectorHalfRegisters[32];
   1058   // Currently only the lower double in 128-bit vectore registers
   1059   // is perserved during unwinding.  We could define new register
   1060   // numbers (> 96) which mean whole vector registers, then this
   1061   // struct would need to change to contain whole vector registers.
   1062 };
   1063 
   1064 inline Registers_arm64::Registers_arm64(const void *registers) {
   1065   static_assert(sizeof(Registers_arm64) < sizeof(unw_context_t),
   1066                     "arm64 registers do not fit into unw_context_t");
   1067   memcpy(&_registers, registers, sizeof(_registers));
   1068   memcpy(_vectorHalfRegisters, (((char *)registers) + 0x110),
   1069          sizeof(_vectorHalfRegisters));
   1070 }
   1071 
   1072 inline Registers_arm64::Registers_arm64() {
   1073   memset(&_registers, 0, sizeof(_registers));
   1074   memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
   1075 }
   1076 
   1077 inline bool Registers_arm64::validRegister(int regNum) const {
   1078   if (regNum == UNW_REG_IP)
   1079     return true;
   1080   if (regNum == UNW_REG_SP)
   1081     return true;
   1082   if (regNum < 0)
   1083     return false;
   1084   if (regNum > 95)
   1085     return false;
   1086   if ((regNum > 31) && (regNum < 64))
   1087     return false;
   1088   return true;
   1089 }
   1090 
   1091 inline uint64_t Registers_arm64::getRegister(int regNum) const {
   1092   if (regNum == UNW_REG_IP)
   1093     return _registers.__pc;
   1094   if (regNum == UNW_REG_SP)
   1095     return _registers.__sp;
   1096   if ((regNum >= 0) && (regNum < 32))
   1097     return _registers.__x[regNum];
   1098   _LIBUNWIND_ABORT("unsupported arm64 register");
   1099 }
   1100 
   1101 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
   1102   if (regNum == UNW_REG_IP)
   1103     _registers.__pc = value;
   1104   else if (regNum == UNW_REG_SP)
   1105     _registers.__sp = value;
   1106   else if ((regNum >= 0) && (regNum < 32))
   1107     _registers.__x[regNum] = value;
   1108   else
   1109     _LIBUNWIND_ABORT("unsupported arm64 register");
   1110 }
   1111 
   1112 inline const char *Registers_arm64::getRegisterName(int regNum) {
   1113   switch (regNum) {
   1114   case UNW_REG_IP:
   1115     return "pc";
   1116   case UNW_REG_SP:
   1117     return "sp";
   1118   case UNW_ARM64_X0:
   1119     return "x0";
   1120   case UNW_ARM64_X1:
   1121     return "x1";
   1122   case UNW_ARM64_X2:
   1123     return "x2";
   1124   case UNW_ARM64_X3:
   1125     return "x3";
   1126   case UNW_ARM64_X4:
   1127     return "x4";
   1128   case UNW_ARM64_X5:
   1129     return "x5";
   1130   case UNW_ARM64_X6:
   1131     return "x6";
   1132   case UNW_ARM64_X7:
   1133     return "x7";
   1134   case UNW_ARM64_X8:
   1135     return "x8";
   1136   case UNW_ARM64_X9:
   1137     return "x9";
   1138   case UNW_ARM64_X10:
   1139     return "x10";
   1140   case UNW_ARM64_X11:
   1141     return "x11";
   1142   case UNW_ARM64_X12:
   1143     return "x12";
   1144   case UNW_ARM64_X13:
   1145     return "x13";
   1146   case UNW_ARM64_X14:
   1147     return "x14";
   1148   case UNW_ARM64_X15:
   1149     return "x15";
   1150   case UNW_ARM64_X16:
   1151     return "x16";
   1152   case UNW_ARM64_X17:
   1153     return "x17";
   1154   case UNW_ARM64_X18:
   1155     return "x18";
   1156   case UNW_ARM64_X19:
   1157     return "x19";
   1158   case UNW_ARM64_X20:
   1159     return "x20";
   1160   case UNW_ARM64_X21:
   1161     return "x21";
   1162   case UNW_ARM64_X22:
   1163     return "x22";
   1164   case UNW_ARM64_X23:
   1165     return "x23";
   1166   case UNW_ARM64_X24:
   1167     return "x24";
   1168   case UNW_ARM64_X25:
   1169     return "x25";
   1170   case UNW_ARM64_X26:
   1171     return "x26";
   1172   case UNW_ARM64_X27:
   1173     return "x27";
   1174   case UNW_ARM64_X28:
   1175     return "x28";
   1176   case UNW_ARM64_X29:
   1177     return "fp";
   1178   case UNW_ARM64_X30:
   1179     return "lr";
   1180   case UNW_ARM64_X31:
   1181     return "sp";
   1182   case UNW_ARM64_D0:
   1183     return "d0";
   1184   case UNW_ARM64_D1:
   1185     return "d1";
   1186   case UNW_ARM64_D2:
   1187     return "d2";
   1188   case UNW_ARM64_D3:
   1189     return "d3";
   1190   case UNW_ARM64_D4:
   1191     return "d4";
   1192   case UNW_ARM64_D5:
   1193     return "d5";
   1194   case UNW_ARM64_D6:
   1195     return "d6";
   1196   case UNW_ARM64_D7:
   1197     return "d7";
   1198   case UNW_ARM64_D8:
   1199     return "d8";
   1200   case UNW_ARM64_D9:
   1201     return "d9";
   1202   case UNW_ARM64_D10:
   1203     return "d10";
   1204   case UNW_ARM64_D11:
   1205     return "d11";
   1206   case UNW_ARM64_D12:
   1207     return "d12";
   1208   case UNW_ARM64_D13:
   1209     return "d13";
   1210   case UNW_ARM64_D14:
   1211     return "d14";
   1212   case UNW_ARM64_D15:
   1213     return "d15";
   1214   case UNW_ARM64_D16:
   1215     return "d16";
   1216   case UNW_ARM64_D17:
   1217     return "d17";
   1218   case UNW_ARM64_D18:
   1219     return "d18";
   1220   case UNW_ARM64_D19:
   1221     return "d19";
   1222   case UNW_ARM64_D20:
   1223     return "d20";
   1224   case UNW_ARM64_D21:
   1225     return "d21";
   1226   case UNW_ARM64_D22:
   1227     return "d22";
   1228   case UNW_ARM64_D23:
   1229     return "d23";
   1230   case UNW_ARM64_D24:
   1231     return "d24";
   1232   case UNW_ARM64_D25:
   1233     return "d25";
   1234   case UNW_ARM64_D26:
   1235     return "d26";
   1236   case UNW_ARM64_D27:
   1237     return "d27";
   1238   case UNW_ARM64_D28:
   1239     return "d28";
   1240   case UNW_ARM64_D29:
   1241     return "d29";
   1242   case UNW_ARM64_D30:
   1243     return "d30";
   1244   case UNW_ARM64_D31:
   1245     return "d31";
   1246   default:
   1247     return "unknown register";
   1248   }
   1249 }
   1250 
   1251 inline bool Registers_arm64::validFloatRegister(int regNum) const {
   1252   if (regNum < UNW_ARM64_D0)
   1253     return false;
   1254   if (regNum > UNW_ARM64_D31)
   1255     return false;
   1256   return true;
   1257 }
   1258 
   1259 inline double Registers_arm64::getFloatRegister(int regNum) const {
   1260   assert(validFloatRegister(regNum));
   1261   return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
   1262 }
   1263 
   1264 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
   1265   assert(validFloatRegister(regNum));
   1266   _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
   1267 }
   1268 
   1269 inline bool Registers_arm64::validVectorRegister(int) const {
   1270   return false;
   1271 }
   1272 
   1273 inline v128 Registers_arm64::getVectorRegister(int) const {
   1274   _LIBUNWIND_ABORT("no arm64 vector register support yet");
   1275 }
   1276 
   1277 inline void Registers_arm64::setVectorRegister(int, v128) {
   1278   _LIBUNWIND_ABORT("no arm64 vector register support yet");
   1279 }
   1280 
   1281 /// Registers_arm holds the register state of a thread in a 32-bit arm
   1282 /// process.
   1283 ///
   1284 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
   1285 /// this uses more memory than required.
   1286 class _LIBUNWIND_HIDDEN Registers_arm {
   1287 public:
   1288   Registers_arm();
   1289   Registers_arm(const void *registers);
   1290 
   1291   bool        validRegister(int num) const;
   1292   uint32_t    getRegister(int num);
   1293   void        setRegister(int num, uint32_t value);
   1294   bool        validFloatRegister(int num) const;
   1295   unw_fpreg_t getFloatRegister(int num);
   1296   void        setFloatRegister(int num, unw_fpreg_t value);
   1297   bool        validVectorRegister(int num) const;
   1298   v128        getVectorRegister(int num) const;
   1299   void        setVectorRegister(int num, v128 value);
   1300   const char *getRegisterName(int num);
   1301   void        jumpto() {
   1302     restoreSavedFloatRegisters();
   1303     restoreCoreAndJumpTo();
   1304   }
   1305 
   1306   uint32_t  getSP() const         { return _registers.__sp; }
   1307   void      setSP(uint32_t value) { _registers.__sp = value; }
   1308   uint32_t  getIP() const         { return _registers.__pc; }
   1309   void      setIP(uint32_t value) { _registers.__pc = value; }
   1310 
   1311   void saveVFPAsX() {
   1312     assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
   1313     _use_X_for_vfp_save = true;
   1314   }
   1315 
   1316   void restoreSavedFloatRegisters() {
   1317     if (_saved_vfp_d0_d15) {
   1318       if (_use_X_for_vfp_save)
   1319         restoreVFPWithFLDMX(_vfp_d0_d15_pad);
   1320       else
   1321         restoreVFPWithFLDMD(_vfp_d0_d15_pad);
   1322     }
   1323     if (_saved_vfp_d16_d31)
   1324       restoreVFPv3(_vfp_d16_d31);
   1325     if (_saved_iwmmx)
   1326       restoreiWMMX(_iwmmx);
   1327     if (_saved_iwmmx_control)
   1328       restoreiWMMXControl(_iwmmx_control);
   1329   }
   1330 
   1331 private:
   1332   struct GPRs {
   1333     uint32_t __r[13]; // r0-r12
   1334     uint32_t __sp;    // Stack pointer r13
   1335     uint32_t __lr;    // Link register r14
   1336     uint32_t __pc;    // Program counter r15
   1337   };
   1338 
   1339   static void saveVFPWithFSTMD(unw_fpreg_t*);
   1340   static void saveVFPWithFSTMX(unw_fpreg_t*);
   1341   static void saveVFPv3(unw_fpreg_t*);
   1342   static void saveiWMMX(unw_fpreg_t*);
   1343   static void saveiWMMXControl(uint32_t*);
   1344   static void restoreVFPWithFLDMD(unw_fpreg_t*);
   1345   static void restoreVFPWithFLDMX(unw_fpreg_t*);
   1346   static void restoreVFPv3(unw_fpreg_t*);
   1347   static void restoreiWMMX(unw_fpreg_t*);
   1348   static void restoreiWMMXControl(uint32_t*);
   1349   void restoreCoreAndJumpTo();
   1350 
   1351   // ARM registers
   1352   GPRs _registers;
   1353 
   1354   // We save floating point registers lazily because we can't know ahead of
   1355   // time which ones are used. See EHABI #4.7.
   1356 
   1357   // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
   1358   //
   1359   // See EHABI #7.5 that explains how matching instruction sequences for load
   1360   // and store need to be used to correctly restore the exact register bits.
   1361   bool _use_X_for_vfp_save;
   1362   // Whether VFP D0-D15 are saved.
   1363   bool _saved_vfp_d0_d15;
   1364   // Whether VFPv3 D16-D31 are saved.
   1365   bool _saved_vfp_d16_d31;
   1366   // Whether iWMMX data registers are saved.
   1367   bool _saved_iwmmx;
   1368   // Whether iWMMX control registers are saved.
   1369   bool _saved_iwmmx_control;
   1370   // VFP registers D0-D15, + padding if saved using FSTMX
   1371   unw_fpreg_t _vfp_d0_d15_pad[17];
   1372   // VFPv3 registers D16-D31, always saved using FSTMD
   1373   unw_fpreg_t _vfp_d16_d31[16];
   1374   // iWMMX registers
   1375   unw_fpreg_t _iwmmx[16];
   1376   // iWMMX control registers
   1377   uint32_t _iwmmx_control[4];
   1378 };
   1379 
   1380 inline Registers_arm::Registers_arm(const void *registers)
   1381   : _use_X_for_vfp_save(false),
   1382     _saved_vfp_d0_d15(false),
   1383     _saved_vfp_d16_d31(false),
   1384     _saved_iwmmx(false),
   1385     _saved_iwmmx_control(false) {
   1386   static_assert(sizeof(Registers_arm) < sizeof(unw_context_t),
   1387                     "arm registers do not fit into unw_context_t");
   1388   // See unw_getcontext() note about data.
   1389   memcpy(&_registers, registers, sizeof(_registers));
   1390   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
   1391   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
   1392   memset(&_iwmmx, 0, sizeof(_iwmmx));
   1393   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
   1394 }
   1395 
   1396 inline Registers_arm::Registers_arm()
   1397   : _use_X_for_vfp_save(false),
   1398     _saved_vfp_d0_d15(false),
   1399     _saved_vfp_d16_d31(false),
   1400     _saved_iwmmx(false),
   1401     _saved_iwmmx_control(false) {
   1402   memset(&_registers, 0, sizeof(_registers));
   1403   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
   1404   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
   1405   memset(&_iwmmx, 0, sizeof(_iwmmx));
   1406   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
   1407 }
   1408 
   1409 inline bool Registers_arm::validRegister(int regNum) const {
   1410   // Returns true for all non-VFP registers supported by the EHABI
   1411   // virtual register set (VRS).
   1412   if (regNum == UNW_REG_IP)
   1413     return true;
   1414   if (regNum == UNW_REG_SP)
   1415     return true;
   1416   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
   1417     return true;
   1418   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
   1419     return true;
   1420   return false;
   1421 }
   1422 
   1423 inline uint32_t Registers_arm::getRegister(int regNum) {
   1424   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
   1425     return _registers.__sp;
   1426   if (regNum == UNW_ARM_LR)
   1427     return _registers.__lr;
   1428   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
   1429     return _registers.__pc;
   1430   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
   1431     return _registers.__r[regNum];
   1432   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
   1433     if (!_saved_iwmmx_control) {
   1434       _saved_iwmmx_control = true;
   1435       saveiWMMXControl(_iwmmx_control);
   1436     }
   1437     return _iwmmx_control[regNum - UNW_ARM_WC0];
   1438   }
   1439   _LIBUNWIND_ABORT("unsupported arm register");
   1440 }
   1441 
   1442 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
   1443   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
   1444     _registers.__sp = value;
   1445   else if (regNum == UNW_ARM_LR)
   1446     _registers.__lr = value;
   1447   else if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
   1448     _registers.__pc = value;
   1449   else if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
   1450     _registers.__r[regNum] = value;
   1451   else if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
   1452     if (!_saved_iwmmx_control) {
   1453       _saved_iwmmx_control = true;
   1454       saveiWMMXControl(_iwmmx_control);
   1455     }
   1456     _iwmmx_control[regNum - UNW_ARM_WC0] = value;
   1457   } else
   1458     _LIBUNWIND_ABORT("unsupported arm register");
   1459 }
   1460 
   1461 inline const char *Registers_arm::getRegisterName(int regNum) {
   1462   switch (regNum) {
   1463   case UNW_REG_IP:
   1464   case UNW_ARM_IP: // UNW_ARM_R15 is alias
   1465     return "pc";
   1466   case UNW_ARM_LR: // UNW_ARM_R14 is alias
   1467     return "lr";
   1468   case UNW_REG_SP:
   1469   case UNW_ARM_SP: // UNW_ARM_R13 is alias
   1470     return "sp";
   1471   case UNW_ARM_R0:
   1472     return "r0";
   1473   case UNW_ARM_R1:
   1474     return "r1";
   1475   case UNW_ARM_R2:
   1476     return "r2";
   1477   case UNW_ARM_R3:
   1478     return "r3";
   1479   case UNW_ARM_R4:
   1480     return "r4";
   1481   case UNW_ARM_R5:
   1482     return "r5";
   1483   case UNW_ARM_R6:
   1484     return "r6";
   1485   case UNW_ARM_R7:
   1486     return "r7";
   1487   case UNW_ARM_R8:
   1488     return "r8";
   1489   case UNW_ARM_R9:
   1490     return "r9";
   1491   case UNW_ARM_R10:
   1492     return "r10";
   1493   case UNW_ARM_R11:
   1494     return "r11";
   1495   case UNW_ARM_R12:
   1496     return "r12";
   1497   case UNW_ARM_S0:
   1498     return "s0";
   1499   case UNW_ARM_S1:
   1500     return "s1";
   1501   case UNW_ARM_S2:
   1502     return "s2";
   1503   case UNW_ARM_S3:
   1504     return "s3";
   1505   case UNW_ARM_S4:
   1506     return "s4";
   1507   case UNW_ARM_S5:
   1508     return "s5";
   1509   case UNW_ARM_S6:
   1510     return "s6";
   1511   case UNW_ARM_S7:
   1512     return "s7";
   1513   case UNW_ARM_S8:
   1514     return "s8";
   1515   case UNW_ARM_S9:
   1516     return "s9";
   1517   case UNW_ARM_S10:
   1518     return "s10";
   1519   case UNW_ARM_S11:
   1520     return "s11";
   1521   case UNW_ARM_S12:
   1522     return "s12";
   1523   case UNW_ARM_S13:
   1524     return "s13";
   1525   case UNW_ARM_S14:
   1526     return "s14";
   1527   case UNW_ARM_S15:
   1528     return "s15";
   1529   case UNW_ARM_S16:
   1530     return "s16";
   1531   case UNW_ARM_S17:
   1532     return "s17";
   1533   case UNW_ARM_S18:
   1534     return "s18";
   1535   case UNW_ARM_S19:
   1536     return "s19";
   1537   case UNW_ARM_S20:
   1538     return "s20";
   1539   case UNW_ARM_S21:
   1540     return "s21";
   1541   case UNW_ARM_S22:
   1542     return "s22";
   1543   case UNW_ARM_S23:
   1544     return "s23";
   1545   case UNW_ARM_S24:
   1546     return "s24";
   1547   case UNW_ARM_S25:
   1548     return "s25";
   1549   case UNW_ARM_S26:
   1550     return "s26";
   1551   case UNW_ARM_S27:
   1552     return "s27";
   1553   case UNW_ARM_S28:
   1554     return "s28";
   1555   case UNW_ARM_S29:
   1556     return "s29";
   1557   case UNW_ARM_S30:
   1558     return "s30";
   1559   case UNW_ARM_S31:
   1560     return "s31";
   1561   case UNW_ARM_D0:
   1562     return "d0";
   1563   case UNW_ARM_D1:
   1564     return "d1";
   1565   case UNW_ARM_D2:
   1566     return "d2";
   1567   case UNW_ARM_D3:
   1568     return "d3";
   1569   case UNW_ARM_D4:
   1570     return "d4";
   1571   case UNW_ARM_D5:
   1572     return "d5";
   1573   case UNW_ARM_D6:
   1574     return "d6";
   1575   case UNW_ARM_D7:
   1576     return "d7";
   1577   case UNW_ARM_D8:
   1578     return "d8";
   1579   case UNW_ARM_D9:
   1580     return "d9";
   1581   case UNW_ARM_D10:
   1582     return "d10";
   1583   case UNW_ARM_D11:
   1584     return "d11";
   1585   case UNW_ARM_D12:
   1586     return "d12";
   1587   case UNW_ARM_D13:
   1588     return "d13";
   1589   case UNW_ARM_D14:
   1590     return "d14";
   1591   case UNW_ARM_D15:
   1592     return "d15";
   1593   case UNW_ARM_D16:
   1594     return "d16";
   1595   case UNW_ARM_D17:
   1596     return "d17";
   1597   case UNW_ARM_D18:
   1598     return "d18";
   1599   case UNW_ARM_D19:
   1600     return "d19";
   1601   case UNW_ARM_D20:
   1602     return "d20";
   1603   case UNW_ARM_D21:
   1604     return "d21";
   1605   case UNW_ARM_D22:
   1606     return "d22";
   1607   case UNW_ARM_D23:
   1608     return "d23";
   1609   case UNW_ARM_D24:
   1610     return "d24";
   1611   case UNW_ARM_D25:
   1612     return "d25";
   1613   case UNW_ARM_D26:
   1614     return "d26";
   1615   case UNW_ARM_D27:
   1616     return "d27";
   1617   case UNW_ARM_D28:
   1618     return "d28";
   1619   case UNW_ARM_D29:
   1620     return "d29";
   1621   case UNW_ARM_D30:
   1622     return "d30";
   1623   case UNW_ARM_D31:
   1624     return "d31";
   1625   default:
   1626     return "unknown register";
   1627   }
   1628 }
   1629 
   1630 inline bool Registers_arm::validFloatRegister(int regNum) const {
   1631   // NOTE: Consider the intel MMX registers floating points so the
   1632   // unw_get_fpreg can be used to transmit the 64-bit data back.
   1633   return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
   1634       || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15));
   1635 }
   1636 
   1637 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
   1638   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
   1639     if (!_saved_vfp_d0_d15) {
   1640       _saved_vfp_d0_d15 = true;
   1641       if (_use_X_for_vfp_save)
   1642         saveVFPWithFSTMX(_vfp_d0_d15_pad);
   1643       else
   1644         saveVFPWithFSTMD(_vfp_d0_d15_pad);
   1645     }
   1646     return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
   1647   } else if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
   1648     if (!_saved_vfp_d16_d31) {
   1649       _saved_vfp_d16_d31 = true;
   1650       saveVFPv3(_vfp_d16_d31);
   1651     }
   1652     return _vfp_d16_d31[regNum - UNW_ARM_D16];
   1653   } else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
   1654     if (!_saved_iwmmx) {
   1655       _saved_iwmmx = true;
   1656       saveiWMMX(_iwmmx);
   1657     }
   1658     return _iwmmx[regNum - UNW_ARM_WR0];
   1659   } else {
   1660     _LIBUNWIND_ABORT("Unknown ARM float register");
   1661   }
   1662 }
   1663 
   1664 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
   1665   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
   1666     if (!_saved_vfp_d0_d15) {
   1667       _saved_vfp_d0_d15 = true;
   1668       if (_use_X_for_vfp_save)
   1669         saveVFPWithFSTMX(_vfp_d0_d15_pad);
   1670       else
   1671         saveVFPWithFSTMD(_vfp_d0_d15_pad);
   1672     }
   1673     _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
   1674   } else if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
   1675     if (!_saved_vfp_d16_d31) {
   1676       _saved_vfp_d16_d31 = true;
   1677       saveVFPv3(_vfp_d16_d31);
   1678     }
   1679     _vfp_d16_d31[regNum - UNW_ARM_D0] = value;
   1680   } else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
   1681     if (!_saved_iwmmx) {
   1682       _saved_iwmmx = true;
   1683       saveiWMMX(_iwmmx);
   1684     }
   1685     _iwmmx[regNum - UNW_ARM_WR0] = value;
   1686   } else {
   1687     _LIBUNWIND_ABORT("Unknown ARM float register");
   1688   }
   1689 }
   1690 
   1691 inline bool Registers_arm::validVectorRegister(int) const {
   1692   return false;
   1693 }
   1694 
   1695 inline v128 Registers_arm::getVectorRegister(int) const {
   1696   _LIBUNWIND_ABORT("ARM vector support not implemented");
   1697 }
   1698 
   1699 inline void Registers_arm::setVectorRegister(int, v128) {
   1700   _LIBUNWIND_ABORT("ARM vector support not implemented");
   1701 }
   1702 
   1703 } // namespace libunwind
   1704 
   1705 #endif // __REGISTERS_HPP__
   1706