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