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