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