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