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:
strip_trailoptnull49   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;
fatalnull359   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:
rst_sectionnull364     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);
am__f_oknull1150   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;
result_countnull1195     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];
create_testsuite_reportnull1213 
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 > 32) && (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 || regNum == UNW_ARM64_PC)
1859     return _registers.__pc;
1860   if (regNum == UNW_REG_SP || regNum == UNW_ARM64_SP)
1861     return _registers.__sp;
1862   if (regNum == UNW_ARM64_RA_SIGN_STATE)
1863     return _registers.__ra_sign_state;
1864   if (regNum == UNW_ARM64_FP)
1865     return _registers.__fp;
1866   if (regNum == UNW_ARM64_LR)
1867     return _registers.__lr;
1868   if ((regNum >= 0) && (regNum < 29))
1869     return _registers.__x[regNum];
1870   _LIBUNWIND_ABORT("unsupported arm64 register");
1871 }
1872 
1873 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1874   if (regNum == UNW_REG_IP || regNum == UNW_ARM64_PC)
1875     _registers.__pc = value;
1876   else if (regNum == UNW_REG_SP || regNum == UNW_ARM64_SP)
1877     _registers.__sp = value;
1878   else if (regNum == UNW_ARM64_RA_SIGN_STATE)
1879     _registers.__ra_sign_state = value;
1880   else if (regNum == UNW_ARM64_FP)
1881     _registers.__fp = value;
1882   else if (regNum == UNW_ARM64_LR)
1883     _registers.__lr = value;
1884   else if ((regNum >= 0) && (regNum < 29))
1885     _registers.__x[regNum] = value;
1886   else
1887     _LIBUNWIND_ABORT("unsupported arm64 register");
1888 }
1889 
1890 inline const char *Registers_arm64::getRegisterName(int regNum) {
1891   switch (regNum) {
1892   case UNW_REG_IP:
1893     return "pc";
1894   case UNW_REG_SP:
1895     return "sp";
1896   case UNW_ARM64_X0:
1897     return "x0";
1898   case UNW_ARM64_X1:
1899     return "x1";
1900   case UNW_ARM64_X2:
1901     return "x2";
1902   case UNW_ARM64_X3:
1903     return "x3";
1904   case UNW_ARM64_X4:
1905     return "x4";
1906   case UNW_ARM64_X5:
1907     return "x5";
1908   case UNW_ARM64_X6:
1909     return "x6";
1910   case UNW_ARM64_X7:
1911     return "x7";
1912   case UNW_ARM64_X8:
1913     return "x8";
1914   case UNW_ARM64_X9:
1915     return "x9";
1916   case UNW_ARM64_X10:
1917     return "x10";
1918   case UNW_ARM64_X11:
1919     return "x11";
1920   case UNW_ARM64_X12:
1921     return "x12";
1922   case UNW_ARM64_X13:
1923     return "x13";
1924   case UNW_ARM64_X14:
1925     return "x14";
1926   case UNW_ARM64_X15:
1927     return "x15";
1928   case UNW_ARM64_X16:
1929     return "x16";
1930   case UNW_ARM64_X17:
1931     return "x17";
1932   case UNW_ARM64_X18:
1933     return "x18";
1934   case UNW_ARM64_X19:
1935     return "x19";
1936   case UNW_ARM64_X20:
1937     return "x20";
1938   case UNW_ARM64_X21:
1939     return "x21";
1940   case UNW_ARM64_X22:
1941     return "x22";
1942   case UNW_ARM64_X23:
1943     return "x23";
1944   case UNW_ARM64_X24:
1945     return "x24";
1946   case UNW_ARM64_X25:
1947     return "x25";
1948   case UNW_ARM64_X26:
1949     return "x26";
1950   case UNW_ARM64_X27:
1951     return "x27";
1952   case UNW_ARM64_X28:
1953     return "x28";
1954   case UNW_ARM64_FP:
1955     return "fp";
1956   case UNW_ARM64_LR:
1957     return "lr";
1958   case UNW_ARM64_SP:
1959     return "sp";
1960   case UNW_ARM64_PC:
1961     return "pc";
1962   case UNW_ARM64_D0:
1963     return "d0";
1964   case UNW_ARM64_D1:
1965     return "d1";
1966   case UNW_ARM64_D2:
1967     return "d2";
1968   case UNW_ARM64_D3:
1969     return "d3";
1970   case UNW_ARM64_D4:
1971     return "d4";
1972   case UNW_ARM64_D5:
1973     return "d5";
1974   case UNW_ARM64_D6:
1975     return "d6";
1976   case UNW_ARM64_D7:
1977     return "d7";
1978   case UNW_ARM64_D8:
1979     return "d8";
1980   case UNW_ARM64_D9:
1981     return "d9";
1982   case UNW_ARM64_D10:
1983     return "d10";
1984   case UNW_ARM64_D11:
1985     return "d11";
1986   case UNW_ARM64_D12:
1987     return "d12";
1988   case UNW_ARM64_D13:
1989     return "d13";
1990   case UNW_ARM64_D14:
1991     return "d14";
1992   case UNW_ARM64_D15:
1993     return "d15";
1994   case UNW_ARM64_D16:
1995     return "d16";
1996   case UNW_ARM64_D17:
1997     return "d17";
1998   case UNW_ARM64_D18:
1999     return "d18";
2000   case UNW_ARM64_D19:
2001     return "d19";
2002   case UNW_ARM64_D20:
2003     return "d20";
2004   case UNW_ARM64_D21:
2005     return "d21";
2006   case UNW_ARM64_D22:
2007     return "d22";
2008   case UNW_ARM64_D23:
2009     return "d23";
2010   case UNW_ARM64_D24:
2011     return "d24";
2012   case UNW_ARM64_D25:
2013     return "d25";
2014   case UNW_ARM64_D26:
2015     return "d26";
2016   case UNW_ARM64_D27:
2017     return "d27";
2018   case UNW_ARM64_D28:
2019     return "d28";
2020   case UNW_ARM64_D29:
2021     return "d29";
2022   case UNW_ARM64_D30:
2023     return "d30";
2024   case UNW_ARM64_D31:
2025     return "d31";
2026   default:
2027     return "unknown register";
2028   }
2029 }
2030 
2031 inline bool Registers_arm64::validFloatRegister(int regNum) const {
2032   if (regNum < UNW_ARM64_D0)
2033     return false;
2034   if (regNum > UNW_ARM64_D31)
2035     return false;
2036   return true;
2037 }
2038 
2039 inline double Registers_arm64::getFloatRegister(int regNum) const {
2040   assert(validFloatRegister(regNum));
2041   return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
2042 }
2043 
2044 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
2045   assert(validFloatRegister(regNum));
2046   _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
2047 }
2048 
2049 inline bool Registers_arm64::validVectorRegister(int) const {
2050   return false;
2051 }
2052 
2053 inline v128 Registers_arm64::getVectorRegister(int) const {
2054   _LIBUNWIND_ABORT("no arm64 vector register support yet");
2055 }
2056 
2057 inline void Registers_arm64::setVectorRegister(int, v128) {
2058   _LIBUNWIND_ABORT("no arm64 vector register support yet");
2059 }
2060 #endif // _LIBUNWIND_TARGET_AARCH64
2061 
2062 #if defined(_LIBUNWIND_TARGET_ARM)
2063 /// Registers_arm holds the register state of a thread in a 32-bit arm
2064 /// process.
2065 ///
2066 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
2067 /// this uses more memory than required.
2068 class _LIBUNWIND_HIDDEN Registers_arm {
2069 public:
2070   Registers_arm();
2071   Registers_arm(const void *registers);
2072 
2073   bool        validRegister(int num) const;
2074   uint32_t    getRegister(int num) const;
2075   void        setRegister(int num, uint32_t value);
2076   bool        validFloatRegister(int num) const;
2077   unw_fpreg_t getFloatRegister(int num);
2078   void        setFloatRegister(int num, unw_fpreg_t value);
2079   bool        validVectorRegister(int num) const;
2080   v128        getVectorRegister(int num) const;
2081   void        setVectorRegister(int num, v128 value);
2082   static const char *getRegisterName(int num);
2083   void        jumpto() {
2084     restoreSavedFloatRegisters();
2085     restoreCoreAndJumpTo();
2086   }
2087   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; }
2088   static int  getArch() { return REGISTERS_ARM; }
2089 
2090   uint32_t  getSP() const         { return _registers.__sp; }
2091   void      setSP(uint32_t value) { _registers.__sp = value; }
2092   uint32_t  getIP() const         { return _registers.__pc; }
2093   void      setIP(uint32_t value) { _registers.__pc = value; }
2094 
2095   void saveVFPAsX() {
2096     assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
2097     _use_X_for_vfp_save = true;
2098   }
2099 
2100   void restoreSavedFloatRegisters() {
2101     if (_saved_vfp_d0_d15) {
2102       if (_use_X_for_vfp_save)
2103         restoreVFPWithFLDMX(_vfp_d0_d15_pad);
2104       else
2105         restoreVFPWithFLDMD(_vfp_d0_d15_pad);
2106     }
2107     if (_saved_vfp_d16_d31)
2108       restoreVFPv3(_vfp_d16_d31);
2109 #if defined(__ARM_WMMX)
2110     if (_saved_iwmmx)
2111       restoreiWMMX(_iwmmx);
2112     if (_saved_iwmmx_control)
2113       restoreiWMMXControl(_iwmmx_control);
2114 #endif
2115   }
2116 
2117 private:
2118   struct GPRs {
2119     uint32_t __r[13]; // r0-r12
2120     uint32_t __sp;    // Stack pointer r13
2121     uint32_t __lr;    // Link register r14
2122     uint32_t __pc;    // Program counter r15
2123   };
2124 
2125   static void saveVFPWithFSTMD(void*);
2126   static void saveVFPWithFSTMX(void*);
2127   static void saveVFPv3(void*);
2128   static void restoreVFPWithFLDMD(void*);
2129   static void restoreVFPWithFLDMX(void*);
2130   static void restoreVFPv3(void*);
2131 #if defined(__ARM_WMMX)
2132   static void saveiWMMX(void*);
2133   static void saveiWMMXControl(uint32_t*);
2134   static void restoreiWMMX(void*);
2135   static void restoreiWMMXControl(uint32_t*);
2136 #endif
2137   void restoreCoreAndJumpTo();
2138 
2139   // ARM registers
2140   GPRs _registers;
2141 
2142   // We save floating point registers lazily because we can't know ahead of
2143   // time which ones are used. See EHABI #4.7.
2144 
2145   // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
2146   //
2147   // See EHABI #7.5 that explains how matching instruction sequences for load
2148   // and store need to be used to correctly restore the exact register bits.
2149   bool _use_X_for_vfp_save;
2150   // Whether VFP D0-D15 are saved.
2151   bool _saved_vfp_d0_d15;
2152   // Whether VFPv3 D16-D31 are saved.
2153   bool _saved_vfp_d16_d31;
2154   // VFP registers D0-D15, + padding if saved using FSTMX
2155   unw_fpreg_t _vfp_d0_d15_pad[17];
2156   // VFPv3 registers D16-D31, always saved using FSTMD
2157   unw_fpreg_t _vfp_d16_d31[16];
2158 #if defined(__ARM_WMMX)
2159   // Whether iWMMX data registers are saved.
2160   bool _saved_iwmmx;
2161   // Whether iWMMX control registers are saved.
2162   mutable bool _saved_iwmmx_control;
2163   // iWMMX registers
2164   unw_fpreg_t _iwmmx[16];
2165   // iWMMX control registers
2166   mutable uint32_t _iwmmx_control[4];
2167 #endif
2168 };
2169 
2170 inline Registers_arm::Registers_arm(const void *registers)
2171   : _use_X_for_vfp_save(false),
2172     _saved_vfp_d0_d15(false),
2173     _saved_vfp_d16_d31(false) {
2174   static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
2175                 "arm registers do not fit into unw_context_t");
2176   // See __unw_getcontext() note about data.
2177   memcpy(&_registers, registers, sizeof(_registers));
2178   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2179   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2180 #if defined(__ARM_WMMX)
2181   _saved_iwmmx = false;
2182   _saved_iwmmx_control = false;
2183   memset(&_iwmmx, 0, sizeof(_iwmmx));
2184   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2185 #endif
2186 }
2187 
2188 inline Registers_arm::Registers_arm()
2189   : _use_X_for_vfp_save(false),
2190     _saved_vfp_d0_d15(false),
2191     _saved_vfp_d16_d31(false) {
2192   memset(&_registers, 0, sizeof(_registers));
2193   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2194   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2195 #if defined(__ARM_WMMX)
2196   _saved_iwmmx = false;
2197   _saved_iwmmx_control = false;
2198   memset(&_iwmmx, 0, sizeof(_iwmmx));
2199   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2200 #endif
2201 }
2202 
2203 inline bool Registers_arm::validRegister(int regNum) const {
2204   // Returns true for all non-VFP registers supported by the EHABI
2205   // virtual register set (VRS).
2206   if (regNum == UNW_REG_IP)
2207     return true;
2208 
2209   if (regNum == UNW_REG_SP)
2210     return true;
2211 
2212   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
2213     return true;
2214 
2215 #if defined(__ARM_WMMX)
2216   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
2217     return true;
2218 #endif
2219 
2220   return false;
2221 }
2222 
2223 inline uint32_t Registers_arm::getRegister(int regNum) const {
2224   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
2225     return _registers.__sp;
2226 
2227   if (regNum == UNW_ARM_LR)
2228     return _registers.__lr;
2229 
2230   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
2231     return _registers.__pc;
2232 
2233   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
2234     return _registers.__r[regNum];
2235 
2236 #if defined(__ARM_WMMX)
2237   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2238     if (!_saved_iwmmx_control) {
2239       _saved_iwmmx_control = true;
2240       saveiWMMXControl(_iwmmx_control);
2241     }
2242     return _iwmmx_control[regNum - UNW_ARM_WC0];
2243   }
2244 #endif
2245 
2246   _LIBUNWIND_ABORT("unsupported arm register");
2247 }
2248 
2249 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
2250   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
2251     _registers.__sp = value;
2252     return;
2253   }
2254 
2255   if (regNum == UNW_ARM_LR) {
2256     _registers.__lr = value;
2257     return;
2258   }
2259 
2260   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
2261     _registers.__pc = value;
2262     return;
2263   }
2264 
2265   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
2266     _registers.__r[regNum] = value;
2267     return;
2268   }
2269 
2270 #if defined(__ARM_WMMX)
2271   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2272     if (!_saved_iwmmx_control) {
2273       _saved_iwmmx_control = true;
2274       saveiWMMXControl(_iwmmx_control);
2275     }
2276     _iwmmx_control[regNum - UNW_ARM_WC0] = value;
2277     return;
2278   }
2279 #endif
2280 
2281   _LIBUNWIND_ABORT("unsupported arm register");
2282 }
2283 
2284 inline const char *Registers_arm::getRegisterName(int regNum) {
2285   switch (regNum) {
2286   case UNW_REG_IP:
2287   case UNW_ARM_IP: // UNW_ARM_R15 is alias
2288     return "pc";
2289   case UNW_ARM_LR: // UNW_ARM_R14 is alias
2290     return "lr";
2291   case UNW_REG_SP:
2292   case UNW_ARM_SP: // UNW_ARM_R13 is alias
2293     return "sp";
2294   case UNW_ARM_R0:
2295     return "r0";
2296   case UNW_ARM_R1:
2297     return "r1";
2298   case UNW_ARM_R2:
2299     return "r2";
2300   case UNW_ARM_R3:
2301     return "r3";
2302   case UNW_ARM_R4:
2303     return "r4";
2304   case UNW_ARM_R5:
2305     return "r5";
2306   case UNW_ARM_R6:
2307     return "r6";
2308   case UNW_ARM_R7:
2309     return "r7";
2310   case UNW_ARM_R8:
2311     return "r8";
2312   case UNW_ARM_R9:
2313     return "r9";
2314   case UNW_ARM_R10:
2315     return "r10";
2316   case UNW_ARM_R11:
2317     return "r11";
2318   case UNW_ARM_R12:
2319     return "r12";
2320   case UNW_ARM_S0:
2321     return "s0";
2322   case UNW_ARM_S1:
2323     return "s1";
2324   case UNW_ARM_S2:
2325     return "s2";
2326   case UNW_ARM_S3:
2327     return "s3";
2328   case UNW_ARM_S4:
2329     return "s4";
2330   case UNW_ARM_S5:
2331     return "s5";
2332   case UNW_ARM_S6:
2333     return "s6";
2334   case UNW_ARM_S7:
2335     return "s7";
2336   case UNW_ARM_S8:
2337     return "s8";
2338   case UNW_ARM_S9:
2339     return "s9";
2340   case UNW_ARM_S10:
2341     return "s10";
2342   case UNW_ARM_S11:
2343     return "s11";
2344   case UNW_ARM_S12:
2345     return "s12";
2346   case UNW_ARM_S13:
2347     return "s13";
2348   case UNW_ARM_S14:
2349     return "s14";
2350   case UNW_ARM_S15:
2351     return "s15";
2352   case UNW_ARM_S16:
2353     return "s16";
2354   case UNW_ARM_S17:
2355     return "s17";
2356   case UNW_ARM_S18:
2357     return "s18";
2358   case UNW_ARM_S19:
2359     return "s19";
2360   case UNW_ARM_S20:
2361     return "s20";
2362   case UNW_ARM_S21:
2363     return "s21";
2364   case UNW_ARM_S22:
2365     return "s22";
2366   case UNW_ARM_S23:
2367     return "s23";
2368   case UNW_ARM_S24:
2369     return "s24";
2370   case UNW_ARM_S25:
2371     return "s25";
2372   case UNW_ARM_S26:
2373     return "s26";
2374   case UNW_ARM_S27:
2375     return "s27";
2376   case UNW_ARM_S28:
2377     return "s28";
2378   case UNW_ARM_S29:
2379     return "s29";
2380   case UNW_ARM_S30:
2381     return "s30";
2382   case UNW_ARM_S31:
2383     return "s31";
2384   case UNW_ARM_D0:
2385     return "d0";
2386   case UNW_ARM_D1:
2387     return "d1";
2388   case UNW_ARM_D2:
2389     return "d2";
2390   case UNW_ARM_D3:
2391     return "d3";
2392   case UNW_ARM_D4:
2393     return "d4";
2394   case UNW_ARM_D5:
2395     return "d5";
2396   case UNW_ARM_D6:
2397     return "d6";
2398   case UNW_ARM_D7:
2399     return "d7";
2400   case UNW_ARM_D8:
2401     return "d8";
2402   case UNW_ARM_D9:
2403     return "d9";
2404   case UNW_ARM_D10:
2405     return "d10";
2406   case UNW_ARM_D11:
2407     return "d11";
2408   case UNW_ARM_D12:
2409     return "d12";
2410   case UNW_ARM_D13:
2411     return "d13";
2412   case UNW_ARM_D14:
2413     return "d14";
2414   case UNW_ARM_D15:
2415     return "d15";
2416   case UNW_ARM_D16:
2417     return "d16";
2418   case UNW_ARM_D17:
2419     return "d17";
2420   case UNW_ARM_D18:
2421     return "d18";
2422   case UNW_ARM_D19:
2423     return "d19";
2424   case UNW_ARM_D20:
2425     return "d20";
2426   case UNW_ARM_D21:
2427     return "d21";
2428   case UNW_ARM_D22:
2429     return "d22";
2430   case UNW_ARM_D23:
2431     return "d23";
2432   case UNW_ARM_D24:
2433     return "d24";
2434   case UNW_ARM_D25:
2435     return "d25";
2436   case UNW_ARM_D26:
2437     return "d26";
2438   case UNW_ARM_D27:
2439     return "d27";
2440   case UNW_ARM_D28:
2441     return "d28";
2442   case UNW_ARM_D29:
2443     return "d29";
2444   case UNW_ARM_D30:
2445     return "d30";
2446   case UNW_ARM_D31:
2447     return "d31";
2448   default:
2449     return "unknown register";
2450   }
2451 }
2452 
2453 inline bool Registers_arm::validFloatRegister(int regNum) const {
2454   // NOTE: Consider the intel MMX registers floating points so the
2455   // __unw_get_fpreg can be used to transmit the 64-bit data back.
2456   return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
2457 #if defined(__ARM_WMMX)
2458       || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
2459 #endif
2460       ;
2461 }
2462 
2463 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
2464   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2465     if (!_saved_vfp_d0_d15) {
2466       _saved_vfp_d0_d15 = true;
2467       if (_use_X_for_vfp_save)
2468         saveVFPWithFSTMX(_vfp_d0_d15_pad);
2469       else
2470         saveVFPWithFSTMD(_vfp_d0_d15_pad);
2471     }
2472     return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
2473   }
2474 
2475   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2476     if (!_saved_vfp_d16_d31) {
2477       _saved_vfp_d16_d31 = true;
2478       saveVFPv3(_vfp_d16_d31);
2479     }
2480     return _vfp_d16_d31[regNum - UNW_ARM_D16];
2481   }
2482 
2483 #if defined(__ARM_WMMX)
2484   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2485     if (!_saved_iwmmx) {
2486       _saved_iwmmx = true;
2487       saveiWMMX(_iwmmx);
2488     }
2489     return _iwmmx[regNum - UNW_ARM_WR0];
2490   }
2491 #endif
2492 
2493   _LIBUNWIND_ABORT("Unknown ARM float register");
2494 }
2495 
2496 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
2497   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2498     if (!_saved_vfp_d0_d15) {
2499       _saved_vfp_d0_d15 = true;
2500       if (_use_X_for_vfp_save)
2501         saveVFPWithFSTMX(_vfp_d0_d15_pad);
2502       else
2503         saveVFPWithFSTMD(_vfp_d0_d15_pad);
2504     }
2505     _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
2506     return;
2507   }
2508 
2509   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2510     if (!_saved_vfp_d16_d31) {
2511       _saved_vfp_d16_d31 = true;
2512       saveVFPv3(_vfp_d16_d31);
2513     }
2514     _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
2515     return;
2516   }
2517 
2518 #if defined(__ARM_WMMX)
2519   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2520     if (!_saved_iwmmx) {
2521       _saved_iwmmx = true;
2522       saveiWMMX(_iwmmx);
2523     }
2524     _iwmmx[regNum - UNW_ARM_WR0] = value;
2525     return;
2526   }
2527 #endif
2528 
2529   _LIBUNWIND_ABORT("Unknown ARM float register");
2530 }
2531 
2532 inline bool Registers_arm::validVectorRegister(int) const {
2533   return false;
2534 }
2535 
2536 inline v128 Registers_arm::getVectorRegister(int) const {
2537   _LIBUNWIND_ABORT("ARM vector support not implemented");
2538 }
2539 
2540 inline void Registers_arm::setVectorRegister(int, v128) {
2541   _LIBUNWIND_ABORT("ARM vector support not implemented");
2542 }
2543 #endif // _LIBUNWIND_TARGET_ARM
2544 
2545 
2546 #if defined(_LIBUNWIND_TARGET_OR1K)
2547 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
2548 /// process.
2549 class _LIBUNWIND_HIDDEN Registers_or1k {
2550 public:
2551   Registers_or1k();
2552   Registers_or1k(const void *registers);
2553 
2554   bool        validRegister(int num) const;
2555   uint32_t    getRegister(int num) const;
2556   void        setRegister(int num, uint32_t value);
2557   bool        validFloatRegister(int num) const;
2558   double      getFloatRegister(int num) const;
2559   void        setFloatRegister(int num, double value);
2560   bool        validVectorRegister(int num) const;
2561   v128        getVectorRegister(int num) const;
2562   void        setVectorRegister(int num, v128 value);
2563   static const char *getRegisterName(int num);
2564   void        jumpto();
2565   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; }
2566   static int  getArch() { return REGISTERS_OR1K; }
2567 
2568   uint64_t  getSP() const         { return _registers.__r[1]; }
2569   void      setSP(uint32_t value) { _registers.__r[1] = value; }
2570   uint64_t  getIP() const         { return _registers.__pc; }
2571   void      setIP(uint32_t value) { _registers.__pc = value; }
2572 
2573 private:
2574   struct or1k_thread_state_t {
2575     unsigned int __r[32]; // r0-r31
2576     unsigned int __pc;    // Program counter
2577     unsigned int __epcr;  // Program counter at exception
2578   };
2579 
2580   or1k_thread_state_t _registers;
2581 };
2582 
2583 inline Registers_or1k::Registers_or1k(const void *registers) {
2584   static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
2585                 "or1k registers do not fit into unw_context_t");
2586   memcpy(&_registers, static_cast<const uint8_t *>(registers),
2587          sizeof(_registers));
2588 }
2589 
2590 inline Registers_or1k::Registers_or1k() {
2591   memset(&_registers, 0, sizeof(_registers));
2592 }
2593 
2594 inline bool Registers_or1k::validRegister(int regNum) const {
2595   if (regNum == UNW_REG_IP)
2596     return true;
2597   if (regNum == UNW_REG_SP)
2598     return true;
2599   if (regNum < 0)
2600     return false;
2601   if (regNum <= UNW_OR1K_R31)
2602     return true;
2603   if (regNum == UNW_OR1K_EPCR)
2604     return true;
2605   return false;
2606 }
2607 
2608 inline uint32_t Registers_or1k::getRegister(int regNum) const {
2609   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
2610     return _registers.__r[regNum - UNW_OR1K_R0];
2611 
2612   switch (regNum) {
2613   case UNW_REG_IP:
2614     return _registers.__pc;
2615   case UNW_REG_SP:
2616     return _registers.__r[1];
2617   case UNW_OR1K_EPCR:
2618     return _registers.__epcr;
2619   }
2620   _LIBUNWIND_ABORT("unsupported or1k register");
2621 }
2622 
2623 inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
2624   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
2625     _registers.__r[regNum - UNW_OR1K_R0] = value;
2626     return;
2627   }
2628 
2629   switch (regNum) {
2630   case UNW_REG_IP:
2631     _registers.__pc = value;
2632     return;
2633   case UNW_REG_SP:
2634     _registers.__r[1] = value;
2635     return;
2636   case UNW_OR1K_EPCR:
2637     _registers.__epcr = value;
2638     return;
2639   }
2640   _LIBUNWIND_ABORT("unsupported or1k register");
2641 }
2642 
2643 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
2644   return false;
2645 }
2646 
2647 inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
2648   _LIBUNWIND_ABORT("or1k float support not implemented");
2649 }
2650 
2651 inline void Registers_or1k::setFloatRegister(int /* regNum */,
2652                                              double /* value */) {
2653   _LIBUNWIND_ABORT("or1k float support not implemented");
2654 }
2655 
2656 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
2657   return false;
2658 }
2659 
2660 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
2661   _LIBUNWIND_ABORT("or1k vector support not implemented");
2662 }
2663 
2664 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
2665   _LIBUNWIND_ABORT("or1k vector support not implemented");
2666 }
2667 
2668 inline const char *Registers_or1k::getRegisterName(int regNum) {
2669   switch (regNum) {
2670   case UNW_OR1K_R0:
2671     return "r0";
2672   case UNW_OR1K_R1:
2673     return "r1";
2674   case UNW_OR1K_R2:
2675     return "r2";
2676   case UNW_OR1K_R3:
2677     return "r3";
2678   case UNW_OR1K_R4:
2679     return "r4";
2680   case UNW_OR1K_R5:
2681     return "r5";
2682   case UNW_OR1K_R6:
2683     return "r6";
2684   case UNW_OR1K_R7:
2685     return "r7";
2686   case UNW_OR1K_R8:
2687     return "r8";
2688   case UNW_OR1K_R9:
2689     return "r9";
2690   case UNW_OR1K_R10:
2691     return "r10";
2692   case UNW_OR1K_R11:
2693     return "r11";
2694   case UNW_OR1K_R12:
2695     return "r12";
2696   case UNW_OR1K_R13:
2697     return "r13";
2698   case UNW_OR1K_R14:
2699     return "r14";
2700   case UNW_OR1K_R15:
2701     return "r15";
2702   case UNW_OR1K_R16:
2703     return "r16";
2704   case UNW_OR1K_R17:
2705     return "r17";
2706   case UNW_OR1K_R18:
2707     return "r18";
2708   case UNW_OR1K_R19:
2709     return "r19";
2710   case UNW_OR1K_R20:
2711     return "r20";
2712   case UNW_OR1K_R21:
2713     return "r21";
2714   case UNW_OR1K_R22:
2715     return "r22";
2716   case UNW_OR1K_R23:
2717     return "r23";
2718   case UNW_OR1K_R24:
2719     return "r24";
2720   case UNW_OR1K_R25:
2721     return "r25";
2722   case UNW_OR1K_R26:
2723     return "r26";
2724   case UNW_OR1K_R27:
2725     return "r27";
2726   case UNW_OR1K_R28:
2727     return "r28";
2728   case UNW_OR1K_R29:
2729     return "r29";
2730   case UNW_OR1K_R30:
2731     return "r30";
2732   case UNW_OR1K_R31:
2733     return "r31";
2734   case UNW_OR1K_EPCR:
2735     return "EPCR";
2736   default:
2737     return "unknown register";
2738   }
2739 
2740 }
2741 #endif // _LIBUNWIND_TARGET_OR1K
2742 
2743 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
2744 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
2745 /// process.
2746 class _LIBUNWIND_HIDDEN Registers_mips_o32 {
2747 public:
2748   Registers_mips_o32();
2749   Registers_mips_o32(const void *registers);
2750 
2751   bool        validRegister(int num) const;
2752   uint32_t    getRegister(int num) const;
2753   void        setRegister(int num, uint32_t value);
2754   bool        validFloatRegister(int num) const;
2755   double      getFloatRegister(int num) const;
2756   void        setFloatRegister(int num, double value);
2757   bool        validVectorRegister(int num) const;
2758   v128        getVectorRegister(int num) const;
2759   void        setVectorRegister(int num, v128 value);
2760   static const char *getRegisterName(int num);
2761   void        jumpto();
2762   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
2763   static int  getArch() { return REGISTERS_MIPS_O32; }
2764 
2765   uint32_t  getSP() const         { return _registers.__r[29]; }
2766   void      setSP(uint32_t value) { _registers.__r[29] = value; }
2767   uint32_t  getIP() const         { return _registers.__pc; }
2768   void      setIP(uint32_t value) { _registers.__pc = value; }
2769 
2770 private:
2771   struct mips_o32_thread_state_t {
2772     uint32_t __r[32];
2773     uint32_t __pc;
2774     uint32_t __hi;
2775     uint32_t __lo;
2776   };
2777 
2778   mips_o32_thread_state_t _registers;
2779 #ifdef __mips_hard_float
2780   /// O32 with 32-bit floating point registers only uses half of this
2781   /// space.  However, using the same layout for 32-bit vs 64-bit
2782   /// floating point registers results in a single context size for
2783   /// O32 with hard float.
2784   uint32_t _padding;
2785   double _floats[32];
2786 #endif
2787 };
2788 
2789 inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
2790   static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
2791                 "mips_o32 registers do not fit into unw_context_t");
2792   memcpy(&_registers, static_cast<const uint8_t *>(registers),
2793          sizeof(_registers));
2794 }
2795 
2796 inline Registers_mips_o32::Registers_mips_o32() {
2797   memset(&_registers, 0, sizeof(_registers));
2798 }
2799 
2800 inline bool Registers_mips_o32::validRegister(int regNum) const {
2801   if (regNum == UNW_REG_IP)
2802     return true;
2803   if (regNum == UNW_REG_SP)
2804     return true;
2805   if (regNum < 0)
2806     return false;
2807   if (regNum <= UNW_MIPS_R31)
2808     return true;
2809 #if __mips_isa_rev != 6
2810   if (regNum == UNW_MIPS_HI)
2811     return true;
2812   if (regNum == UNW_MIPS_LO)
2813     return true;
2814 #endif
2815 #if defined(__mips_hard_float) && __mips_fpr == 32
2816   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2817     return true;
2818 #endif
2819   // FIXME: DSP accumulator registers, MSA registers
2820   return false;
2821 }
2822 
2823 inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
2824   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
2825     return _registers.__r[regNum - UNW_MIPS_R0];
2826 #if defined(__mips_hard_float) && __mips_fpr == 32
2827   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2828     uint32_t *p;
2829 
2830     if (regNum % 2 == 0)
2831       p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2832     else
2833       p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2834     return *p;
2835   }
2836 #endif
2837 
2838   switch (regNum) {
2839   case UNW_REG_IP:
2840     return _registers.__pc;
2841   case UNW_REG_SP:
2842     return _registers.__r[29];
2843   case UNW_MIPS_HI:
2844     return _registers.__hi;
2845   case UNW_MIPS_LO:
2846     return _registers.__lo;
2847   }
2848   _LIBUNWIND_ABORT("unsupported mips_o32 register");
2849 }
2850 
2851 inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
2852   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
2853     _registers.__r[regNum - UNW_MIPS_R0] = value;
2854     return;
2855   }
2856 #if defined(__mips_hard_float) && __mips_fpr == 32
2857   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2858     uint32_t *p;
2859 
2860     if (regNum % 2 == 0)
2861       p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2862     else
2863       p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2864     *p = value;
2865     return;
2866   }
2867 #endif
2868 
2869   switch (regNum) {
2870   case UNW_REG_IP:
2871     _registers.__pc = value;
2872     return;
2873   case UNW_REG_SP:
2874     _registers.__r[29] = value;
2875     return;
2876   case UNW_MIPS_HI:
2877     _registers.__hi = value;
2878     return;
2879   case UNW_MIPS_LO:
2880     _registers.__lo = value;
2881     return;
2882   }
2883   _LIBUNWIND_ABORT("unsupported mips_o32 register");
2884 }
2885 
2886 inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
2887 #if defined(__mips_hard_float) && __mips_fpr == 64
2888   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2889     return true;
2890 #else
2891   (void)regNum;
2892 #endif
2893   return false;
2894 }
2895 
2896 inline double Registers_mips_o32::getFloatRegister(int regNum) const {
2897 #if defined(__mips_hard_float) && __mips_fpr == 64
2898   assert(validFloatRegister(regNum));
2899   return _floats[regNum - UNW_MIPS_F0];
2900 #else
2901   (void)regNum;
2902   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2903 #endif
2904 }
2905 
2906 inline void Registers_mips_o32::setFloatRegister(int regNum,
2907                                                  double value) {
2908 #if defined(__mips_hard_float) && __mips_fpr == 64
2909   assert(validFloatRegister(regNum));
2910   _floats[regNum - UNW_MIPS_F0] = value;
2911 #else
2912   (void)regNum;
2913   (void)value;
2914   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2915 #endif
2916 }
2917 
2918 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
2919   return false;
2920 }
2921 
2922 inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
2923   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2924 }
2925 
2926 inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
2927   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2928 }
2929 
2930 inline const char *Registers_mips_o32::getRegisterName(int regNum) {
2931   switch (regNum) {
2932   case UNW_MIPS_R0:
2933     return "$0";
2934   case UNW_MIPS_R1:
2935     return "$1";
2936   case UNW_MIPS_R2:
2937     return "$2";
2938   case UNW_MIPS_R3:
2939     return "$3";
2940   case UNW_MIPS_R4:
2941     return "$4";
2942   case UNW_MIPS_R5:
2943     return "$5";
2944   case UNW_MIPS_R6:
2945     return "$6";
2946   case UNW_MIPS_R7:
2947     return "$7";
2948   case UNW_MIPS_R8:
2949     return "$8";
2950   case UNW_MIPS_R9:
2951     return "$9";
2952   case UNW_MIPS_R10:
2953     return "$10";
2954   case UNW_MIPS_R11:
2955     return "$11";
2956   case UNW_MIPS_R12:
2957     return "$12";
2958   case UNW_MIPS_R13:
2959     return "$13";
2960   case UNW_MIPS_R14:
2961     return "$14";
2962   case UNW_MIPS_R15:
2963     return "$15";
2964   case UNW_MIPS_R16:
2965     return "$16";
2966   case UNW_MIPS_R17:
2967     return "$17";
2968   case UNW_MIPS_R18:
2969     return "$18";
2970   case UNW_MIPS_R19:
2971     return "$19";
2972   case UNW_MIPS_R20:
2973     return "$20";
2974   case UNW_MIPS_R21:
2975     return "$21";
2976   case UNW_MIPS_R22:
2977     return "$22";
2978   case UNW_MIPS_R23:
2979     return "$23";
2980   case UNW_MIPS_R24:
2981     return "$24";
2982   case UNW_MIPS_R25:
2983     return "$25";
2984   case UNW_MIPS_R26:
2985     return "$26";
2986   case UNW_MIPS_R27:
2987     return "$27";
2988   case UNW_MIPS_R28:
2989     return "$28";
2990   case UNW_MIPS_R29:
2991     return "$29";
2992   case UNW_MIPS_R30:
2993     return "$30";
2994   case UNW_MIPS_R31:
2995     return "$31";
2996   case UNW_MIPS_F0:
2997     return "$f0";
2998   case UNW_MIPS_F1:
2999     return "$f1";
3000   case UNW_MIPS_F2:
3001     return "$f2";
3002   case UNW_MIPS_F3:
3003     return "$f3";
3004   case UNW_MIPS_F4:
3005     return "$f4";
3006   case UNW_MIPS_F5:
3007     return "$f5";
3008   case UNW_MIPS_F6:
3009     return "$f6";
3010   case UNW_MIPS_F7:
3011     return "$f7";
3012   case UNW_MIPS_F8:
3013     return "$f8";
3014   case UNW_MIPS_F9:
3015     return "$f9";
3016   case UNW_MIPS_F10:
3017     return "$f10";
3018   case UNW_MIPS_F11:
3019     return "$f11";
3020   case UNW_MIPS_F12:
3021     return "$f12";
3022   case UNW_MIPS_F13:
3023     return "$f13";
3024   case UNW_MIPS_F14:
3025     return "$f14";
3026   case UNW_MIPS_F15:
3027     return "$f15";
3028   case UNW_MIPS_F16:
3029     return "$f16";
3030   case UNW_MIPS_F17:
3031     return "$f17";
3032   case UNW_MIPS_F18:
3033     return "$f18";
3034   case UNW_MIPS_F19:
3035     return "$f19";
3036   case UNW_MIPS_F20:
3037     return "$f20";
3038   case UNW_MIPS_F21:
3039     return "$f21";
3040   case UNW_MIPS_F22:
3041     return "$f22";
3042   case UNW_MIPS_F23:
3043     return "$f23";
3044   case UNW_MIPS_F24:
3045     return "$f24";
3046   case UNW_MIPS_F25:
3047     return "$f25";
3048   case UNW_MIPS_F26:
3049     return "$f26";
3050   case UNW_MIPS_F27:
3051     return "$f27";
3052   case UNW_MIPS_F28:
3053     return "$f28";
3054   case UNW_MIPS_F29:
3055     return "$f29";
3056   case UNW_MIPS_F30:
3057     return "$f30";
3058   case UNW_MIPS_F31:
3059     return "$f31";
3060   case UNW_MIPS_HI:
3061     return "$hi";
3062   case UNW_MIPS_LO:
3063     return "$lo";
3064   default:
3065     return "unknown register";
3066   }
3067 }
3068 #endif // _LIBUNWIND_TARGET_MIPS_O32
3069 
3070 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
3071 /// Registers_mips_newabi holds the register state of a thread in a
3072 /// MIPS process using NEWABI (the N32 or N64 ABIs).
3073 class _LIBUNWIND_HIDDEN Registers_mips_newabi {
3074 public:
3075   Registers_mips_newabi();
3076   Registers_mips_newabi(const void *registers);
3077 
3078   bool        validRegister(int num) const;
3079   uint64_t    getRegister(int num) const;
3080   void        setRegister(int num, uint64_t value);
3081   bool        validFloatRegister(int num) const;
3082   double      getFloatRegister(int num) const;
3083   void        setFloatRegister(int num, double value);
3084   bool        validVectorRegister(int num) const;
3085   v128        getVectorRegister(int num) const;
3086   void        setVectorRegister(int num, v128 value);
3087   static const char *getRegisterName(int num);
3088   void        jumpto();
3089   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
3090   static int  getArch() { return REGISTERS_MIPS_NEWABI; }
3091 
3092   uint64_t  getSP() const         { return _registers.__r[29]; }
3093   void      setSP(uint64_t value) { _registers.__r[29] = value; }
3094   uint64_t  getIP() const         { return _registers.__pc; }
3095   void      setIP(uint64_t value) { _registers.__pc = value; }
3096 
3097 private:
3098   struct mips_newabi_thread_state_t {
3099     uint64_t __r[32];
3100     uint64_t __pc;
3101     uint64_t __hi;
3102     uint64_t __lo;
3103   };
3104 
3105   mips_newabi_thread_state_t _registers;
3106 #ifdef __mips_hard_float
3107   double _floats[32];
3108 #endif
3109 };
3110 
3111 inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {
3112   static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),
3113                 "mips_newabi registers do not fit into unw_context_t");
3114   memcpy(&_registers, static_cast<const uint8_t *>(registers),
3115          sizeof(_registers));
3116 }
3117 
3118 inline Registers_mips_newabi::Registers_mips_newabi() {
3119   memset(&_registers, 0, sizeof(_registers));
3120 }
3121 
3122 inline bool Registers_mips_newabi::validRegister(int regNum) const {
3123   if (regNum == UNW_REG_IP)
3124     return true;
3125   if (regNum == UNW_REG_SP)
3126     return true;
3127   if (regNum < 0)
3128     return false;
3129   if (regNum <= UNW_MIPS_R31)
3130     return true;
3131 #if __mips_isa_rev != 6
3132   if (regNum == UNW_MIPS_HI)
3133     return true;
3134   if (regNum == UNW_MIPS_LO)
3135     return true;
3136 #endif
3137   // FIXME: Hard float, DSP accumulator registers, MSA registers
3138   return false;
3139 }
3140 
3141 inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
3142   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3143     return _registers.__r[regNum - UNW_MIPS_R0];
3144 
3145   switch (regNum) {
3146   case UNW_REG_IP:
3147     return _registers.__pc;
3148   case UNW_REG_SP:
3149     return _registers.__r[29];
3150   case UNW_MIPS_HI:
3151     return _registers.__hi;
3152   case UNW_MIPS_LO:
3153     return _registers.__lo;
3154   }
3155   _LIBUNWIND_ABORT("unsupported mips_newabi register");
3156 }
3157 
3158 inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
3159   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3160     _registers.__r[regNum - UNW_MIPS_R0] = value;
3161     return;
3162   }
3163 
3164   switch (regNum) {
3165   case UNW_REG_IP:
3166     _registers.__pc = value;
3167     return;
3168   case UNW_REG_SP:
3169     _registers.__r[29] = value;
3170     return;
3171   case UNW_MIPS_HI:
3172     _registers.__hi = value;
3173     return;
3174   case UNW_MIPS_LO:
3175     _registers.__lo = value;
3176     return;
3177   }
3178   _LIBUNWIND_ABORT("unsupported mips_newabi register");
3179 }
3180 
3181 inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {
3182 #ifdef __mips_hard_float
3183   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3184     return true;
3185 #else
3186   (void)regNum;
3187 #endif
3188   return false;
3189 }
3190 
3191 inline double Registers_mips_newabi::getFloatRegister(int regNum) const {
3192 #ifdef __mips_hard_float
3193   assert(validFloatRegister(regNum));
3194   return _floats[regNum - UNW_MIPS_F0];
3195 #else
3196   (void)regNum;
3197   _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3198 #endif
3199 }
3200 
3201 inline void Registers_mips_newabi::setFloatRegister(int regNum,
3202                                                     double value) {
3203 #ifdef __mips_hard_float
3204   assert(validFloatRegister(regNum));
3205   _floats[regNum - UNW_MIPS_F0] = value;
3206 #else
3207   (void)regNum;
3208   (void)value;
3209   _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3210 #endif
3211 }
3212 
3213 inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {
3214   return false;
3215 }
3216 
3217 inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {
3218   _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3219 }
3220 
3221 inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {
3222   _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3223 }
3224 
3225 inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
3226   switch (regNum) {
3227   case UNW_MIPS_R0:
3228     return "$0";
3229   case UNW_MIPS_R1:
3230     return "$1";
3231   case UNW_MIPS_R2:
3232     return "$2";
3233   case UNW_MIPS_R3:
3234     return "$3";
3235   case UNW_MIPS_R4:
3236     return "$4";
3237   case UNW_MIPS_R5:
3238     return "$5";
3239   case UNW_MIPS_R6:
3240     return "$6";
3241   case UNW_MIPS_R7:
3242     return "$7";
3243   case UNW_MIPS_R8:
3244     return "$8";
3245   case UNW_MIPS_R9:
3246     return "$9";
3247   case UNW_MIPS_R10:
3248     return "$10";
3249   case UNW_MIPS_R11:
3250     return "$11";
3251   case UNW_MIPS_R12:
3252     return "$12";
3253   case UNW_MIPS_R13:
3254     return "$13";
3255   case UNW_MIPS_R14:
3256     return "$14";
3257   case UNW_MIPS_R15:
3258     return "$15";
3259   case UNW_MIPS_R16:
3260     return "$16";
3261   case UNW_MIPS_R17:
3262     return "$17";
3263   case UNW_MIPS_R18:
3264     return "$18";
3265   case UNW_MIPS_R19:
3266     return "$19";
3267   case UNW_MIPS_R20:
3268     return "$20";
3269   case UNW_MIPS_R21:
3270     return "$21";
3271   case UNW_MIPS_R22:
3272     return "$22";
3273   case UNW_MIPS_R23:
3274     return "$23";
3275   case UNW_MIPS_R24:
3276     return "$24";
3277   case UNW_MIPS_R25:
3278     return "$25";
3279   case UNW_MIPS_R26:
3280     return "$26";
3281   case UNW_MIPS_R27:
3282     return "$27";
3283   case UNW_MIPS_R28:
3284     return "$28";
3285   case UNW_MIPS_R29:
3286     return "$29";
3287   case UNW_MIPS_R30:
3288     return "$30";
3289   case UNW_MIPS_R31:
3290     return "$31";
3291   case UNW_MIPS_F0:
3292     return "$f0";
3293   case UNW_MIPS_F1:
3294     return "$f1";
3295   case UNW_MIPS_F2:
3296     return "$f2";
3297   case UNW_MIPS_F3:
3298     return "$f3";
3299   case UNW_MIPS_F4:
3300     return "$f4";
3301   case UNW_MIPS_F5:
3302     return "$f5";
3303   case UNW_MIPS_F6:
3304     return "$f6";
3305   case UNW_MIPS_F7:
3306     return "$f7";
3307   case UNW_MIPS_F8:
3308     return "$f8";
3309   case UNW_MIPS_F9:
3310     return "$f9";
3311   case UNW_MIPS_F10:
3312     return "$f10";
3313   case UNW_MIPS_F11:
3314     return "$f11";
3315   case UNW_MIPS_F12:
3316     return "$f12";
3317   case UNW_MIPS_F13:
3318     return "$f13";
3319   case UNW_MIPS_F14:
3320     return "$f14";
3321   case UNW_MIPS_F15:
3322     return "$f15";
3323   case UNW_MIPS_F16:
3324     return "$f16";
3325   case UNW_MIPS_F17:
3326     return "$f17";
3327   case UNW_MIPS_F18:
3328     return "$f18";
3329   case UNW_MIPS_F19:
3330     return "$f19";
3331   case UNW_MIPS_F20:
3332     return "$f20";
3333   case UNW_MIPS_F21:
3334     return "$f21";
3335   case UNW_MIPS_F22:
3336     return "$f22";
3337   case UNW_MIPS_F23:
3338     return "$f23";
3339   case UNW_MIPS_F24:
3340     return "$f24";
3341   case UNW_MIPS_F25:
3342     return "$f25";
3343   case UNW_MIPS_F26:
3344     return "$f26";
3345   case UNW_MIPS_F27:
3346     return "$f27";
3347   case UNW_MIPS_F28:
3348     return "$f28";
3349   case UNW_MIPS_F29:
3350     return "$f29";
3351   case UNW_MIPS_F30:
3352     return "$f30";
3353   case UNW_MIPS_F31:
3354     return "$f31";
3355   case UNW_MIPS_HI:
3356     return "$hi";
3357   case UNW_MIPS_LO:
3358     return "$lo";
3359   default:
3360     return "unknown register";
3361   }
3362 }
3363 #endif // _LIBUNWIND_TARGET_MIPS_NEWABI
3364 
3365 #if defined(_LIBUNWIND_TARGET_SPARC)
3366 /// Registers_sparc holds the register state of a thread in a 32-bit Sparc
3367 /// process.
3368 class _LIBUNWIND_HIDDEN Registers_sparc {
3369 public:
3370   Registers_sparc();
3371   Registers_sparc(const void *registers);
3372 
3373   bool        validRegister(int num) const;
3374   uint32_t    getRegister(int num) const;
3375   void        setRegister(int num, uint32_t value);
3376   bool        validFloatRegister(int num) const;
3377   double      getFloatRegister(int num) const;
3378   void        setFloatRegister(int num, double value);
3379   bool        validVectorRegister(int num) const;
3380   v128        getVectorRegister(int num) const;
3381   void        setVectorRegister(int num, v128 value);
3382   static const char *getRegisterName(int num);
3383   void        jumpto();
3384   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC; }
3385   static int  getArch() { return REGISTERS_SPARC; }
3386 
3387   uint64_t  getSP() const         { return _registers.__regs[UNW_SPARC_O6]; }
3388   void      setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; }
3389   uint64_t  getIP() const         { return _registers.__regs[UNW_SPARC_O7]; }
3390   void      setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
3391 
3392 private:
3393   struct sparc_thread_state_t {
3394     unsigned int __regs[32];
3395   };
3396 
3397   sparc_thread_state_t _registers;
3398 };
3399 
3400 inline Registers_sparc::Registers_sparc(const void *registers) {
3401   static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit),
3402                 "sparc registers do not fit into unw_context_t");
3403   memcpy(&_registers, static_cast<const uint8_t *>(registers),
3404          sizeof(_registers));
3405 }
3406 
3407 inline Registers_sparc::Registers_sparc() {
3408   memset(&_registers, 0, sizeof(_registers));
3409 }
3410 
3411 inline bool Registers_sparc::validRegister(int regNum) const {
3412   if (regNum == UNW_REG_IP)
3413     return true;
3414   if (regNum == UNW_REG_SP)
3415     return true;
3416   if (regNum < 0)
3417     return false;
3418   if (regNum <= UNW_SPARC_I7)
3419     return true;
3420   return false;
3421 }
3422 
3423 inline uint32_t Registers_sparc::getRegister(int regNum) const {
3424   if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3425     return _registers.__regs[regNum];
3426   }
3427 
3428   switch (regNum) {
3429   case UNW_REG_IP:
3430     return _registers.__regs[UNW_SPARC_O7];
3431   case UNW_REG_SP:
3432     return _registers.__regs[UNW_SPARC_O6];
3433   }
3434   _LIBUNWIND_ABORT("unsupported sparc register");
3435 }
3436 
3437 inline void Registers_sparc::setRegister(int regNum, uint32_t value) {
3438   if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3439     _registers.__regs[regNum] = value;
3440     return;
3441   }
3442 
3443   switch (regNum) {
3444   case UNW_REG_IP:
3445     _registers.__regs[UNW_SPARC_O7] = value;
3446     return;
3447   case UNW_REG_SP:
3448     _registers.__regs[UNW_SPARC_O6] = value;
3449     return;
3450   }
3451   _LIBUNWIND_ABORT("unsupported sparc register");
3452 }
3453 
3454 inline bool Registers_sparc::validFloatRegister(int) const { return false; }
3455 
3456 inline double Registers_sparc::getFloatRegister(int) const {
3457   _LIBUNWIND_ABORT("no Sparc float registers");
3458 }
3459 
3460 inline void Registers_sparc::setFloatRegister(int, double) {
3461   _LIBUNWIND_ABORT("no Sparc float registers");
3462 }
3463 
3464 inline bool Registers_sparc::validVectorRegister(int) const { return false; }
3465 
3466 inline v128 Registers_sparc::getVectorRegister(int) const {
3467   _LIBUNWIND_ABORT("no Sparc vector registers");
3468 }
3469 
3470 inline void Registers_sparc::setVectorRegister(int, v128) {
3471   _LIBUNWIND_ABORT("no Sparc vector registers");
3472 }
3473 
3474 inline const char *Registers_sparc::getRegisterName(int regNum) {
3475   switch (regNum) {
3476   case UNW_REG_IP:
3477     return "pc";
3478   case UNW_SPARC_G0:
3479     return "g0";
3480   case UNW_SPARC_G1:
3481     return "g1";
3482   case UNW_SPARC_G2:
3483     return "g2";
3484   case UNW_SPARC_G3:
3485     return "g3";
3486   case UNW_SPARC_G4:
3487     return "g4";
3488   case UNW_SPARC_G5:
3489     return "g5";
3490   case UNW_SPARC_G6:
3491     return "g6";
3492   case UNW_SPARC_G7:
3493     return "g7";
3494   case UNW_SPARC_O0:
3495     return "o0";
3496   case UNW_SPARC_O1:
3497     return "o1";
3498   case UNW_SPARC_O2:
3499     return "o2";
3500   case UNW_SPARC_O3:
3501     return "o3";
3502   case UNW_SPARC_O4:
3503     return "o4";
3504   case UNW_SPARC_O5:
3505     return "o5";
3506   case UNW_REG_SP:
3507   case UNW_SPARC_O6:
3508     return "sp";
3509   case UNW_SPARC_O7:
3510     return "o7";
3511   case UNW_SPARC_L0:
3512     return "l0";
3513   case UNW_SPARC_L1:
3514     return "l1";
3515   case UNW_SPARC_L2:
3516     return "l2";
3517   case UNW_SPARC_L3:
3518     return "l3";
3519   case UNW_SPARC_L4:
3520     return "l4";
3521   case UNW_SPARC_L5:
3522     return "l5";
3523   case UNW_SPARC_L6:
3524     return "l6";
3525   case UNW_SPARC_L7:
3526     return "l7";
3527   case UNW_SPARC_I0:
3528     return "i0";
3529   case UNW_SPARC_I1:
3530     return "i1";
3531   case UNW_SPARC_I2:
3532     return "i2";
3533   case UNW_SPARC_I3:
3534     return "i3";
3535   case UNW_SPARC_I4:
3536     return "i4";
3537   case UNW_SPARC_I5:
3538     return "i5";
3539   case UNW_SPARC_I6:
3540     return "fp";
3541   case UNW_SPARC_I7:
3542     return "i7";
3543   default:
3544     return "unknown register";
3545   }
3546 }
3547 #endif // _LIBUNWIND_TARGET_SPARC
3548 
3549 #if defined(_LIBUNWIND_TARGET_HEXAGON)
3550 /// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6
3551 /// process.
3552 class _LIBUNWIND_HIDDEN Registers_hexagon {
3553 public:
3554   Registers_hexagon();
3555   Registers_hexagon(const void *registers);
3556 
3557   bool        validRegister(int num) const;
3558   uint32_t    getRegister(int num) const;
3559   void        setRegister(int num, uint32_t value);
3560   bool        validFloatRegister(int num) const;
3561   double      getFloatRegister(int num) const;
3562   void        setFloatRegister(int num, double value);
3563   bool        validVectorRegister(int num) const;
3564   v128        getVectorRegister(int num) const;
3565   void        setVectorRegister(int num, v128 value);
3566   const char *getRegisterName(int num);
3567   void        jumpto();
3568   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON; }
3569   static int  getArch() { return REGISTERS_HEXAGON; }
3570 
3571   uint32_t  getSP() const         { return _registers.__r[UNW_HEXAGON_R29]; }
3572   void      setSP(uint32_t value) { _registers.__r[UNW_HEXAGON_R29] = value; }
3573   uint32_t  getIP() const         { return _registers.__r[UNW_HEXAGON_PC]; }
3574   void      setIP(uint32_t value) { _registers.__r[UNW_HEXAGON_PC] = value; }
3575 
3576 private:
3577   struct hexagon_thread_state_t {
3578     unsigned int __r[35];
3579   };
3580 
3581   hexagon_thread_state_t _registers;
3582 };
3583 
3584 inline Registers_hexagon::Registers_hexagon(const void *registers) {
3585   static_assert((check_fit<Registers_hexagon, unw_context_t>::does_fit),
3586                 "hexagon registers do not fit into unw_context_t");
3587   memcpy(&_registers, static_cast<const uint8_t *>(registers),
3588          sizeof(_registers));
3589 }
3590 
3591 inline Registers_hexagon::Registers_hexagon() {
3592   memset(&_registers, 0, sizeof(_registers));
3593 }
3594 
3595 inline bool Registers_hexagon::validRegister(int regNum) const {
3596   if (regNum <= UNW_HEXAGON_R31)
3597     return true;
3598   return false;
3599 }
3600 
3601 inline uint32_t Registers_hexagon::getRegister(int regNum) const {
3602   if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31)
3603     return _registers.__r[regNum - UNW_HEXAGON_R0];
3604 
3605   switch (regNum) {
3606   case UNW_REG_IP:
3607     return _registers.__r[UNW_HEXAGON_PC];
3608   case UNW_REG_SP:
3609     return _registers.__r[UNW_HEXAGON_R29];
3610   }
3611   _LIBUNWIND_ABORT("unsupported hexagon register");
3612 }
3613 
3614 inline void Registers_hexagon::setRegister(int regNum, uint32_t value) {
3615   if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31) {
3616     _registers.__r[regNum - UNW_HEXAGON_R0] = value;
3617     return;
3618   }
3619 
3620   switch (regNum) {
3621   case UNW_REG_IP:
3622     _registers.__r[UNW_HEXAGON_PC] = value;
3623     return;
3624   case UNW_REG_SP:
3625     _registers.__r[UNW_HEXAGON_R29] = value;
3626     return;
3627   }
3628   _LIBUNWIND_ABORT("unsupported hexagon register");
3629 }
3630 
3631 inline bool Registers_hexagon::validFloatRegister(int /* regNum */) const {
3632   return false;
3633 }
3634 
3635 inline double Registers_hexagon::getFloatRegister(int /* regNum */) const {
3636   _LIBUNWIND_ABORT("hexagon float support not implemented");
3637 }
3638 
3639 inline void Registers_hexagon::setFloatRegister(int /* regNum */,
3640                                              double /* value */) {
3641   _LIBUNWIND_ABORT("hexagon float support not implemented");
3642 }
3643 
3644 inline bool Registers_hexagon::validVectorRegister(int /* regNum */) const {
3645   return false;
3646 }
3647 
3648 inline v128 Registers_hexagon::getVectorRegister(int /* regNum */) const {
3649   _LIBUNWIND_ABORT("hexagon vector support not implemented");
3650 }
3651 
3652 inline void Registers_hexagon::setVectorRegister(int /* regNum */, v128 /* value */) {
3653   _LIBUNWIND_ABORT("hexagon vector support not implemented");
3654 }
3655 
3656 inline const char *Registers_hexagon::getRegisterName(int regNum) {
3657   switch (regNum) {
3658   case UNW_HEXAGON_R0:
3659     return "r0";
3660   case UNW_HEXAGON_R1:
3661     return "r1";
3662   case UNW_HEXAGON_R2:
3663     return "r2";
3664   case UNW_HEXAGON_R3:
3665     return "r3";
3666   case UNW_HEXAGON_R4:
3667     return "r4";
3668   case UNW_HEXAGON_R5:
3669     return "r5";
3670   case UNW_HEXAGON_R6:
3671     return "r6";
3672   case UNW_HEXAGON_R7:
3673     return "r7";
3674   case UNW_HEXAGON_R8:
3675     return "r8";
3676   case UNW_HEXAGON_R9:
3677     return "r9";
3678   case UNW_HEXAGON_R10:
3679     return "r10";
3680   case UNW_HEXAGON_R11:
3681     return "r11";
3682   case UNW_HEXAGON_R12:
3683     return "r12";
3684   case UNW_HEXAGON_R13:
3685     return "r13";
3686   case UNW_HEXAGON_R14:
3687     return "r14";
3688   case UNW_HEXAGON_R15:
3689     return "r15";
3690   case UNW_HEXAGON_R16:
3691     return "r16";
3692   case UNW_HEXAGON_R17:
3693     return "r17";
3694   case UNW_HEXAGON_R18:
3695     return "r18";
3696   case UNW_HEXAGON_R19:
3697     return "r19";
3698   case UNW_HEXAGON_R20:
3699     return "r20";
3700   case UNW_HEXAGON_R21:
3701     return "r21";
3702   case UNW_HEXAGON_R22:
3703     return "r22";
3704   case UNW_HEXAGON_R23:
3705     return "r23";
3706   case UNW_HEXAGON_R24:
3707     return "r24";
3708   case UNW_HEXAGON_R25:
3709     return "r25";
3710   case UNW_HEXAGON_R26:
3711     return "r26";
3712   case UNW_HEXAGON_R27:
3713     return "r27";
3714   case UNW_HEXAGON_R28:
3715     return "r28";
3716   case UNW_HEXAGON_R29:
3717     return "r29";
3718   case UNW_HEXAGON_R30:
3719     return "r30";
3720   case UNW_HEXAGON_R31:
3721     return "r31";
3722   default:
3723     return "unknown register";
3724   }
3725 
3726 }
3727 #endif // _LIBUNWIND_TARGET_HEXAGON
3728 
3729 
3730 #if defined(_LIBUNWIND_TARGET_RISCV)
3731 /// Registers_riscv holds the register state of a thread in a RISC-V
3732 /// process.
3733 
3734 // This check makes it safe when LIBUNWIND_ENABLE_CROSS_UNWINDING enabled.
3735 # ifdef __riscv
3736 #  if __riscv_xlen == 32
3737 typedef uint32_t reg_t;
3738 #  elif __riscv_xlen == 64
3739 typedef uint64_t reg_t;
3740 #  else
3741 #   error "Unsupported __riscv_xlen"
3742 #  endif
3743 
3744 #  if defined(__riscv_flen)
3745 #   if __riscv_flen == 64
3746 typedef double fp_t;
3747 #   elif __riscv_flen == 32
3748 typedef float fp_t;
3749 #   else
3750 #    error "Unsupported __riscv_flen"
3751 #   endif
3752 #  else
3753 // This is just for supressing undeclared error of fp_t.
3754 typedef double fp_t;
3755 #  endif
3756 # else
3757 // Use Max possible width when cross unwinding
3758 typedef uint64_t reg_t;
3759 typedef double fp_t;
3760 # define __riscv_xlen 64
3761 # define __riscv_flen 64
3762 #endif
3763 
3764 /// Registers_riscv holds the register state of a thread.
3765 class _LIBUNWIND_HIDDEN Registers_riscv {
3766 public:
3767   Registers_riscv();
3768   Registers_riscv(const void *registers);
3769 
3770   bool        validRegister(int num) const;
3771   reg_t       getRegister(int num) const;
3772   void        setRegister(int num, reg_t value);
3773   bool        validFloatRegister(int num) const;
3774   fp_t        getFloatRegister(int num) const;
3775   void        setFloatRegister(int num, fp_t value);
3776   bool        validVectorRegister(int num) const;
3777   v128        getVectorRegister(int num) const;
3778   void        setVectorRegister(int num, v128 value);
3779   static const char *getRegisterName(int num);
3780   void        jumpto();
3781   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
3782   static int  getArch() { return REGISTERS_RISCV; }
3783 
3784   reg_t       getSP() const { return _registers[2]; }
3785   void        setSP(reg_t value) { _registers[2] = value; }
3786   reg_t       getIP() const { return _registers[0]; }
3787   void        setIP(reg_t value) { _registers[0] = value; }
3788 
3789 private:
3790   // _registers[0] holds the pc
3791   reg_t _registers[32];
3792 # if defined(__riscv_flen)
3793   fp_t _floats[32];
3794 # endif
3795 };
3796 
3797 inline Registers_riscv::Registers_riscv(const void *registers) {
3798   static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
3799                 "riscv registers do not fit into unw_context_t");
3800   memcpy(&_registers, registers, sizeof(_registers));
3801 # if __riscv_xlen == 32
3802   static_assert(sizeof(_registers) == 0x80,
3803                 "expected float registers to be at offset 128");
3804 # elif __riscv_xlen == 64
3805   static_assert(sizeof(_registers) == 0x100,
3806                 "expected float registers to be at offset 256");
3807 # else
3808 # error "Unexpected float registers."
3809 # endif
3810 
3811 # if defined(__riscv_flen)
3812   memcpy(_floats,
3813          static_cast<const uint8_t *>(registers) + sizeof(_registers),
3814          sizeof(_floats));
3815 # endif
3816 }
3817 
3818 inline Registers_riscv::Registers_riscv() {
3819   memset(&_registers, 0, sizeof(_registers));
3820 # if defined(__riscv_flen)
3821   memset(&_floats, 0, sizeof(_floats));
3822 # endif
3823 }
3824 
3825 inline bool Registers_riscv::validRegister(int regNum) const {
3826   if (regNum == UNW_REG_IP)
3827     return true;
3828   if (regNum == UNW_REG_SP)
3829     return true;
3830   if (regNum < 0)
3831     return false;
3832   if (regNum > UNW_RISCV_F31)
3833     return false;
3834   return true;
3835 }
3836 
3837 inline reg_t Registers_riscv::getRegister(int regNum) const {
3838   if (regNum == UNW_REG_IP)
3839     return _registers[0];
3840   if (regNum == UNW_REG_SP)
3841     return _registers[2];
3842   if (regNum == UNW_RISCV_X0)
3843     return 0;
3844   if ((regNum > 0) && (regNum < 32))
3845     return _registers[regNum];
3846   _LIBUNWIND_ABORT("unsupported riscv register");
3847 }
3848 
3849 inline void Registers_riscv::setRegister(int regNum, reg_t value) {
3850   if (regNum == UNW_REG_IP)
3851     _registers[0] = value;
3852   else if (regNum == UNW_REG_SP)
3853     _registers[2] = value;
3854   else if (regNum == UNW_RISCV_X0)
3855     /* x0 is hardwired to zero */
3856     return;
3857   else if ((regNum > 0) && (regNum < 32))
3858     _registers[regNum] = value;
3859   else
3860     _LIBUNWIND_ABORT("unsupported riscv register");
3861 }
3862 
3863 inline const char *Registers_riscv::getRegisterName(int regNum) {
3864   switch (regNum) {
3865   case UNW_REG_IP:
3866     return "pc";
3867   case UNW_REG_SP:
3868     return "sp";
3869   case UNW_RISCV_X0:
3870     return "zero";
3871   case UNW_RISCV_X1:
3872     return "ra";
3873   case UNW_RISCV_X2:
3874     return "sp";
3875   case UNW_RISCV_X3:
3876     return "gp";
3877   case UNW_RISCV_X4:
3878     return "tp";
3879   case UNW_RISCV_X5:
3880     return "t0";
3881   case UNW_RISCV_X6:
3882     return "t1";
3883   case UNW_RISCV_X7:
3884     return "t2";
3885   case UNW_RISCV_X8:
3886     return "s0";
3887   case UNW_RISCV_X9:
3888     return "s1";
3889   case UNW_RISCV_X10:
3890     return "a0";
3891   case UNW_RISCV_X11:
3892     return "a1";
3893   case UNW_RISCV_X12:
3894     return "a2";
3895   case UNW_RISCV_X13:
3896     return "a3";
3897   case UNW_RISCV_X14:
3898     return "a4";
3899   case UNW_RISCV_X15:
3900     return "a5";
3901   case UNW_RISCV_X16:
3902     return "a6";
3903   case UNW_RISCV_X17:
3904     return "a7";
3905   case UNW_RISCV_X18:
3906     return "s2";
3907   case UNW_RISCV_X19:
3908     return "s3";
3909   case UNW_RISCV_X20:
3910     return "s4";
3911   case UNW_RISCV_X21:
3912     return "s5";
3913   case UNW_RISCV_X22:
3914     return "s6";
3915   case UNW_RISCV_X23:
3916     return "s7";
3917   case UNW_RISCV_X24:
3918     return "s8";
3919   case UNW_RISCV_X25:
3920     return "s9";
3921   case UNW_RISCV_X26:
3922     return "s10";
3923   case UNW_RISCV_X27:
3924     return "s11";
3925   case UNW_RISCV_X28:
3926     return "t3";
3927   case UNW_RISCV_X29:
3928     return "t4";
3929   case UNW_RISCV_X30:
3930     return "t5";
3931   case UNW_RISCV_X31:
3932     return "t6";
3933   case UNW_RISCV_F0:
3934     return "ft0";
3935   case UNW_RISCV_F1:
3936     return "ft1";
3937   case UNW_RISCV_F2:
3938     return "ft2";
3939   case UNW_RISCV_F3:
3940     return "ft3";
3941   case UNW_RISCV_F4:
3942     return "ft4";
3943   case UNW_RISCV_F5:
3944     return "ft5";
3945   case UNW_RISCV_F6:
3946     return "ft6";
3947   case UNW_RISCV_F7:
3948     return "ft7";
3949   case UNW_RISCV_F8:
3950     return "fs0";
3951   case UNW_RISCV_F9:
3952     return "fs1";
3953   case UNW_RISCV_F10:
3954     return "fa0";
3955   case UNW_RISCV_F11:
3956     return "fa1";
3957   case UNW_RISCV_F12:
3958     return "fa2";
3959   case UNW_RISCV_F13:
3960     return "fa3";
3961   case UNW_RISCV_F14:
3962     return "fa4";
3963   case UNW_RISCV_F15:
3964     return "fa5";
3965   case UNW_RISCV_F16:
3966     return "fa6";
3967   case UNW_RISCV_F17:
3968     return "fa7";
3969   case UNW_RISCV_F18:
3970     return "fs2";
3971   case UNW_RISCV_F19:
3972     return "fs3";
3973   case UNW_RISCV_F20:
3974     return "fs4";
3975   case UNW_RISCV_F21:
3976     return "fs5";
3977   case UNW_RISCV_F22:
3978     return "fs6";
3979   case UNW_RISCV_F23:
3980     return "fs7";
3981   case UNW_RISCV_F24:
3982     return "fs8";
3983   case UNW_RISCV_F25:
3984     return "fs9";
3985   case UNW_RISCV_F26:
3986     return "fs10";
3987   case UNW_RISCV_F27:
3988     return "fs11";
3989   case UNW_RISCV_F28:
3990     return "ft8";
3991   case UNW_RISCV_F29:
3992     return "ft9";
3993   case UNW_RISCV_F30:
3994     return "ft10";
3995   case UNW_RISCV_F31:
3996     return "ft11";
3997   default:
3998     return "unknown register";
3999   }
4000 }
4001 
4002 inline bool Registers_riscv::validFloatRegister(int regNum) const {
4003 # if defined(__riscv_flen)
4004   if (regNum < UNW_RISCV_F0)
4005     return false;
4006   if (regNum > UNW_RISCV_F31)
4007     return false;
4008   return true;
4009 # else
4010   (void)regNum;
4011   return false;
4012 # endif
4013 }
4014 
4015 inline fp_t Registers_riscv::getFloatRegister(int regNum) const {
4016 # if defined(__riscv_flen)
4017   assert(validFloatRegister(regNum));
4018   return _floats[regNum - UNW_RISCV_F0];
4019 # else
4020   (void)regNum;
4021   _LIBUNWIND_ABORT("libunwind not built with float support");
4022 # endif
4023 }
4024 
4025 inline void Registers_riscv::setFloatRegister(int regNum, fp_t value) {
4026 # if defined(__riscv_flen)
4027   assert(validFloatRegister(regNum));
4028   _floats[regNum - UNW_RISCV_F0] = value;
4029 # else
4030   (void)regNum;
4031   (void)value;
4032   _LIBUNWIND_ABORT("libunwind not built with float support");
4033 # endif
4034 }
4035 
4036 inline bool Registers_riscv::validVectorRegister(int) const {
4037   return false;
4038 }
4039 
4040 inline v128 Registers_riscv::getVectorRegister(int) const {
4041   _LIBUNWIND_ABORT("no riscv vector register support yet");
4042 }
4043 
4044 inline void Registers_riscv::setVectorRegister(int, v128) {
4045   _LIBUNWIND_ABORT("no riscv vector register support yet");
4046 }
4047 #endif // _LIBUNWIND_TARGET_RISCV
4048 
4049 #if defined(_LIBUNWIND_TARGET_VE)
4050 /// Registers_ve holds the register state of a thread in a VE process.
4051 class _LIBUNWIND_HIDDEN Registers_ve {
4052 public:
4053   Registers_ve();
4054   Registers_ve(const void *registers);
4055 
4056   bool        validRegister(int num) const;
4057   uint64_t    getRegister(int num) const;
4058   void        setRegister(int num, uint64_t value);
4059   bool        validFloatRegister(int num) const;
4060   double      getFloatRegister(int num) const;
4061   void        setFloatRegister(int num, double value);
4062   bool        validVectorRegister(int num) const;
4063   v128        getVectorRegister(int num) const;
4064   void        setVectorRegister(int num, v128 value);
4065   static const char *getRegisterName(int num);
4066   void        jumpto();
4067   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE; }
4068   static int  getArch() { return REGISTERS_VE; }
4069 
4070   uint64_t  getSP() const         { return _registers.__s[11]; }
4071   void      setSP(uint64_t value) { _registers.__s[11] = value; }
4072   uint64_t  getIP() const         { return _registers.__ic; }
4073   void      setIP(uint64_t value) { _registers.__ic = value; }
4074 
4075 private:
4076   // FIXME: Need to store not only scalar registers but also vector and vector
4077   // mask registers.  VEOS uses mcontext_t defined in ucontext.h.  It takes
4078   // 524288 bytes (65536*8 bytes), though.  Currently, we use libunwind for
4079   // SjLj exception support only, so Registers_ve is not implemented completely.
4080   struct ve_thread_state_t {
4081     uint64_t __s[64]; // s0-s64
4082     uint64_t __ic;    // Instruction counter (IC)
4083     uint64_t __vixr;  // Vector Index Register
4084     uint64_t __vl;    // Vector Length Register
4085   };
4086 
4087   ve_thread_state_t _registers; // total 67 registers
4088 
4089   // Currently no vector register is preserved.
4090 };
4091 
4092 inline Registers_ve::Registers_ve(const void *registers) {
4093   static_assert((check_fit<Registers_ve, unw_context_t>::does_fit),
4094                 "ve registers do not fit into unw_context_t");
4095   memcpy(&_registers, static_cast<const uint8_t *>(registers),
4096          sizeof(_registers));
4097   static_assert(sizeof(_registers) == 536,
4098                 "expected vector register offset to be 536");
4099 }
4100 
4101 inline Registers_ve::Registers_ve() {
4102   memset(&_registers, 0, sizeof(_registers));
4103 }
4104 
4105 inline bool Registers_ve::validRegister(int regNum) const {
4106   if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
4107     return true;
4108 
4109   switch (regNum) {
4110   case UNW_REG_IP:
4111   case UNW_REG_SP:
4112   case UNW_VE_VIXR:
4113   case UNW_VE_VL:
4114     return true;
4115   default:
4116     return false;
4117   }
4118 }
4119 
4120 inline uint64_t Registers_ve::getRegister(int regNum) const {
4121   if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
4122     return _registers.__s[regNum - UNW_VE_S0];
4123 
4124   switch (regNum) {
4125   case UNW_REG_IP:
4126     return _registers.__ic;
4127   case UNW_REG_SP:
4128     return _registers.__s[11];
4129   case UNW_VE_VIXR:
4130     return _registers.__vixr;
4131   case UNW_VE_VL:
4132     return _registers.__vl;
4133   }
4134   _LIBUNWIND_ABORT("unsupported ve register");
4135 }
4136 
4137 inline void Registers_ve::setRegister(int regNum, uint64_t value) {
4138   if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63) {
4139     _registers.__s[regNum - UNW_VE_S0] = value;
4140     return;
4141   }
4142 
4143   switch (regNum) {
4144   case UNW_REG_IP:
4145     _registers.__ic = value;
4146     return;
4147   case UNW_REG_SP:
4148     _registers.__s[11] = value;
4149     return;
4150   case UNW_VE_VIXR:
4151     _registers.__vixr = value;
4152     return;
4153   case UNW_VE_VL:
4154     _registers.__vl = value;
4155     return;
4156   }
4157   _LIBUNWIND_ABORT("unsupported ve register");
4158 }
4159 
4160 inline bool Registers_ve::validFloatRegister(int /* regNum */) const {
4161   return false;
4162 }
4163 
4164 inline double Registers_ve::getFloatRegister(int /* regNum */) const {
4165   _LIBUNWIND_ABORT("VE doesn't have float registers");
4166 }
4167 
4168 inline void Registers_ve::setFloatRegister(int /* regNum */,
4169                                            double /* value */) {
4170   _LIBUNWIND_ABORT("VE doesn't have float registers");
4171 }
4172 
4173 inline bool Registers_ve::validVectorRegister(int /* regNum */) const {
4174   return false;
4175 }
4176 
4177 inline v128 Registers_ve::getVectorRegister(int /* regNum */) const {
4178   _LIBUNWIND_ABORT("VE vector support not implemented");
4179 }
4180 
4181 inline void Registers_ve::setVectorRegister(int /* regNum */,
4182                                             v128 /* value */) {
4183   _LIBUNWIND_ABORT("VE vector support not implemented");
4184 }
4185 
4186 inline const char *Registers_ve::getRegisterName(int regNum) {
4187   switch (regNum) {
4188   case UNW_REG_IP:
4189     return "ip";
4190   case UNW_REG_SP:
4191     return "sp";
4192   case UNW_VE_VIXR:
4193     return "vixr";
4194   case UNW_VE_VL:
4195     return "vl";
4196   case UNW_VE_S0:
4197     return "s0";
4198   case UNW_VE_S1:
4199     return "s1";
4200   case UNW_VE_S2:
4201     return "s2";
4202   case UNW_VE_S3:
4203     return "s3";
4204   case UNW_VE_S4:
4205     return "s4";
4206   case UNW_VE_S5:
4207     return "s5";
4208   case UNW_VE_S6:
4209     return "s6";
4210   case UNW_VE_S7:
4211     return "s7";
4212   case UNW_VE_S8:
4213     return "s8";
4214   case UNW_VE_S9:
4215     return "s9";
4216   case UNW_VE_S10:
4217     return "s10";
4218   case UNW_VE_S11:
4219     return "s11";
4220   case UNW_VE_S12:
4221     return "s12";
4222   case UNW_VE_S13:
4223     return "s13";
4224   case UNW_VE_S14:
4225     return "s14";
4226   case UNW_VE_S15:
4227     return "s15";
4228   case UNW_VE_S16:
4229     return "s16";
4230   case UNW_VE_S17:
4231     return "s17";
4232   case UNW_VE_S18:
4233     return "s18";
4234   case UNW_VE_S19:
4235     return "s19";
4236   case UNW_VE_S20:
4237     return "s20";
4238   case UNW_VE_S21:
4239     return "s21";
4240   case UNW_VE_S22:
4241     return "s22";
4242   case UNW_VE_S23:
4243     return "s23";
4244   case UNW_VE_S24:
4245     return "s24";
4246   case UNW_VE_S25:
4247     return "s25";
4248   case UNW_VE_S26:
4249     return "s26";
4250   case UNW_VE_S27:
4251     return "s27";
4252   case UNW_VE_S28:
4253     return "s28";
4254   case UNW_VE_S29:
4255     return "s29";
4256   case UNW_VE_S30:
4257     return "s30";
4258   case UNW_VE_S31:
4259     return "s31";
4260   case UNW_VE_S32:
4261     return "s32";
4262   case UNW_VE_S33:
4263     return "s33";
4264   case UNW_VE_S34:
4265     return "s34";
4266   case UNW_VE_S35:
4267     return "s35";
4268   case UNW_VE_S36:
4269     return "s36";
4270   case UNW_VE_S37:
4271     return "s37";
4272   case UNW_VE_S38:
4273     return "s38";
4274   case UNW_VE_S39:
4275     return "s39";
4276   case UNW_VE_S40:
4277     return "s40";
4278   case UNW_VE_S41:
4279     return "s41";
4280   case UNW_VE_S42:
4281     return "s42";
4282   case UNW_VE_S43:
4283     return "s43";
4284   case UNW_VE_S44:
4285     return "s44";
4286   case UNW_VE_S45:
4287     return "s45";
4288   case UNW_VE_S46:
4289     return "s46";
4290   case UNW_VE_S47:
4291     return "s47";
4292   case UNW_VE_S48:
4293     return "s48";
4294   case UNW_VE_S49:
4295     return "s49";
4296   case UNW_VE_S50:
4297     return "s50";
4298   case UNW_VE_S51:
4299     return "s51";
4300   case UNW_VE_S52:
4301     return "s52";
4302   case UNW_VE_S53:
4303     return "s53";
4304   case UNW_VE_S54:
4305     return "s54";
4306   case UNW_VE_S55:
4307     return "s55";
4308   case UNW_VE_S56:
4309     return "s56";
4310   case UNW_VE_S57:
4311     return "s57";
4312   case UNW_VE_S58:
4313     return "s58";
4314   case UNW_VE_S59:
4315     return "s59";
4316   case UNW_VE_S60:
4317     return "s60";
4318   case UNW_VE_S61:
4319     return "s61";
4320   case UNW_VE_S62:
4321     return "s62";
4322   case UNW_VE_S63:
4323     return "s63";
4324   case UNW_VE_V0:
4325     return "v0";
4326   case UNW_VE_V1:
4327     return "v1";
4328   case UNW_VE_V2:
4329     return "v2";
4330   case UNW_VE_V3:
4331     return "v3";
4332   case UNW_VE_V4:
4333     return "v4";
4334   case UNW_VE_V5:
4335     return "v5";
4336   case UNW_VE_V6:
4337     return "v6";
4338   case UNW_VE_V7:
4339     return "v7";
4340   case UNW_VE_V8:
4341     return "v8";
4342   case UNW_VE_V9:
4343     return "v9";
4344   case UNW_VE_V10:
4345     return "v10";
4346   case UNW_VE_V11:
4347     return "v11";
4348   case UNW_VE_V12:
4349     return "v12";
4350   case UNW_VE_V13:
4351     return "v13";
4352   case UNW_VE_V14:
4353     return "v14";
4354   case UNW_VE_V15:
4355     return "v15";
4356   case UNW_VE_V16:
4357     return "v16";
4358   case UNW_VE_V17:
4359     return "v17";
4360   case UNW_VE_V18:
4361     return "v18";
4362   case UNW_VE_V19:
4363     return "v19";
4364   case UNW_VE_V20:
4365     return "v20";
4366   case UNW_VE_V21:
4367     return "v21";
4368   case UNW_VE_V22:
4369     return "v22";
4370   case UNW_VE_V23:
4371     return "v23";
4372   case UNW_VE_V24:
4373     return "v24";
4374   case UNW_VE_V25:
4375     return "v25";
4376   case UNW_VE_V26:
4377     return "v26";
4378   case UNW_VE_V27:
4379     return "v27";
4380   case UNW_VE_V28:
4381     return "v28";
4382   case UNW_VE_V29:
4383     return "v29";
4384   case UNW_VE_V30:
4385     return "v30";
4386   case UNW_VE_V31:
4387     return "v31";
4388   case UNW_VE_V32:
4389     return "v32";
4390   case UNW_VE_V33:
4391     return "v33";
4392   case UNW_VE_V34:
4393     return "v34";
4394   case UNW_VE_V35:
4395     return "v35";
4396   case UNW_VE_V36:
4397     return "v36";
4398   case UNW_VE_V37:
4399     return "v37";
4400   case UNW_VE_V38:
4401     return "v38";
4402   case UNW_VE_V39:
4403     return "v39";
4404   case UNW_VE_V40:
4405     return "v40";
4406   case UNW_VE_V41:
4407     return "v41";
4408   case UNW_VE_V42:
4409     return "v42";
4410   case UNW_VE_V43:
4411     return "v43";
4412   case UNW_VE_V44:
4413     return "v44";
4414   case UNW_VE_V45:
4415     return "v45";
4416   case UNW_VE_V46:
4417     return "v46";
4418   case UNW_VE_V47:
4419     return "v47";
4420   case UNW_VE_V48:
4421     return "v48";
4422   case UNW_VE_V49:
4423     return "v49";
4424   case UNW_VE_V50:
4425     return "v50";
4426   case UNW_VE_V51:
4427     return "v51";
4428   case UNW_VE_V52:
4429     return "v52";
4430   case UNW_VE_V53:
4431     return "v53";
4432   case UNW_VE_V54:
4433     return "v54";
4434   case UNW_VE_V55:
4435     return "v55";
4436   case UNW_VE_V56:
4437     return "v56";
4438   case UNW_VE_V57:
4439     return "v57";
4440   case UNW_VE_V58:
4441     return "v58";
4442   case UNW_VE_V59:
4443     return "v59";
4444   case UNW_VE_V60:
4445     return "v60";
4446   case UNW_VE_V61:
4447     return "v61";
4448   case UNW_VE_V62:
4449     return "v62";
4450   case UNW_VE_V63:
4451     return "v63";
4452   case UNW_VE_VM0:
4453     return "vm0";
4454   case UNW_VE_VM1:
4455     return "vm1";
4456   case UNW_VE_VM2:
4457     return "vm2";
4458   case UNW_VE_VM3:
4459     return "vm3";
4460   case UNW_VE_VM4:
4461     return "vm4";
4462   case UNW_VE_VM5:
4463     return "vm5";
4464   case UNW_VE_VM6:
4465     return "vm6";
4466   case UNW_VE_VM7:
4467     return "vm7";
4468   case UNW_VE_VM8:
4469     return "vm8";
4470   case UNW_VE_VM9:
4471     return "vm9";
4472   case UNW_VE_VM10:
4473     return "vm10";
4474   case UNW_VE_VM11:
4475     return "vm11";
4476   case UNW_VE_VM12:
4477     return "vm12";
4478   case UNW_VE_VM13:
4479     return "vm13";
4480   case UNW_VE_VM14:
4481     return "vm14";
4482   case UNW_VE_VM15:
4483     return "vm15";
4484   }
4485   return "unknown register";
4486 }
4487 #endif // _LIBUNWIND_TARGET_VE
4488 
4489 } // namespace libunwind
4490 
4491 #endif // __REGISTERS_HPP__
4492