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