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