1 //===----------------------------- Registers.hpp --------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //
9 //  Models register sets for supported processors.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef __REGISTERS_HPP__
14 #define __REGISTERS_HPP__
15 
16 #include <stdint.h>
17 #include <string.h>
18 
19 #include "libunwind.h"
20 #include "config.h"
21 
22 namespace libunwind {
23 
24 // For emulating 128-bit registers
25 struct v128 { uint32_t vec[4]; };
26 
27 
28 #if defined(_LIBUNWIND_TARGET_I386)
29 /// Registers_x86 holds the register state of a thread in a 32-bit intel
30 /// process.
31 class _LIBUNWIND_HIDDEN Registers_x86 {
32 public:
33   Registers_x86();
34   Registers_x86(const void *registers);
35 
36   bool        validRegister(int num) const;
37   uint32_t    getRegister(int num) const;
38   void        setRegister(int num, uint32_t value);
39   bool        validFloatRegister(int) const { return false; }
40   double      getFloatRegister(int num) const;
41   void        setFloatRegister(int num, double value);
42   bool        validVectorRegister(int) const { return false; }
43   v128        getVectorRegister(int num) const;
44   void        setVectorRegister(int num, v128 value);
45   const char *getRegisterName(int num);
46   void        jumpto();
47   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
48 
49   uint32_t  getSP() const          { return _registers.__esp; }
50   void      setSP(uint32_t value)  { _registers.__esp = value; }
51   uint32_t  getIP() const          { return _registers.__eip; }
52   void      setIP(uint32_t value)  { _registers.__eip = value; }
53   uint32_t  getEBP() const         { return _registers.__ebp; }
54   void      setEBP(uint32_t value) { _registers.__ebp = value; }
55   uint32_t  getEBX() const         { return _registers.__ebx; }
56   void      setEBX(uint32_t value) { _registers.__ebx = value; }
57   uint32_t  getECX() const         { return _registers.__ecx; }
58   void      setECX(uint32_t value) { _registers.__ecx = value; }
59   uint32_t  getEDX() const         { return _registers.__edx; }
60   void      setEDX(uint32_t value) { _registers.__edx = value; }
61   uint32_t  getESI() const         { return _registers.__esi; }
62   void      setESI(uint32_t value) { _registers.__esi = value; }
63   uint32_t  getEDI() const         { return _registers.__edi; }
64   void      setEDI(uint32_t value) { _registers.__edi = value; }
65 
66 private:
67   struct GPRs {
68     unsigned int __eax;
69     unsigned int __ebx;
70     unsigned int __ecx;
71     unsigned int __edx;
72     unsigned int __edi;
73     unsigned int __esi;
74     unsigned int __ebp;
75     unsigned int __esp;
76     unsigned int __ss;
77     unsigned int __eflags;
78     unsigned int __eip;
79     unsigned int __cs;
80     unsigned int __ds;
81     unsigned int __es;
82     unsigned int __fs;
83     unsigned int __gs;
84   };
85 
86   GPRs _registers;
87 };
88 
89 inline Registers_x86::Registers_x86(const void *registers) {
90   static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
91                 "x86 registers do not fit into unw_context_t");
92   memcpy(&_registers, registers, sizeof(_registers));
93 }
94 
95 inline Registers_x86::Registers_x86() {
96   memset(&_registers, 0, sizeof(_registers));
97 }
98 
99 inline bool Registers_x86::validRegister(int regNum) const {
100   if (regNum == UNW_REG_IP)
101     return true;
102   if (regNum == UNW_REG_SP)
103     return true;
104   if (regNum < 0)
105     return false;
106   if (regNum > 7)
107     return false;
108   return true;
109 }
110 
111 inline uint32_t Registers_x86::getRegister(int regNum) const {
112   switch (regNum) {
113   case UNW_REG_IP:
114     return _registers.__eip;
115   case UNW_REG_SP:
116     return _registers.__esp;
117   case UNW_X86_EAX:
118     return _registers.__eax;
119   case UNW_X86_ECX:
120     return _registers.__ecx;
121   case UNW_X86_EDX:
122     return _registers.__edx;
123   case UNW_X86_EBX:
124     return _registers.__ebx;
125 #if !defined(__APPLE__)
126   case UNW_X86_ESP:
127 #else
128   case UNW_X86_EBP:
129 #endif
130     return _registers.__ebp;
131 #if !defined(__APPLE__)
132   case UNW_X86_EBP:
133 #else
134   case UNW_X86_ESP:
135 #endif
136     return _registers.__esp;
137   case UNW_X86_ESI:
138     return _registers.__esi;
139   case UNW_X86_EDI:
140     return _registers.__edi;
141   }
142   _LIBUNWIND_ABORT("unsupported x86 register");
143 }
144 
145 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
146   switch (regNum) {
147   case UNW_REG_IP:
148     _registers.__eip = value;
149     return;
150   case UNW_REG_SP:
151     _registers.__esp = value;
152     return;
153   case UNW_X86_EAX:
154     _registers.__eax = value;
155     return;
156   case UNW_X86_ECX:
157     _registers.__ecx = value;
158     return;
159   case UNW_X86_EDX:
160     _registers.__edx = value;
161     return;
162   case UNW_X86_EBX:
163     _registers.__ebx = value;
164     return;
165 #if !defined(__APPLE__)
166   case UNW_X86_ESP:
167 #else
168   case UNW_X86_EBP:
169 #endif
170     _registers.__ebp = value;
171     return;
172 #if !defined(__APPLE__)
173   case UNW_X86_EBP:
174 #else
175   case UNW_X86_ESP:
176 #endif
177     _registers.__esp = value;
178     return;
179   case UNW_X86_ESI:
180     _registers.__esi = value;
181     return;
182   case UNW_X86_EDI:
183     _registers.__edi = value;
184     return;
185   }
186   _LIBUNWIND_ABORT("unsupported x86 register");
187 }
188 
189 inline const char *Registers_x86::getRegisterName(int regNum) {
190   switch (regNum) {
191   case UNW_REG_IP:
192     return "ip";
193   case UNW_REG_SP:
194     return "esp";
195   case UNW_X86_EAX:
196     return "eax";
197   case UNW_X86_ECX:
198     return "ecx";
199   case UNW_X86_EDX:
200     return "edx";
201   case UNW_X86_EBX:
202     return "ebx";
203   case UNW_X86_EBP:
204     return "ebp";
205   case UNW_X86_ESP:
206     return "esp";
207   case UNW_X86_ESI:
208     return "esi";
209   case UNW_X86_EDI:
210     return "edi";
211   default:
212     return "unknown register";
213   }
214 }
215 
216 inline double Registers_x86::getFloatRegister(int) const {
217   _LIBUNWIND_ABORT("no x86 float registers");
218 }
219 
220 inline void Registers_x86::setFloatRegister(int, double) {
221   _LIBUNWIND_ABORT("no x86 float registers");
222 }
223 
224 inline v128 Registers_x86::getVectorRegister(int) const {
225   _LIBUNWIND_ABORT("no x86 vector registers");
226 }
227 
228 inline void Registers_x86::setVectorRegister(int, v128) {
229   _LIBUNWIND_ABORT("no x86 vector registers");
230 }
231 #endif // _LIBUNWIND_TARGET_I386
232 
233 
234 #if defined(_LIBUNWIND_TARGET_X86_64)
235 /// Registers_x86_64  holds the register state of a thread in a 64-bit intel
236 /// process.
237 class _LIBUNWIND_HIDDEN Registers_x86_64 {
238 public:
239   Registers_x86_64();
240   Registers_x86_64(const void *registers);
241 
242   bool        validRegister(int num) const;
243   uint64_t    getRegister(int num) const;
244   void        setRegister(int num, uint64_t value);
245   bool        validFloatRegister(int) const { return false; }
246   double      getFloatRegister(int num) const;
247   void        setFloatRegister(int num, double value);
248   bool        validVectorRegister(int) const;
249   v128        getVectorRegister(int num) const;
250   void        setVectorRegister(int num, v128 value);
251   const char *getRegisterName(int num);
252   void        jumpto();
253   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
254 
255   uint64_t  getSP() const          { return _registers.__rsp; }
256   void      setSP(uint64_t value)  { _registers.__rsp = value; }
257   uint64_t  getIP() const          { return _registers.__rip; }
258   void      setIP(uint64_t value)  { _registers.__rip = value; }
259   uint64_t  getRBP() const         { return _registers.__rbp; }
260   void      setRBP(uint64_t value) { _registers.__rbp = value; }
261   uint64_t  getRBX() const         { return _registers.__rbx; }
262   void      setRBX(uint64_t value) { _registers.__rbx = value; }
263   uint64_t  getR12() const         { return _registers.__r12; }
264   void      setR12(uint64_t value) { _registers.__r12 = value; }
265   uint64_t  getR13() const         { return _registers.__r13; }
266   void      setR13(uint64_t value) { _registers.__r13 = value; }
267   uint64_t  getR14() const         { return _registers.__r14; }
268   void      setR14(uint64_t value) { _registers.__r14 = value; }
269   uint64_t  getR15() const         { return _registers.__r15; }
270   void      setR15(uint64_t value) { _registers.__r15 = value; }
271 
272 private:
273   struct GPRs {
274     uint64_t __rax;
275     uint64_t __rbx;
276     uint64_t __rcx;
277     uint64_t __rdx;
278     uint64_t __rdi;
279     uint64_t __rsi;
280     uint64_t __rbp;
281     uint64_t __rsp;
282     uint64_t __r8;
283     uint64_t __r9;
284     uint64_t __r10;
285     uint64_t __r11;
286     uint64_t __r12;
287     uint64_t __r13;
288     uint64_t __r14;
289     uint64_t __r15;
290     uint64_t __rip;
291     uint64_t __rflags;
292     uint64_t __cs;
293     uint64_t __fs;
294     uint64_t __gs;
295 #if defined(_WIN64)
296     uint64_t __padding; // 16-byte align
297 #endif
298   };
299   GPRs _registers;
300 #if defined(_WIN64)
301   v128 _xmm[16];
302 #endif
303 };
304 
305 inline Registers_x86_64::Registers_x86_64(const void *registers) {
306   static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
307                 "x86_64 registers do not fit into unw_context_t");
308   memcpy(&_registers, registers, sizeof(_registers));
309 }
310 
311 inline Registers_x86_64::Registers_x86_64() {
312   memset(&_registers, 0, sizeof(_registers));
313 }
314 
315 inline bool Registers_x86_64::validRegister(int regNum) const {
316   if (regNum == UNW_REG_IP)
317     return true;
318   if (regNum == UNW_REG_SP)
319     return true;
320   if (regNum < 0)
321     return false;
322   if (regNum > 15)
323     return false;
324   return true;
325 }
326 
327 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
328   switch (regNum) {
329   case UNW_REG_IP:
330     return _registers.__rip;
331   case UNW_REG_SP:
332     return _registers.__rsp;
333   case UNW_X86_64_RAX:
334     return _registers.__rax;
335   case UNW_X86_64_RDX:
336     return _registers.__rdx;
337   case UNW_X86_64_RCX:
338     return _registers.__rcx;
339   case UNW_X86_64_RBX:
340     return _registers.__rbx;
341   case UNW_X86_64_RSI:
342     return _registers.__rsi;
343   case UNW_X86_64_RDI:
344     return _registers.__rdi;
345   case UNW_X86_64_RBP:
346     return _registers.__rbp;
347   case UNW_X86_64_RSP:
348     return _registers.__rsp;
349   case UNW_X86_64_R8:
350     return _registers.__r8;
351   case UNW_X86_64_R9:
352     return _registers.__r9;
353   case UNW_X86_64_R10:
354     return _registers.__r10;
355   case UNW_X86_64_R11:
356     return _registers.__r11;
357   case UNW_X86_64_R12:
358     return _registers.__r12;
359   case UNW_X86_64_R13:
360     return _registers.__r13;
361   case UNW_X86_64_R14:
362     return _registers.__r14;
363   case UNW_X86_64_R15:
364     return _registers.__r15;
365   }
366   _LIBUNWIND_ABORT("unsupported x86_64 register");
367 }
368 
369 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
370   switch (regNum) {
371   case UNW_REG_IP:
372     _registers.__rip = value;
373     return;
374   case UNW_REG_SP:
375     _registers.__rsp = value;
376     return;
377   case UNW_X86_64_RAX:
378     _registers.__rax = value;
379     return;
380   case UNW_X86_64_RDX:
381     _registers.__rdx = value;
382     return;
383   case UNW_X86_64_RCX:
384     _registers.__rcx = value;
385     return;
386   case UNW_X86_64_RBX:
387     _registers.__rbx = value;
388     return;
389   case UNW_X86_64_RSI:
390     _registers.__rsi = value;
391     return;
392   case UNW_X86_64_RDI:
393     _registers.__rdi = value;
394     return;
395   case UNW_X86_64_RBP:
396     _registers.__rbp = value;
397     return;
398   case UNW_X86_64_RSP:
399     _registers.__rsp = value;
400     return;
401   case UNW_X86_64_R8:
402     _registers.__r8 = value;
403     return;
404   case UNW_X86_64_R9:
405     _registers.__r9 = value;
406     return;
407   case UNW_X86_64_R10:
408     _registers.__r10 = value;
409     return;
410   case UNW_X86_64_R11:
411     _registers.__r11 = value;
412     return;
413   case UNW_X86_64_R12:
414     _registers.__r12 = value;
415     return;
416   case UNW_X86_64_R13:
417     _registers.__r13 = value;
418     return;
419   case UNW_X86_64_R14:
420     _registers.__r14 = value;
421     return;
422   case UNW_X86_64_R15:
423     _registers.__r15 = value;
424     return;
425   }
426   _LIBUNWIND_ABORT("unsupported x86_64 register");
427 }
428 
429 inline const char *Registers_x86_64::getRegisterName(int regNum) {
430   switch (regNum) {
431   case UNW_REG_IP:
432     return "rip";
433   case UNW_REG_SP:
434     return "rsp";
435   case UNW_X86_64_RAX:
436     return "rax";
437   case UNW_X86_64_RDX:
438     return "rdx";
439   case UNW_X86_64_RCX:
440     return "rcx";
441   case UNW_X86_64_RBX:
442     return "rbx";
443   case UNW_X86_64_RSI:
444     return "rsi";
445   case UNW_X86_64_RDI:
446     return "rdi";
447   case UNW_X86_64_RBP:
448     return "rbp";
449   case UNW_X86_64_RSP:
450     return "rsp";
451   case UNW_X86_64_R8:
452     return "r8";
453   case UNW_X86_64_R9:
454     return "r9";
455   case UNW_X86_64_R10:
456     return "r10";
457   case UNW_X86_64_R11:
458     return "r11";
459   case UNW_X86_64_R12:
460     return "r12";
461   case UNW_X86_64_R13:
462     return "r13";
463   case UNW_X86_64_R14:
464     return "r14";
465   case UNW_X86_64_R15:
466     return "r15";
467   case UNW_X86_64_XMM0:
468     return "xmm0";
469   case UNW_X86_64_XMM1:
470     return "xmm1";
471   case UNW_X86_64_XMM2:
472     return "xmm2";
473   case UNW_X86_64_XMM3:
474     return "xmm3";
475   case UNW_X86_64_XMM4:
476     return "xmm4";
477   case UNW_X86_64_XMM5:
478     return "xmm5";
479   case UNW_X86_64_XMM6:
480     return "xmm6";
481   case UNW_X86_64_XMM7:
482     return "xmm7";
483   case UNW_X86_64_XMM8:
484     return "xmm8";
485   case UNW_X86_64_XMM9:
486     return "xmm9";
487   case UNW_X86_64_XMM10:
488     return "xmm10";
489   case UNW_X86_64_XMM11:
490     return "xmm11";
491   case UNW_X86_64_XMM12:
492     return "xmm12";
493   case UNW_X86_64_XMM13:
494     return "xmm13";
495   case UNW_X86_64_XMM14:
496     return "xmm14";
497   case UNW_X86_64_XMM15:
498     return "xmm15";
499   default:
500     return "unknown register";
501   }
502 }
503 
504 inline double Registers_x86_64::getFloatRegister(int) const {
505   _LIBUNWIND_ABORT("no x86_64 float registers");
506 }
507 
508 inline void Registers_x86_64::setFloatRegister(int, double) {
509   _LIBUNWIND_ABORT("no x86_64 float registers");
510 }
511 
512 inline bool Registers_x86_64::validVectorRegister(int regNum) const {
513 #if defined(_WIN64)
514   if (regNum < UNW_X86_64_XMM0)
515     return false;
516   if (regNum > UNW_X86_64_XMM15)
517     return false;
518   return true;
519 #else
520   (void)regNum; // suppress unused parameter warning
521   return false;
522 #endif
523 }
524 
525 inline v128 Registers_x86_64::getVectorRegister(int regNum) const {
526 #if defined(_WIN64)
527   assert(validVectorRegister(regNum));
528   return _xmm[regNum - UNW_X86_64_XMM0];
529 #else
530   (void)regNum; // suppress unused parameter warning
531   _LIBUNWIND_ABORT("no x86_64 vector registers");
532 #endif
533 }
534 
535 inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {
536 #if defined(_WIN64)
537   assert(validVectorRegister(regNum));
538   _xmm[regNum - UNW_X86_64_XMM0] = value;
539 #else
540   (void)regNum; (void)value; // suppress unused parameter warnings
541   _LIBUNWIND_ABORT("no x86_64 vector registers");
542 #endif
543 }
544 #endif // _LIBUNWIND_TARGET_X86_64
545 
546 
547 #if defined(_LIBUNWIND_TARGET_PPC)
548 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
549 /// process.
550 class _LIBUNWIND_HIDDEN Registers_ppc {
551 public:
552   Registers_ppc();
553   Registers_ppc(const void *registers);
554 
555   bool        validRegister(int num) const;
556   uint32_t    getRegister(int num) const;
557   void        setRegister(int num, uint32_t value);
558   bool        validFloatRegister(int num) const;
559   double      getFloatRegister(int num) const;
560   void        setFloatRegister(int num, double value);
561   bool        validVectorRegister(int num) const;
562   v128        getVectorRegister(int num) const;
563   void        setVectorRegister(int num, v128 value);
564   const char *getRegisterName(int num);
565   void        jumpto();
566   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; }
567 
568   uint64_t  getSP() const         { return _registers.__r1; }
569   void      setSP(uint32_t value) { _registers.__r1 = value; }
570   uint64_t  getIP() const         { return _registers.__srr0; }
571   void      setIP(uint32_t value) { _registers.__srr0 = value; }
572 
573 private:
574   struct ppc_thread_state_t {
575     unsigned int __srr0; /* Instruction address register (PC) */
576     unsigned int __srr1; /* Machine state register (supervisor) */
577     unsigned int __r0;
578     unsigned int __r1;
579     unsigned int __r2;
580     unsigned int __r3;
581     unsigned int __r4;
582     unsigned int __r5;
583     unsigned int __r6;
584     unsigned int __r7;
585     unsigned int __r8;
586     unsigned int __r9;
587     unsigned int __r10;
588     unsigned int __r11;
589     unsigned int __r12;
590     unsigned int __r13;
591     unsigned int __r14;
592     unsigned int __r15;
593     unsigned int __r16;
594     unsigned int __r17;
595     unsigned int __r18;
596     unsigned int __r19;
597     unsigned int __r20;
598     unsigned int __r21;
599     unsigned int __r22;
600     unsigned int __r23;
601     unsigned int __r24;
602     unsigned int __r25;
603     unsigned int __r26;
604     unsigned int __r27;
605     unsigned int __r28;
606     unsigned int __r29;
607     unsigned int __r30;
608     unsigned int __r31;
609     unsigned int __cr;     /* Condition register */
610     unsigned int __xer;    /* User's integer exception register */
611     unsigned int __lr;     /* Link register */
612     unsigned int __ctr;    /* Count register */
613     unsigned int __mq;     /* MQ register (601 only) */
614     unsigned int __vrsave; /* Vector Save Register */
615   };
616 
617   struct ppc_float_state_t {
618     double __fpregs[32];
619 
620     unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
621     unsigned int __fpscr;     /* floating point status register */
622   };
623 
624   ppc_thread_state_t _registers;
625   ppc_float_state_t  _floatRegisters;
626   v128               _vectorRegisters[32]; // offset 424
627 };
628 
629 inline Registers_ppc::Registers_ppc(const void *registers) {
630   static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
631                 "ppc registers do not fit into unw_context_t");
632   memcpy(&_registers, static_cast<const uint8_t *>(registers),
633          sizeof(_registers));
634   static_assert(sizeof(ppc_thread_state_t) == 160,
635                 "expected float register offset to be 160");
636   memcpy(&_floatRegisters,
637          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
638          sizeof(_floatRegisters));
639   static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
640                 "expected vector register offset to be 424 bytes");
641   memcpy(_vectorRegisters,
642          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
643              sizeof(ppc_float_state_t),
644          sizeof(_vectorRegisters));
645 }
646 
647 inline Registers_ppc::Registers_ppc() {
648   memset(&_registers, 0, sizeof(_registers));
649   memset(&_floatRegisters, 0, sizeof(_floatRegisters));
650   memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
651 }
652 
653 inline bool Registers_ppc::validRegister(int regNum) const {
654   if (regNum == UNW_REG_IP)
655     return true;
656   if (regNum == UNW_REG_SP)
657     return true;
658   if (regNum == UNW_PPC_VRSAVE)
659     return true;
660   if (regNum < 0)
661     return false;
662   if (regNum <= UNW_PPC_R31)
663     return true;
664   if (regNum == UNW_PPC_MQ)
665     return true;
666   if (regNum == UNW_PPC_LR)
667     return true;
668   if (regNum == UNW_PPC_CTR)
669     return true;
670   if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
671     return true;
672   return false;
673 }
674 
675 inline uint32_t Registers_ppc::getRegister(int regNum) const {
676   switch (regNum) {
677   case UNW_REG_IP:
678     return _registers.__srr0;
679   case UNW_REG_SP:
680     return _registers.__r1;
681   case UNW_PPC_R0:
682     return _registers.__r0;
683   case UNW_PPC_R1:
684     return _registers.__r1;
685   case UNW_PPC_R2:
686     return _registers.__r2;
687   case UNW_PPC_R3:
688     return _registers.__r3;
689   case UNW_PPC_R4:
690     return _registers.__r4;
691   case UNW_PPC_R5:
692     return _registers.__r5;
693   case UNW_PPC_R6:
694     return _registers.__r6;
695   case UNW_PPC_R7:
696     return _registers.__r7;
697   case UNW_PPC_R8:
698     return _registers.__r8;
699   case UNW_PPC_R9:
700     return _registers.__r9;
701   case UNW_PPC_R10:
702     return _registers.__r10;
703   case UNW_PPC_R11:
704     return _registers.__r11;
705   case UNW_PPC_R12:
706     return _registers.__r12;
707   case UNW_PPC_R13:
708     return _registers.__r13;
709   case UNW_PPC_R14:
710     return _registers.__r14;
711   case UNW_PPC_R15:
712     return _registers.__r15;
713   case UNW_PPC_R16:
714     return _registers.__r16;
715   case UNW_PPC_R17:
716     return _registers.__r17;
717   case UNW_PPC_R18:
718     return _registers.__r18;
719   case UNW_PPC_R19:
720     return _registers.__r19;
721   case UNW_PPC_R20:
722     return _registers.__r20;
723   case UNW_PPC_R21:
724     return _registers.__r21;
725   case UNW_PPC_R22:
726     return _registers.__r22;
727   case UNW_PPC_R23:
728     return _registers.__r23;
729   case UNW_PPC_R24:
730     return _registers.__r24;
731   case UNW_PPC_R25:
732     return _registers.__r25;
733   case UNW_PPC_R26:
734     return _registers.__r26;
735   case UNW_PPC_R27:
736     return _registers.__r27;
737   case UNW_PPC_R28:
738     return _registers.__r28;
739   case UNW_PPC_R29:
740     return _registers.__r29;
741   case UNW_PPC_R30:
742     return _registers.__r30;
743   case UNW_PPC_R31:
744     return _registers.__r31;
745   case UNW_PPC_LR:
746     return _registers.__lr;
747   case UNW_PPC_CR0:
748     return (_registers.__cr & 0xF0000000);
749   case UNW_PPC_CR1:
750     return (_registers.__cr & 0x0F000000);
751   case UNW_PPC_CR2:
752     return (_registers.__cr & 0x00F00000);
753   case UNW_PPC_CR3:
754     return (_registers.__cr & 0x000F0000);
755   case UNW_PPC_CR4:
756     return (_registers.__cr & 0x0000F000);
757   case UNW_PPC_CR5:
758     return (_registers.__cr & 0x00000F00);
759   case UNW_PPC_CR6:
760     return (_registers.__cr & 0x000000F0);
761   case UNW_PPC_CR7:
762     return (_registers.__cr & 0x0000000F);
763   case UNW_PPC_VRSAVE:
764     return _registers.__vrsave;
765   }
766   _LIBUNWIND_ABORT("unsupported ppc register");
767 }
768 
769 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
770   //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
771   switch (regNum) {
772   case UNW_REG_IP:
773     _registers.__srr0 = value;
774     return;
775   case UNW_REG_SP:
776     _registers.__r1 = value;
777     return;
778   case UNW_PPC_R0:
779     _registers.__r0 = value;
780     return;
781   case UNW_PPC_R1:
782     _registers.__r1 = value;
783     return;
784   case UNW_PPC_R2:
785     _registers.__r2 = value;
786     return;
787   case UNW_PPC_R3:
788     _registers.__r3 = value;
789     return;
790   case UNW_PPC_R4:
791     _registers.__r4 = value;
792     return;
793   case UNW_PPC_R5:
794     _registers.__r5 = value;
795     return;
796   case UNW_PPC_R6:
797     _registers.__r6 = value;
798     return;
799   case UNW_PPC_R7:
800     _registers.__r7 = value;
801     return;
802   case UNW_PPC_R8:
803     _registers.__r8 = value;
804     return;
805   case UNW_PPC_R9:
806     _registers.__r9 = value;
807     return;
808   case UNW_PPC_R10:
809     _registers.__r10 = value;
810     return;
811   case UNW_PPC_R11:
812     _registers.__r11 = value;
813     return;
814   case UNW_PPC_R12:
815     _registers.__r12 = value;
816     return;
817   case UNW_PPC_R13:
818     _registers.__r13 = value;
819     return;
820   case UNW_PPC_R14:
821     _registers.__r14 = value;
822     return;
823   case UNW_PPC_R15:
824     _registers.__r15 = value;
825     return;
826   case UNW_PPC_R16:
827     _registers.__r16 = value;
828     return;
829   case UNW_PPC_R17:
830     _registers.__r17 = value;
831     return;
832   case UNW_PPC_R18:
833     _registers.__r18 = value;
834     return;
835   case UNW_PPC_R19:
836     _registers.__r19 = value;
837     return;
838   case UNW_PPC_R20:
839     _registers.__r20 = value;
840     return;
841   case UNW_PPC_R21:
842     _registers.__r21 = value;
843     return;
844   case UNW_PPC_R22:
845     _registers.__r22 = value;
846     return;
847   case UNW_PPC_R23:
848     _registers.__r23 = value;
849     return;
850   case UNW_PPC_R24:
851     _registers.__r24 = value;
852     return;
853   case UNW_PPC_R25:
854     _registers.__r25 = value;
855     return;
856   case UNW_PPC_R26:
857     _registers.__r26 = value;
858     return;
859   case UNW_PPC_R27:
860     _registers.__r27 = value;
861     return;
862   case UNW_PPC_R28:
863     _registers.__r28 = value;
864     return;
865   case UNW_PPC_R29:
866     _registers.__r29 = value;
867     return;
868   case UNW_PPC_R30:
869     _registers.__r30 = value;
870     return;
871   case UNW_PPC_R31:
872     _registers.__r31 = value;
873     return;
874   case UNW_PPC_MQ:
875     _registers.__mq = value;
876     return;
877   case UNW_PPC_LR:
878     _registers.__lr = value;
879     return;
880   case UNW_PPC_CTR:
881     _registers.__ctr = value;
882     return;
883   case UNW_PPC_CR0:
884     _registers.__cr &= 0x0FFFFFFF;
885     _registers.__cr |= (value & 0xF0000000);
886     return;
887   case UNW_PPC_CR1:
888     _registers.__cr &= 0xF0FFFFFF;
889     _registers.__cr |= (value & 0x0F000000);
890     return;
891   case UNW_PPC_CR2:
892     _registers.__cr &= 0xFF0FFFFF;
893     _registers.__cr |= (value & 0x00F00000);
894     return;
895   case UNW_PPC_CR3:
896     _registers.__cr &= 0xFFF0FFFF;
897     _registers.__cr |= (value & 0x000F0000);
898     return;
899   case UNW_PPC_CR4:
900     _registers.__cr &= 0xFFFF0FFF;
901     _registers.__cr |= (value & 0x0000F000);
902     return;
903   case UNW_PPC_CR5:
904     _registers.__cr &= 0xFFFFF0FF;
905     _registers.__cr |= (value & 0x00000F00);
906     return;
907   case UNW_PPC_CR6:
908     _registers.__cr &= 0xFFFFFF0F;
909     _registers.__cr |= (value & 0x000000F0);
910     return;
911   case UNW_PPC_CR7:
912     _registers.__cr &= 0xFFFFFFF0;
913     _registers.__cr |= (value & 0x0000000F);
914     return;
915   case UNW_PPC_VRSAVE:
916     _registers.__vrsave = value;
917     return;
918     // not saved
919     return;
920   case UNW_PPC_XER:
921     _registers.__xer = value;
922     return;
923   case UNW_PPC_AP:
924   case UNW_PPC_VSCR:
925   case UNW_PPC_SPEFSCR:
926     // not saved
927     return;
928   }
929   _LIBUNWIND_ABORT("unsupported ppc register");
930 }
931 
932 inline bool Registers_ppc::validFloatRegister(int regNum) const {
933   if (regNum < UNW_PPC_F0)
934     return false;
935   if (regNum > UNW_PPC_F31)
936     return false;
937   return true;
938 }
939 
940 inline double Registers_ppc::getFloatRegister(int regNum) const {
941   assert(validFloatRegister(regNum));
942   return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
943 }
944 
945 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
946   assert(validFloatRegister(regNum));
947   _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
948 }
949 
950 inline bool Registers_ppc::validVectorRegister(int regNum) const {
951   if (regNum < UNW_PPC_V0)
952     return false;
953   if (regNum > UNW_PPC_V31)
954     return false;
955   return true;
956 }
957 
958 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
959   assert(validVectorRegister(regNum));
960   v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
961   return result;
962 }
963 
964 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
965   assert(validVectorRegister(regNum));
966   _vectorRegisters[regNum - UNW_PPC_V0] = value;
967 }
968 
969 inline const char *Registers_ppc::getRegisterName(int regNum) {
970   switch (regNum) {
971   case UNW_REG_IP:
972     return "ip";
973   case UNW_REG_SP:
974     return "sp";
975   case UNW_PPC_R0:
976     return "r0";
977   case UNW_PPC_R1:
978     return "r1";
979   case UNW_PPC_R2:
980     return "r2";
981   case UNW_PPC_R3:
982     return "r3";
983   case UNW_PPC_R4:
984     return "r4";
985   case UNW_PPC_R5:
986     return "r5";
987   case UNW_PPC_R6:
988     return "r6";
989   case UNW_PPC_R7:
990     return "r7";
991   case UNW_PPC_R8:
992     return "r8";
993   case UNW_PPC_R9:
994     return "r9";
995   case UNW_PPC_R10:
996     return "r10";
997   case UNW_PPC_R11:
998     return "r11";
999   case UNW_PPC_R12:
1000     return "r12";
1001   case UNW_PPC_R13:
1002     return "r13";
1003   case UNW_PPC_R14:
1004     return "r14";
1005   case UNW_PPC_R15:
1006     return "r15";
1007   case UNW_PPC_R16:
1008     return "r16";
1009   case UNW_PPC_R17:
1010     return "r17";
1011   case UNW_PPC_R18:
1012     return "r18";
1013   case UNW_PPC_R19:
1014     return "r19";
1015   case UNW_PPC_R20:
1016     return "r20";
1017   case UNW_PPC_R21:
1018     return "r21";
1019   case UNW_PPC_R22:
1020     return "r22";
1021   case UNW_PPC_R23:
1022     return "r23";
1023   case UNW_PPC_R24:
1024     return "r24";
1025   case UNW_PPC_R25:
1026     return "r25";
1027   case UNW_PPC_R26:
1028     return "r26";
1029   case UNW_PPC_R27:
1030     return "r27";
1031   case UNW_PPC_R28:
1032     return "r28";
1033   case UNW_PPC_R29:
1034     return "r29";
1035   case UNW_PPC_R30:
1036     return "r30";
1037   case UNW_PPC_R31:
1038     return "r31";
1039   case UNW_PPC_F0:
1040     return "fp0";
1041   case UNW_PPC_F1:
1042     return "fp1";
1043   case UNW_PPC_F2:
1044     return "fp2";
1045   case UNW_PPC_F3:
1046     return "fp3";
1047   case UNW_PPC_F4:
1048     return "fp4";
1049   case UNW_PPC_F5:
1050     return "fp5";
1051   case UNW_PPC_F6:
1052     return "fp6";
1053   case UNW_PPC_F7:
1054     return "fp7";
1055   case UNW_PPC_F8:
1056     return "fp8";
1057   case UNW_PPC_F9:
1058     return "fp9";
1059   case UNW_PPC_F10:
1060     return "fp10";
1061   case UNW_PPC_F11:
1062     return "fp11";
1063   case UNW_PPC_F12:
1064     return "fp12";
1065   case UNW_PPC_F13:
1066     return "fp13";
1067   case UNW_PPC_F14:
1068     return "fp14";
1069   case UNW_PPC_F15:
1070     return "fp15";
1071   case UNW_PPC_F16:
1072     return "fp16";
1073   case UNW_PPC_F17:
1074     return "fp17";
1075   case UNW_PPC_F18:
1076     return "fp18";
1077   case UNW_PPC_F19:
1078     return "fp19";
1079   case UNW_PPC_F20:
1080     return "fp20";
1081   case UNW_PPC_F21:
1082     return "fp21";
1083   case UNW_PPC_F22:
1084     return "fp22";
1085   case UNW_PPC_F23:
1086     return "fp23";
1087   case UNW_PPC_F24:
1088     return "fp24";
1089   case UNW_PPC_F25:
1090     return "fp25";
1091   case UNW_PPC_F26:
1092     return "fp26";
1093   case UNW_PPC_F27:
1094     return "fp27";
1095   case UNW_PPC_F28:
1096     return "fp28";
1097   case UNW_PPC_F29:
1098     return "fp29";
1099   case UNW_PPC_F30:
1100     return "fp30";
1101   case UNW_PPC_F31:
1102     return "fp31";
1103   case UNW_PPC_LR:
1104     return "lr";
1105   default:
1106     return "unknown register";
1107   }
1108 
1109 }
1110 #endif // _LIBUNWIND_TARGET_PPC
1111 
1112 #if defined(_LIBUNWIND_TARGET_PPC64)
1113 /// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC
1114 /// process.
1115 class _LIBUNWIND_HIDDEN Registers_ppc64 {
1116 public:
1117   Registers_ppc64();
1118   Registers_ppc64(const void *registers);
1119 
1120   bool        validRegister(int num) const;
1121   uint64_t    getRegister(int num) const;
1122   void        setRegister(int num, uint64_t value);
1123   bool        validFloatRegister(int num) const;
1124   double      getFloatRegister(int num) const;
1125   void        setFloatRegister(int num, double value);
1126   bool        validVectorRegister(int num) const;
1127   v128        getVectorRegister(int num) const;
1128   void        setVectorRegister(int num, v128 value);
1129   const char *getRegisterName(int num);
1130   void        jumpto();
1131   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64; }
1132 
1133   uint64_t  getSP() const         { return _registers.__r1; }
1134   void      setSP(uint64_t value) { _registers.__r1 = value; }
1135   uint64_t  getIP() const         { return _registers.__srr0; }
1136   void      setIP(uint64_t value) { _registers.__srr0 = value; }
1137 
1138 private:
1139   struct ppc64_thread_state_t {
1140     uint64_t __srr0;    // Instruction address register (PC)
1141     uint64_t __srr1;    // Machine state register (supervisor)
1142     uint64_t __r0;
1143     uint64_t __r1;
1144     uint64_t __r2;
1145     uint64_t __r3;
1146     uint64_t __r4;
1147     uint64_t __r5;
1148     uint64_t __r6;
1149     uint64_t __r7;
1150     uint64_t __r8;
1151     uint64_t __r9;
1152     uint64_t __r10;
1153     uint64_t __r11;
1154     uint64_t __r12;
1155     uint64_t __r13;
1156     uint64_t __r14;
1157     uint64_t __r15;
1158     uint64_t __r16;
1159     uint64_t __r17;
1160     uint64_t __r18;
1161     uint64_t __r19;
1162     uint64_t __r20;
1163     uint64_t __r21;
1164     uint64_t __r22;
1165     uint64_t __r23;
1166     uint64_t __r24;
1167     uint64_t __r25;
1168     uint64_t __r26;
1169     uint64_t __r27;
1170     uint64_t __r28;
1171     uint64_t __r29;
1172     uint64_t __r30;
1173     uint64_t __r31;
1174     uint64_t __cr;      // Condition register
1175     uint64_t __xer;     // User's integer exception register
1176     uint64_t __lr;      // Link register
1177     uint64_t __ctr;     // Count register
1178     uint64_t __vrsave;  // Vector Save Register
1179   };
1180 
1181   union ppc64_vsr_t {
1182     struct asfloat_s {
1183       double f;
1184       uint64_t v2;
1185     } asfloat;
1186     v128 v;
1187   };
1188 
1189   ppc64_thread_state_t _registers;
1190   ppc64_vsr_t          _vectorScalarRegisters[64];
1191 
1192   static int getVectorRegNum(int num);
1193 };
1194 
1195 inline Registers_ppc64::Registers_ppc64(const void *registers) {
1196   static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit),
1197                 "ppc64 registers do not fit into unw_context_t");
1198   memcpy(&_registers, static_cast<const uint8_t *>(registers),
1199          sizeof(_registers));
1200   static_assert(sizeof(_registers) == 312,
1201                 "expected vector scalar register offset to be 312");
1202   memcpy(&_vectorScalarRegisters,
1203          static_cast<const uint8_t *>(registers) + sizeof(_registers),
1204          sizeof(_vectorScalarRegisters));
1205   static_assert(sizeof(_registers) +
1206                 sizeof(_vectorScalarRegisters) == 1336,
1207                 "expected vector register offset to be 1336 bytes");
1208 }
1209 
1210 inline Registers_ppc64::Registers_ppc64() {
1211   memset(&_registers, 0, sizeof(_registers));
1212   memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters));
1213 }
1214 
1215 inline bool Registers_ppc64::validRegister(int regNum) const {
1216   switch (regNum) {
1217   case UNW_REG_IP:
1218   case UNW_REG_SP:
1219   case UNW_PPC64_XER:
1220   case UNW_PPC64_LR:
1221   case UNW_PPC64_CTR:
1222   case UNW_PPC64_VRSAVE:
1223       return true;
1224   }
1225 
1226   if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31)
1227     return true;
1228   if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7)
1229     return true;
1230 
1231   return false;
1232 }
1233 
1234 inline uint64_t Registers_ppc64::getRegister(int regNum) const {
1235   switch (regNum) {
1236   case UNW_REG_IP:
1237     return _registers.__srr0;
1238   case UNW_PPC64_R0:
1239     return _registers.__r0;
1240   case UNW_PPC64_R1:
1241   case UNW_REG_SP:
1242     return _registers.__r1;
1243   case UNW_PPC64_R2:
1244     return _registers.__r2;
1245   case UNW_PPC64_R3:
1246     return _registers.__r3;
1247   case UNW_PPC64_R4:
1248     return _registers.__r4;
1249   case UNW_PPC64_R5:
1250     return _registers.__r5;
1251   case UNW_PPC64_R6:
1252     return _registers.__r6;
1253   case UNW_PPC64_R7:
1254     return _registers.__r7;
1255   case UNW_PPC64_R8:
1256     return _registers.__r8;
1257   case UNW_PPC64_R9:
1258     return _registers.__r9;
1259   case UNW_PPC64_R10:
1260     return _registers.__r10;
1261   case UNW_PPC64_R11:
1262     return _registers.__r11;
1263   case UNW_PPC64_R12:
1264     return _registers.__r12;
1265   case UNW_PPC64_R13:
1266     return _registers.__r13;
1267   case UNW_PPC64_R14:
1268     return _registers.__r14;
1269   case UNW_PPC64_R15:
1270     return _registers.__r15;
1271   case UNW_PPC64_R16:
1272     return _registers.__r16;
1273   case UNW_PPC64_R17:
1274     return _registers.__r17;
1275   case UNW_PPC64_R18:
1276     return _registers.__r18;
1277   case UNW_PPC64_R19:
1278     return _registers.__r19;
1279   case UNW_PPC64_R20:
1280     return _registers.__r20;
1281   case UNW_PPC64_R21:
1282     return _registers.__r21;
1283   case UNW_PPC64_R22:
1284     return _registers.__r22;
1285   case UNW_PPC64_R23:
1286     return _registers.__r23;
1287   case UNW_PPC64_R24:
1288     return _registers.__r24;
1289   case UNW_PPC64_R25:
1290     return _registers.__r25;
1291   case UNW_PPC64_R26:
1292     return _registers.__r26;
1293   case UNW_PPC64_R27:
1294     return _registers.__r27;
1295   case UNW_PPC64_R28:
1296     return _registers.__r28;
1297   case UNW_PPC64_R29:
1298     return _registers.__r29;
1299   case UNW_PPC64_R30:
1300     return _registers.__r30;
1301   case UNW_PPC64_R31:
1302     return _registers.__r31;
1303   case UNW_PPC64_CR0:
1304     return (_registers.__cr & 0xF0000000);
1305   case UNW_PPC64_CR1:
1306     return (_registers.__cr & 0x0F000000);
1307   case UNW_PPC64_CR2:
1308     return (_registers.__cr & 0x00F00000);
1309   case UNW_PPC64_CR3:
1310     return (_registers.__cr & 0x000F0000);
1311   case UNW_PPC64_CR4:
1312     return (_registers.__cr & 0x0000F000);
1313   case UNW_PPC64_CR5:
1314     return (_registers.__cr & 0x00000F00);
1315   case UNW_PPC64_CR6:
1316     return (_registers.__cr & 0x000000F0);
1317   case UNW_PPC64_CR7:
1318     return (_registers.__cr & 0x0000000F);
1319   case UNW_PPC64_XER:
1320     return _registers.__xer;
1321   case UNW_PPC64_LR:
1322     return _registers.__lr;
1323   case UNW_PPC64_CTR:
1324     return _registers.__ctr;
1325   case UNW_PPC64_VRSAVE:
1326     return _registers.__vrsave;
1327   }
1328   _LIBUNWIND_ABORT("unsupported ppc64 register");
1329 }
1330 
1331 inline void Registers_ppc64::setRegister(int regNum, uint64_t value) {
1332   switch (regNum) {
1333   case UNW_REG_IP:
1334     _registers.__srr0 = value;
1335     return;
1336   case UNW_PPC64_R0:
1337     _registers.__r0 = value;
1338     return;
1339   case UNW_PPC64_R1:
1340   case UNW_REG_SP:
1341     _registers.__r1 = value;
1342     return;
1343   case UNW_PPC64_R2:
1344     _registers.__r2 = value;
1345     return;
1346   case UNW_PPC64_R3:
1347     _registers.__r3 = value;
1348     return;
1349   case UNW_PPC64_R4:
1350     _registers.__r4 = value;
1351     return;
1352   case UNW_PPC64_R5:
1353     _registers.__r5 = value;
1354     return;
1355   case UNW_PPC64_R6:
1356     _registers.__r6 = value;
1357     return;
1358   case UNW_PPC64_R7:
1359     _registers.__r7 = value;
1360     return;
1361   case UNW_PPC64_R8:
1362     _registers.__r8 = value;
1363     return;
1364   case UNW_PPC64_R9:
1365     _registers.__r9 = value;
1366     return;
1367   case UNW_PPC64_R10:
1368     _registers.__r10 = value;
1369     return;
1370   case UNW_PPC64_R11:
1371     _registers.__r11 = value;
1372     return;
1373   case UNW_PPC64_R12:
1374     _registers.__r12 = value;
1375     return;
1376   case UNW_PPC64_R13:
1377     _registers.__r13 = value;
1378     return;
1379   case UNW_PPC64_R14:
1380     _registers.__r14 = value;
1381     return;
1382   case UNW_PPC64_R15:
1383     _registers.__r15 = value;
1384     return;
1385   case UNW_PPC64_R16:
1386     _registers.__r16 = value;
1387     return;
1388   case UNW_PPC64_R17:
1389     _registers.__r17 = value;
1390     return;
1391   case UNW_PPC64_R18:
1392     _registers.__r18 = value;
1393     return;
1394   case UNW_PPC64_R19:
1395     _registers.__r19 = value;
1396     return;
1397   case UNW_PPC64_R20:
1398     _registers.__r20 = value;
1399     return;
1400   case UNW_PPC64_R21:
1401     _registers.__r21 = value;
1402     return;
1403   case UNW_PPC64_R22:
1404     _registers.__r22 = value;
1405     return;
1406   case UNW_PPC64_R23:
1407     _registers.__r23 = value;
1408     return;
1409   case UNW_PPC64_R24:
1410     _registers.__r24 = value;
1411     return;
1412   case UNW_PPC64_R25:
1413     _registers.__r25 = value;
1414     return;
1415   case UNW_PPC64_R26:
1416     _registers.__r26 = value;
1417     return;
1418   case UNW_PPC64_R27:
1419     _registers.__r27 = value;
1420     return;
1421   case UNW_PPC64_R28:
1422     _registers.__r28 = value;
1423     return;
1424   case UNW_PPC64_R29:
1425     _registers.__r29 = value;
1426     return;
1427   case UNW_PPC64_R30:
1428     _registers.__r30 = value;
1429     return;
1430   case UNW_PPC64_R31:
1431     _registers.__r31 = value;
1432     return;
1433   case UNW_PPC64_CR0:
1434     _registers.__cr &= 0x0FFFFFFF;
1435     _registers.__cr |= (value & 0xF0000000);
1436     return;
1437   case UNW_PPC64_CR1:
1438     _registers.__cr &= 0xF0FFFFFF;
1439     _registers.__cr |= (value & 0x0F000000);
1440     return;
1441   case UNW_PPC64_CR2:
1442     _registers.__cr &= 0xFF0FFFFF;
1443     _registers.__cr |= (value & 0x00F00000);
1444     return;
1445   case UNW_PPC64_CR3:
1446     _registers.__cr &= 0xFFF0FFFF;
1447     _registers.__cr |= (value & 0x000F0000);
1448     return;
1449   case UNW_PPC64_CR4:
1450     _registers.__cr &= 0xFFFF0FFF;
1451     _registers.__cr |= (value & 0x0000F000);
1452     return;
1453   case UNW_PPC64_CR5:
1454     _registers.__cr &= 0xFFFFF0FF;
1455     _registers.__cr |= (value & 0x00000F00);
1456     return;
1457   case UNW_PPC64_CR6:
1458     _registers.__cr &= 0xFFFFFF0F;
1459     _registers.__cr |= (value & 0x000000F0);
1460     return;
1461   case UNW_PPC64_CR7:
1462     _registers.__cr &= 0xFFFFFFF0;
1463     _registers.__cr |= (value & 0x0000000F);
1464     return;
1465   case UNW_PPC64_XER:
1466     _registers.__xer = value;
1467     return;
1468   case UNW_PPC64_LR:
1469     _registers.__lr = value;
1470     return;
1471   case UNW_PPC64_CTR:
1472     _registers.__ctr = value;
1473     return;
1474   case UNW_PPC64_VRSAVE:
1475     _registers.__vrsave = value;
1476     return;
1477   }
1478   _LIBUNWIND_ABORT("unsupported ppc64 register");
1479 }
1480 
1481 inline bool Registers_ppc64::validFloatRegister(int regNum) const {
1482   return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31;
1483 }
1484 
1485 inline double Registers_ppc64::getFloatRegister(int regNum) const {
1486   assert(validFloatRegister(regNum));
1487   return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f;
1488 }
1489 
1490 inline void Registers_ppc64::setFloatRegister(int regNum, double value) {
1491   assert(validFloatRegister(regNum));
1492   _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value;
1493 }
1494 
1495 inline bool Registers_ppc64::validVectorRegister(int regNum) const {
1496 #ifdef PPC64_HAS_VMX
1497   if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)
1498     return true;
1499   if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)
1500     return true;
1501 #else
1502   if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)
1503     return true;
1504 #endif
1505   return false;
1506 }
1507 
1508 inline int Registers_ppc64::getVectorRegNum(int num)
1509 {
1510   if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31)
1511     return num - UNW_PPC64_VS0;
1512   else
1513     return num - UNW_PPC64_VS32 + 32;
1514 }
1515 
1516 inline v128 Registers_ppc64::getVectorRegister(int regNum) const {
1517   assert(validVectorRegister(regNum));
1518   return _vectorScalarRegisters[getVectorRegNum(regNum)].v;
1519 }
1520 
1521 inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) {
1522   assert(validVectorRegister(regNum));
1523   _vectorScalarRegisters[getVectorRegNum(regNum)].v = value;
1524 }
1525 
1526 inline const char *Registers_ppc64::getRegisterName(int regNum) {
1527   switch (regNum) {
1528   case UNW_REG_IP:
1529     return "ip";
1530   case UNW_REG_SP:
1531     return "sp";
1532   case UNW_PPC64_R0:
1533     return "r0";
1534   case UNW_PPC64_R1:
1535     return "r1";
1536   case UNW_PPC64_R2:
1537     return "r2";
1538   case UNW_PPC64_R3:
1539     return "r3";
1540   case UNW_PPC64_R4:
1541     return "r4";
1542   case UNW_PPC64_R5:
1543     return "r5";
1544   case UNW_PPC64_R6:
1545     return "r6";
1546   case UNW_PPC64_R7:
1547     return "r7";
1548   case UNW_PPC64_R8:
1549     return "r8";
1550   case UNW_PPC64_R9:
1551     return "r9";
1552   case UNW_PPC64_R10:
1553     return "r10";
1554   case UNW_PPC64_R11:
1555     return "r11";
1556   case UNW_PPC64_R12:
1557     return "r12";
1558   case UNW_PPC64_R13:
1559     return "r13";
1560   case UNW_PPC64_R14:
1561     return "r14";
1562   case UNW_PPC64_R15:
1563     return "r15";
1564   case UNW_PPC64_R16:
1565     return "r16";
1566   case UNW_PPC64_R17:
1567     return "r17";
1568   case UNW_PPC64_R18:
1569     return "r18";
1570   case UNW_PPC64_R19:
1571     return "r19";
1572   case UNW_PPC64_R20:
1573     return "r20";
1574   case UNW_PPC64_R21:
1575     return "r21";
1576   case UNW_PPC64_R22:
1577     return "r22";
1578   case UNW_PPC64_R23:
1579     return "r23";
1580   case UNW_PPC64_R24:
1581     return "r24";
1582   case UNW_PPC64_R25:
1583     return "r25";
1584   case UNW_PPC64_R26:
1585     return "r26";
1586   case UNW_PPC64_R27:
1587     return "r27";
1588   case UNW_PPC64_R28:
1589     return "r28";
1590   case UNW_PPC64_R29:
1591     return "r29";
1592   case UNW_PPC64_R30:
1593     return "r30";
1594   case UNW_PPC64_R31:
1595     return "r31";
1596   case UNW_PPC64_CR0:
1597     return "cr0";
1598   case UNW_PPC64_CR1:
1599     return "cr1";
1600   case UNW_PPC64_CR2:
1601     return "cr2";
1602   case UNW_PPC64_CR3:
1603     return "cr3";
1604   case UNW_PPC64_CR4:
1605     return "cr4";
1606   case UNW_PPC64_CR5:
1607     return "cr5";
1608   case UNW_PPC64_CR6:
1609     return "cr6";
1610   case UNW_PPC64_CR7:
1611     return "cr7";
1612   case UNW_PPC64_XER:
1613     return "xer";
1614   case UNW_PPC64_LR:
1615     return "lr";
1616   case UNW_PPC64_CTR:
1617     return "ctr";
1618   case UNW_PPC64_VRSAVE:
1619     return "vrsave";
1620   case UNW_PPC64_F0:
1621     return "fp0";
1622   case UNW_PPC64_F1:
1623     return "fp1";
1624   case UNW_PPC64_F2:
1625     return "fp2";
1626   case UNW_PPC64_F3:
1627     return "fp3";
1628   case UNW_PPC64_F4:
1629     return "fp4";
1630   case UNW_PPC64_F5:
1631     return "fp5";
1632   case UNW_PPC64_F6:
1633     return "fp6";
1634   case UNW_PPC64_F7:
1635     return "fp7";
1636   case UNW_PPC64_F8:
1637     return "fp8";
1638   case UNW_PPC64_F9:
1639     return "fp9";
1640   case UNW_PPC64_F10:
1641     return "fp10";
1642   case UNW_PPC64_F11:
1643     return "fp11";
1644   case UNW_PPC64_F12:
1645     return "fp12";
1646   case UNW_PPC64_F13:
1647     return "fp13";
1648   case UNW_PPC64_F14:
1649     return "fp14";
1650   case UNW_PPC64_F15:
1651     return "fp15";
1652   case UNW_PPC64_F16:
1653     return "fp16";
1654   case UNW_PPC64_F17:
1655     return "fp17";
1656   case UNW_PPC64_F18:
1657     return "fp18";
1658   case UNW_PPC64_F19:
1659     return "fp19";
1660   case UNW_PPC64_F20:
1661     return "fp20";
1662   case UNW_PPC64_F21:
1663     return "fp21";
1664   case UNW_PPC64_F22:
1665     return "fp22";
1666   case UNW_PPC64_F23:
1667     return "fp23";
1668   case UNW_PPC64_F24:
1669     return "fp24";
1670   case UNW_PPC64_F25:
1671     return "fp25";
1672   case UNW_PPC64_F26:
1673     return "fp26";
1674   case UNW_PPC64_F27:
1675     return "fp27";
1676   case UNW_PPC64_F28:
1677     return "fp28";
1678   case UNW_PPC64_F29:
1679     return "fp29";
1680   case UNW_PPC64_F30:
1681     return "fp30";
1682   case UNW_PPC64_F31:
1683     return "fp31";
1684   case UNW_PPC64_V0:
1685     return "v0";
1686   case UNW_PPC64_V1:
1687     return "v1";
1688   case UNW_PPC64_V2:
1689     return "v2";
1690   case UNW_PPC64_V3:
1691     return "v3";
1692   case UNW_PPC64_V4:
1693     return "v4";
1694   case UNW_PPC64_V5:
1695     return "v5";
1696   case UNW_PPC64_V6:
1697     return "v6";
1698   case UNW_PPC64_V7:
1699     return "v7";
1700   case UNW_PPC64_V8:
1701     return "v8";
1702   case UNW_PPC64_V9:
1703     return "v9";
1704   case UNW_PPC64_V10:
1705     return "v10";
1706   case UNW_PPC64_V11:
1707     return "v11";
1708   case UNW_PPC64_V12:
1709     return "v12";
1710   case UNW_PPC64_V13:
1711     return "v13";
1712   case UNW_PPC64_V14:
1713     return "v14";
1714   case UNW_PPC64_V15:
1715     return "v15";
1716   case UNW_PPC64_V16:
1717     return "v16";
1718   case UNW_PPC64_V17:
1719     return "v17";
1720   case UNW_PPC64_V18:
1721     return "v18";
1722   case UNW_PPC64_V19:
1723     return "v19";
1724   case UNW_PPC64_V20:
1725     return "v20";
1726   case UNW_PPC64_V21:
1727     return "v21";
1728   case UNW_PPC64_V22:
1729     return "v22";
1730   case UNW_PPC64_V23:
1731     return "v23";
1732   case UNW_PPC64_V24:
1733     return "v24";
1734   case UNW_PPC64_V25:
1735     return "v25";
1736   case UNW_PPC64_V26:
1737     return "v26";
1738   case UNW_PPC64_V27:
1739     return "v27";
1740   case UNW_PPC64_V28:
1741     return "v28";
1742   case UNW_PPC64_V29:
1743     return "v29";
1744   case UNW_PPC64_V30:
1745     return "v30";
1746   case UNW_PPC64_V31:
1747     return "v31";
1748   }
1749   return "unknown register";
1750 }
1751 #endif // _LIBUNWIND_TARGET_PPC64
1752 
1753 
1754 #if defined(_LIBUNWIND_TARGET_AARCH64)
1755 /// Registers_arm64  holds the register state of a thread in a 64-bit arm
1756 /// process.
1757 class _LIBUNWIND_HIDDEN Registers_arm64 {
1758 public:
1759   Registers_arm64();
1760   Registers_arm64(const void *registers);
1761 
1762   bool        validRegister(int num) const;
1763   uint64_t    getRegister(int num) const;
1764   void        setRegister(int num, uint64_t value);
1765   bool        validFloatRegister(int num) const;
1766   double      getFloatRegister(int num) const;
1767   void        setFloatRegister(int num, double value);
1768   bool        validVectorRegister(int num) const;
1769   v128        getVectorRegister(int num) const;
1770   void        setVectorRegister(int num, v128 value);
1771   const char *getRegisterName(int num);
1772   void        jumpto();
1773   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
1774 
1775   uint64_t  getSP() const         { return _registers.__sp; }
1776   void      setSP(uint64_t value) { _registers.__sp = value; }
1777   uint64_t  getIP() const         { return _registers.__pc; }
1778   void      setIP(uint64_t value) { _registers.__pc = value; }
1779   uint64_t  getFP() const         { return _registers.__fp; }
1780   void      setFP(uint64_t value) { _registers.__fp = value; }
1781 
1782 private:
1783   struct GPRs {
1784     uint64_t __x[29]; // x0-x28
1785     uint64_t __fp;    // Frame pointer x29
1786     uint64_t __lr;    // Link register x30
1787     uint64_t __sp;    // Stack pointer x31
1788     uint64_t __pc;    // Program counter
1789     uint64_t padding; // 16-byte align
1790   };
1791 
1792   GPRs    _registers;
1793   double  _vectorHalfRegisters[32];
1794   // Currently only the lower double in 128-bit vectore registers
1795   // is perserved during unwinding.  We could define new register
1796   // numbers (> 96) which mean whole vector registers, then this
1797   // struct would need to change to contain whole vector registers.
1798 };
1799 
1800 inline Registers_arm64::Registers_arm64(const void *registers) {
1801   static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
1802                 "arm64 registers do not fit into unw_context_t");
1803   memcpy(&_registers, registers, sizeof(_registers));
1804   static_assert(sizeof(GPRs) == 0x110,
1805                 "expected VFP registers to be at offset 272");
1806   memcpy(_vectorHalfRegisters,
1807          static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1808          sizeof(_vectorHalfRegisters));
1809 }
1810 
1811 inline Registers_arm64::Registers_arm64() {
1812   memset(&_registers, 0, sizeof(_registers));
1813   memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1814 }
1815 
1816 inline bool Registers_arm64::validRegister(int regNum) const {
1817   if (regNum == UNW_REG_IP)
1818     return true;
1819   if (regNum == UNW_REG_SP)
1820     return true;
1821   if (regNum < 0)
1822     return false;
1823   if (regNum > 95)
1824     return false;
1825   if ((regNum > 31) && (regNum < 64))
1826     return false;
1827   return true;
1828 }
1829 
1830 inline uint64_t Registers_arm64::getRegister(int regNum) const {
1831   if (regNum == UNW_REG_IP)
1832     return _registers.__pc;
1833   if (regNum == UNW_REG_SP)
1834     return _registers.__sp;
1835   if ((regNum >= 0) && (regNum < 32))
1836     return _registers.__x[regNum];
1837   _LIBUNWIND_ABORT("unsupported arm64 register");
1838 }
1839 
1840 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1841   if (regNum == UNW_REG_IP)
1842     _registers.__pc = value;
1843   else if (regNum == UNW_REG_SP)
1844     _registers.__sp = value;
1845   else if ((regNum >= 0) && (regNum < 32))
1846     _registers.__x[regNum] = value;
1847   else
1848     _LIBUNWIND_ABORT("unsupported arm64 register");
1849 }
1850 
1851 inline const char *Registers_arm64::getRegisterName(int regNum) {
1852   switch (regNum) {
1853   case UNW_REG_IP:
1854     return "pc";
1855   case UNW_REG_SP:
1856     return "sp";
1857   case UNW_ARM64_X0:
1858     return "x0";
1859   case UNW_ARM64_X1:
1860     return "x1";
1861   case UNW_ARM64_X2:
1862     return "x2";
1863   case UNW_ARM64_X3:
1864     return "x3";
1865   case UNW_ARM64_X4:
1866     return "x4";
1867   case UNW_ARM64_X5:
1868     return "x5";
1869   case UNW_ARM64_X6:
1870     return "x6";
1871   case UNW_ARM64_X7:
1872     return "x7";
1873   case UNW_ARM64_X8:
1874     return "x8";
1875   case UNW_ARM64_X9:
1876     return "x9";
1877   case UNW_ARM64_X10:
1878     return "x10";
1879   case UNW_ARM64_X11:
1880     return "x11";
1881   case UNW_ARM64_X12:
1882     return "x12";
1883   case UNW_ARM64_X13:
1884     return "x13";
1885   case UNW_ARM64_X14:
1886     return "x14";
1887   case UNW_ARM64_X15:
1888     return "x15";
1889   case UNW_ARM64_X16:
1890     return "x16";
1891   case UNW_ARM64_X17:
1892     return "x17";
1893   case UNW_ARM64_X18:
1894     return "x18";
1895   case UNW_ARM64_X19:
1896     return "x19";
1897   case UNW_ARM64_X20:
1898     return "x20";
1899   case UNW_ARM64_X21:
1900     return "x21";
1901   case UNW_ARM64_X22:
1902     return "x22";
1903   case UNW_ARM64_X23:
1904     return "x23";
1905   case UNW_ARM64_X24:
1906     return "x24";
1907   case UNW_ARM64_X25:
1908     return "x25";
1909   case UNW_ARM64_X26:
1910     return "x26";
1911   case UNW_ARM64_X27:
1912     return "x27";
1913   case UNW_ARM64_X28:
1914     return "x28";
1915   case UNW_ARM64_X29:
1916     return "fp";
1917   case UNW_ARM64_X30:
1918     return "lr";
1919   case UNW_ARM64_X31:
1920     return "sp";
1921   case UNW_ARM64_D0:
1922     return "d0";
1923   case UNW_ARM64_D1:
1924     return "d1";
1925   case UNW_ARM64_D2:
1926     return "d2";
1927   case UNW_ARM64_D3:
1928     return "d3";
1929   case UNW_ARM64_D4:
1930     return "d4";
1931   case UNW_ARM64_D5:
1932     return "d5";
1933   case UNW_ARM64_D6:
1934     return "d6";
1935   case UNW_ARM64_D7:
1936     return "d7";
1937   case UNW_ARM64_D8:
1938     return "d8";
1939   case UNW_ARM64_D9:
1940     return "d9";
1941   case UNW_ARM64_D10:
1942     return "d10";
1943   case UNW_ARM64_D11:
1944     return "d11";
1945   case UNW_ARM64_D12:
1946     return "d12";
1947   case UNW_ARM64_D13:
1948     return "d13";
1949   case UNW_ARM64_D14:
1950     return "d14";
1951   case UNW_ARM64_D15:
1952     return "d15";
1953   case UNW_ARM64_D16:
1954     return "d16";
1955   case UNW_ARM64_D17:
1956     return "d17";
1957   case UNW_ARM64_D18:
1958     return "d18";
1959   case UNW_ARM64_D19:
1960     return "d19";
1961   case UNW_ARM64_D20:
1962     return "d20";
1963   case UNW_ARM64_D21:
1964     return "d21";
1965   case UNW_ARM64_D22:
1966     return "d22";
1967   case UNW_ARM64_D23:
1968     return "d23";
1969   case UNW_ARM64_D24:
1970     return "d24";
1971   case UNW_ARM64_D25:
1972     return "d25";
1973   case UNW_ARM64_D26:
1974     return "d26";
1975   case UNW_ARM64_D27:
1976     return "d27";
1977   case UNW_ARM64_D28:
1978     return "d28";
1979   case UNW_ARM64_D29:
1980     return "d29";
1981   case UNW_ARM64_D30:
1982     return "d30";
1983   case UNW_ARM64_D31:
1984     return "d31";
1985   default:
1986     return "unknown register";
1987   }
1988 }
1989 
1990 inline bool Registers_arm64::validFloatRegister(int regNum) const {
1991   if (regNum < UNW_ARM64_D0)
1992     return false;
1993   if (regNum > UNW_ARM64_D31)
1994     return false;
1995   return true;
1996 }
1997 
1998 inline double Registers_arm64::getFloatRegister(int regNum) const {
1999   assert(validFloatRegister(regNum));
2000   return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
2001 }
2002 
2003 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
2004   assert(validFloatRegister(regNum));
2005   _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
2006 }
2007 
2008 inline bool Registers_arm64::validVectorRegister(int) const {
2009   return false;
2010 }
2011 
2012 inline v128 Registers_arm64::getVectorRegister(int) const {
2013   _LIBUNWIND_ABORT("no arm64 vector register support yet");
2014 }
2015 
2016 inline void Registers_arm64::setVectorRegister(int, v128) {
2017   _LIBUNWIND_ABORT("no arm64 vector register support yet");
2018 }
2019 #endif // _LIBUNWIND_TARGET_AARCH64
2020 
2021 #if defined(_LIBUNWIND_TARGET_ARM)
2022 /// Registers_arm holds the register state of a thread in a 32-bit arm
2023 /// process.
2024 ///
2025 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
2026 /// this uses more memory than required.
2027 class _LIBUNWIND_HIDDEN Registers_arm {
2028 public:
2029   Registers_arm();
2030   Registers_arm(const void *registers);
2031 
2032   bool        validRegister(int num) const;
2033   uint32_t    getRegister(int num) const;
2034   void        setRegister(int num, uint32_t value);
2035   bool        validFloatRegister(int num) const;
2036   unw_fpreg_t getFloatRegister(int num);
2037   void        setFloatRegister(int num, unw_fpreg_t value);
2038   bool        validVectorRegister(int num) const;
2039   v128        getVectorRegister(int num) const;
2040   void        setVectorRegister(int num, v128 value);
2041   const char *getRegisterName(int num);
2042   void        jumpto() {
2043     restoreSavedFloatRegisters();
2044     restoreCoreAndJumpTo();
2045   }
2046   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; }
2047 
2048   uint32_t  getSP() const         { return _registers.__sp; }
2049   void      setSP(uint32_t value) { _registers.__sp = value; }
2050   uint32_t  getIP() const         { return _registers.__pc; }
2051   void      setIP(uint32_t value) { _registers.__pc = value; }
2052 
2053   void saveVFPAsX() {
2054     assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
2055     _use_X_for_vfp_save = true;
2056   }
2057 
2058   void restoreSavedFloatRegisters() {
2059     if (_saved_vfp_d0_d15) {
2060       if (_use_X_for_vfp_save)
2061         restoreVFPWithFLDMX(_vfp_d0_d15_pad);
2062       else
2063         restoreVFPWithFLDMD(_vfp_d0_d15_pad);
2064     }
2065     if (_saved_vfp_d16_d31)
2066       restoreVFPv3(_vfp_d16_d31);
2067 #if defined(__ARM_WMMX)
2068     if (_saved_iwmmx)
2069       restoreiWMMX(_iwmmx);
2070     if (_saved_iwmmx_control)
2071       restoreiWMMXControl(_iwmmx_control);
2072 #endif
2073   }
2074 
2075 private:
2076   struct GPRs {
2077     uint32_t __r[13]; // r0-r12
2078     uint32_t __sp;    // Stack pointer r13
2079     uint32_t __lr;    // Link register r14
2080     uint32_t __pc;    // Program counter r15
2081   };
2082 
2083   static void saveVFPWithFSTMD(unw_fpreg_t*);
2084   static void saveVFPWithFSTMX(unw_fpreg_t*);
2085   static void saveVFPv3(unw_fpreg_t*);
2086   static void restoreVFPWithFLDMD(unw_fpreg_t*);
2087   static void restoreVFPWithFLDMX(unw_fpreg_t*);
2088   static void restoreVFPv3(unw_fpreg_t*);
2089 #if defined(__ARM_WMMX)
2090   static void saveiWMMX(unw_fpreg_t*);
2091   static void saveiWMMXControl(uint32_t*);
2092   static void restoreiWMMX(unw_fpreg_t*);
2093   static void restoreiWMMXControl(uint32_t*);
2094 #endif
2095   void restoreCoreAndJumpTo();
2096 
2097   // ARM registers
2098   GPRs _registers;
2099 
2100   // We save floating point registers lazily because we can't know ahead of
2101   // time which ones are used. See EHABI #4.7.
2102 
2103   // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
2104   //
2105   // See EHABI #7.5 that explains how matching instruction sequences for load
2106   // and store need to be used to correctly restore the exact register bits.
2107   bool _use_X_for_vfp_save;
2108   // Whether VFP D0-D15 are saved.
2109   bool _saved_vfp_d0_d15;
2110   // Whether VFPv3 D16-D31 are saved.
2111   bool _saved_vfp_d16_d31;
2112   // VFP registers D0-D15, + padding if saved using FSTMX
2113   unw_fpreg_t _vfp_d0_d15_pad[17];
2114   // VFPv3 registers D16-D31, always saved using FSTMD
2115   unw_fpreg_t _vfp_d16_d31[16];
2116 #if defined(__ARM_WMMX)
2117   // Whether iWMMX data registers are saved.
2118   bool _saved_iwmmx;
2119   // Whether iWMMX control registers are saved.
2120   mutable bool _saved_iwmmx_control;
2121   // iWMMX registers
2122   unw_fpreg_t _iwmmx[16];
2123   // iWMMX control registers
2124   mutable uint32_t _iwmmx_control[4];
2125 #endif
2126 };
2127 
2128 inline Registers_arm::Registers_arm(const void *registers)
2129   : _use_X_for_vfp_save(false),
2130     _saved_vfp_d0_d15(false),
2131     _saved_vfp_d16_d31(false) {
2132   static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
2133                 "arm registers do not fit into unw_context_t");
2134   // See unw_getcontext() note about data.
2135   memcpy(&_registers, registers, sizeof(_registers));
2136   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2137   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2138 #if defined(__ARM_WMMX)
2139   _saved_iwmmx = false;
2140   _saved_iwmmx_control = false;
2141   memset(&_iwmmx, 0, sizeof(_iwmmx));
2142   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2143 #endif
2144 }
2145 
2146 inline Registers_arm::Registers_arm()
2147   : _use_X_for_vfp_save(false),
2148     _saved_vfp_d0_d15(false),
2149     _saved_vfp_d16_d31(false) {
2150   memset(&_registers, 0, sizeof(_registers));
2151   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2152   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2153 #if defined(__ARM_WMMX)
2154   _saved_iwmmx = false;
2155   _saved_iwmmx_control = false;
2156   memset(&_iwmmx, 0, sizeof(_iwmmx));
2157   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2158 #endif
2159 }
2160 
2161 inline bool Registers_arm::validRegister(int regNum) const {
2162   // Returns true for all non-VFP registers supported by the EHABI
2163   // virtual register set (VRS).
2164   if (regNum == UNW_REG_IP)
2165     return true;
2166 
2167   if (regNum == UNW_REG_SP)
2168     return true;
2169 
2170   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
2171     return true;
2172 
2173 #if defined(__ARM_WMMX)
2174   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
2175     return true;
2176 #endif
2177 
2178   return false;
2179 }
2180 
2181 inline uint32_t Registers_arm::getRegister(int regNum) const {
2182   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
2183     return _registers.__sp;
2184 
2185   if (regNum == UNW_ARM_LR)
2186     return _registers.__lr;
2187 
2188   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
2189     return _registers.__pc;
2190 
2191   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
2192     return _registers.__r[regNum];
2193 
2194 #if defined(__ARM_WMMX)
2195   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2196     if (!_saved_iwmmx_control) {
2197       _saved_iwmmx_control = true;
2198       saveiWMMXControl(_iwmmx_control);
2199     }
2200     return _iwmmx_control[regNum - UNW_ARM_WC0];
2201   }
2202 #endif
2203 
2204   _LIBUNWIND_ABORT("unsupported arm register");
2205 }
2206 
2207 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
2208   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
2209     _registers.__sp = value;
2210     return;
2211   }
2212 
2213   if (regNum == UNW_ARM_LR) {
2214     _registers.__lr = value;
2215     return;
2216   }
2217 
2218   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
2219     _registers.__pc = value;
2220     return;
2221   }
2222 
2223   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
2224     _registers.__r[regNum] = value;
2225     return;
2226   }
2227 
2228 #if defined(__ARM_WMMX)
2229   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2230     if (!_saved_iwmmx_control) {
2231       _saved_iwmmx_control = true;
2232       saveiWMMXControl(_iwmmx_control);
2233     }
2234     _iwmmx_control[regNum - UNW_ARM_WC0] = value;
2235     return;
2236   }
2237 #endif
2238 
2239   _LIBUNWIND_ABORT("unsupported arm register");
2240 }
2241 
2242 inline const char *Registers_arm::getRegisterName(int regNum) {
2243   switch (regNum) {
2244   case UNW_REG_IP:
2245   case UNW_ARM_IP: // UNW_ARM_R15 is alias
2246     return "pc";
2247   case UNW_ARM_LR: // UNW_ARM_R14 is alias
2248     return "lr";
2249   case UNW_REG_SP:
2250   case UNW_ARM_SP: // UNW_ARM_R13 is alias
2251     return "sp";
2252   case UNW_ARM_R0:
2253     return "r0";
2254   case UNW_ARM_R1:
2255     return "r1";
2256   case UNW_ARM_R2:
2257     return "r2";
2258   case UNW_ARM_R3:
2259     return "r3";
2260   case UNW_ARM_R4:
2261     return "r4";
2262   case UNW_ARM_R5:
2263     return "r5";
2264   case UNW_ARM_R6:
2265     return "r6";
2266   case UNW_ARM_R7:
2267     return "r7";
2268   case UNW_ARM_R8:
2269     return "r8";
2270   case UNW_ARM_R9:
2271     return "r9";
2272   case UNW_ARM_R10:
2273     return "r10";
2274   case UNW_ARM_R11:
2275     return "r11";
2276   case UNW_ARM_R12:
2277     return "r12";
2278   case UNW_ARM_S0:
2279     return "s0";
2280   case UNW_ARM_S1:
2281     return "s1";
2282   case UNW_ARM_S2:
2283     return "s2";
2284   case UNW_ARM_S3:
2285     return "s3";
2286   case UNW_ARM_S4:
2287     return "s4";
2288   case UNW_ARM_S5:
2289     return "s5";
2290   case UNW_ARM_S6:
2291     return "s6";
2292   case UNW_ARM_S7:
2293     return "s7";
2294   case UNW_ARM_S8:
2295     return "s8";
2296   case UNW_ARM_S9:
2297     return "s9";
2298   case UNW_ARM_S10:
2299     return "s10";
2300   case UNW_ARM_S11:
2301     return "s11";
2302   case UNW_ARM_S12:
2303     return "s12";
2304   case UNW_ARM_S13:
2305     return "s13";
2306   case UNW_ARM_S14:
2307     return "s14";
2308   case UNW_ARM_S15:
2309     return "s15";
2310   case UNW_ARM_S16:
2311     return "s16";
2312   case UNW_ARM_S17:
2313     return "s17";
2314   case UNW_ARM_S18:
2315     return "s18";
2316   case UNW_ARM_S19:
2317     return "s19";
2318   case UNW_ARM_S20:
2319     return "s20";
2320   case UNW_ARM_S21:
2321     return "s21";
2322   case UNW_ARM_S22:
2323     return "s22";
2324   case UNW_ARM_S23:
2325     return "s23";
2326   case UNW_ARM_S24:
2327     return "s24";
2328   case UNW_ARM_S25:
2329     return "s25";
2330   case UNW_ARM_S26:
2331     return "s26";
2332   case UNW_ARM_S27:
2333     return "s27";
2334   case UNW_ARM_S28:
2335     return "s28";
2336   case UNW_ARM_S29:
2337     return "s29";
2338   case UNW_ARM_S30:
2339     return "s30";
2340   case UNW_ARM_S31:
2341     return "s31";
2342   case UNW_ARM_D0:
2343     return "d0";
2344   case UNW_ARM_D1:
2345     return "d1";
2346   case UNW_ARM_D2:
2347     return "d2";
2348   case UNW_ARM_D3:
2349     return "d3";
2350   case UNW_ARM_D4:
2351     return "d4";
2352   case UNW_ARM_D5:
2353     return "d5";
2354   case UNW_ARM_D6:
2355     return "d6";
2356   case UNW_ARM_D7:
2357     return "d7";
2358   case UNW_ARM_D8:
2359     return "d8";
2360   case UNW_ARM_D9:
2361     return "d9";
2362   case UNW_ARM_D10:
2363     return "d10";
2364   case UNW_ARM_D11:
2365     return "d11";
2366   case UNW_ARM_D12:
2367     return "d12";
2368   case UNW_ARM_D13:
2369     return "d13";
2370   case UNW_ARM_D14:
2371     return "d14";
2372   case UNW_ARM_D15:
2373     return "d15";
2374   case UNW_ARM_D16:
2375     return "d16";
2376   case UNW_ARM_D17:
2377     return "d17";
2378   case UNW_ARM_D18:
2379     return "d18";
2380   case UNW_ARM_D19:
2381     return "d19";
2382   case UNW_ARM_D20:
2383     return "d20";
2384   case UNW_ARM_D21:
2385     return "d21";
2386   case UNW_ARM_D22:
2387     return "d22";
2388   case UNW_ARM_D23:
2389     return "d23";
2390   case UNW_ARM_D24:
2391     return "d24";
2392   case UNW_ARM_D25:
2393     return "d25";
2394   case UNW_ARM_D26:
2395     return "d26";
2396   case UNW_ARM_D27:
2397     return "d27";
2398   case UNW_ARM_D28:
2399     return "d28";
2400   case UNW_ARM_D29:
2401     return "d29";
2402   case UNW_ARM_D30:
2403     return "d30";
2404   case UNW_ARM_D31:
2405     return "d31";
2406   default:
2407     return "unknown register";
2408   }
2409 }
2410 
2411 inline bool Registers_arm::validFloatRegister(int regNum) const {
2412   // NOTE: Consider the intel MMX registers floating points so the
2413   // unw_get_fpreg can be used to transmit the 64-bit data back.
2414   return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
2415 #if defined(__ARM_WMMX)
2416       || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
2417 #endif
2418       ;
2419 }
2420 
2421 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
2422   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2423     if (!_saved_vfp_d0_d15) {
2424       _saved_vfp_d0_d15 = true;
2425       if (_use_X_for_vfp_save)
2426         saveVFPWithFSTMX(_vfp_d0_d15_pad);
2427       else
2428         saveVFPWithFSTMD(_vfp_d0_d15_pad);
2429     }
2430     return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
2431   }
2432 
2433   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2434     if (!_saved_vfp_d16_d31) {
2435       _saved_vfp_d16_d31 = true;
2436       saveVFPv3(_vfp_d16_d31);
2437     }
2438     return _vfp_d16_d31[regNum - UNW_ARM_D16];
2439   }
2440 
2441 #if defined(__ARM_WMMX)
2442   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2443     if (!_saved_iwmmx) {
2444       _saved_iwmmx = true;
2445       saveiWMMX(_iwmmx);
2446     }
2447     return _iwmmx[regNum - UNW_ARM_WR0];
2448   }
2449 #endif
2450 
2451   _LIBUNWIND_ABORT("Unknown ARM float register");
2452 }
2453 
2454 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
2455   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2456     if (!_saved_vfp_d0_d15) {
2457       _saved_vfp_d0_d15 = true;
2458       if (_use_X_for_vfp_save)
2459         saveVFPWithFSTMX(_vfp_d0_d15_pad);
2460       else
2461         saveVFPWithFSTMD(_vfp_d0_d15_pad);
2462     }
2463     _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
2464     return;
2465   }
2466 
2467   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2468     if (!_saved_vfp_d16_d31) {
2469       _saved_vfp_d16_d31 = true;
2470       saveVFPv3(_vfp_d16_d31);
2471     }
2472     _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
2473     return;
2474   }
2475 
2476 #if defined(__ARM_WMMX)
2477   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2478     if (!_saved_iwmmx) {
2479       _saved_iwmmx = true;
2480       saveiWMMX(_iwmmx);
2481     }
2482     _iwmmx[regNum - UNW_ARM_WR0] = value;
2483     return;
2484   }
2485 #endif
2486 
2487   _LIBUNWIND_ABORT("Unknown ARM float register");
2488 }
2489 
2490 inline bool Registers_arm::validVectorRegister(int) const {
2491   return false;
2492 }
2493 
2494 inline v128 Registers_arm::getVectorRegister(int) const {
2495   _LIBUNWIND_ABORT("ARM vector support not implemented");
2496 }
2497 
2498 inline void Registers_arm::setVectorRegister(int, v128) {
2499   _LIBUNWIND_ABORT("ARM vector support not implemented");
2500 }
2501 #endif // _LIBUNWIND_TARGET_ARM
2502 
2503 
2504 #if defined(_LIBUNWIND_TARGET_OR1K)
2505 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
2506 /// process.
2507 class _LIBUNWIND_HIDDEN Registers_or1k {
2508 public:
2509   Registers_or1k();
2510   Registers_or1k(const void *registers);
2511 
2512   bool        validRegister(int num) const;
2513   uint32_t    getRegister(int num) const;
2514   void        setRegister(int num, uint32_t value);
2515   bool        validFloatRegister(int num) const;
2516   double      getFloatRegister(int num) const;
2517   void        setFloatRegister(int num, double value);
2518   bool        validVectorRegister(int num) const;
2519   v128        getVectorRegister(int num) const;
2520   void        setVectorRegister(int num, v128 value);
2521   const char *getRegisterName(int num);
2522   void        jumpto();
2523   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; }
2524 
2525   uint64_t  getSP() const         { return _registers.__r[1]; }
2526   void      setSP(uint32_t value) { _registers.__r[1] = value; }
2527   uint64_t  getIP() const         { return _registers.__pc; }
2528   void      setIP(uint32_t value) { _registers.__pc = value; }
2529 
2530 private:
2531   struct or1k_thread_state_t {
2532     unsigned int __r[32]; // r0-r31
2533     unsigned int __pc;    // Program counter
2534     unsigned int __epcr;  // Program counter at exception
2535   };
2536 
2537   or1k_thread_state_t _registers;
2538 };
2539 
2540 inline Registers_or1k::Registers_or1k(const void *registers) {
2541   static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
2542                 "or1k registers do not fit into unw_context_t");
2543   memcpy(&_registers, static_cast<const uint8_t *>(registers),
2544          sizeof(_registers));
2545 }
2546 
2547 inline Registers_or1k::Registers_or1k() {
2548   memset(&_registers, 0, sizeof(_registers));
2549 }
2550 
2551 inline bool Registers_or1k::validRegister(int regNum) const {
2552   if (regNum == UNW_REG_IP)
2553     return true;
2554   if (regNum == UNW_REG_SP)
2555     return true;
2556   if (regNum < 0)
2557     return false;
2558   if (regNum <= UNW_OR1K_R31)
2559     return true;
2560   if (regNum == UNW_OR1K_EPCR)
2561     return true;
2562   return false;
2563 }
2564 
2565 inline uint32_t Registers_or1k::getRegister(int regNum) const {
2566   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
2567     return _registers.__r[regNum - UNW_OR1K_R0];
2568 
2569   switch (regNum) {
2570   case UNW_REG_IP:
2571     return _registers.__pc;
2572   case UNW_REG_SP:
2573     return _registers.__r[1];
2574   case UNW_OR1K_EPCR:
2575     return _registers.__epcr;
2576   }
2577   _LIBUNWIND_ABORT("unsupported or1k register");
2578 }
2579 
2580 inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
2581   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
2582     _registers.__r[regNum - UNW_OR1K_R0] = value;
2583     return;
2584   }
2585 
2586   switch (regNum) {
2587   case UNW_REG_IP:
2588     _registers.__pc = value;
2589     return;
2590   case UNW_REG_SP:
2591     _registers.__r[1] = value;
2592     return;
2593   case UNW_OR1K_EPCR:
2594     _registers.__epcr = value;
2595     return;
2596   }
2597   _LIBUNWIND_ABORT("unsupported or1k register");
2598 }
2599 
2600 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
2601   return false;
2602 }
2603 
2604 inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
2605   _LIBUNWIND_ABORT("or1k float support not implemented");
2606 }
2607 
2608 inline void Registers_or1k::setFloatRegister(int /* regNum */,
2609                                              double /* value */) {
2610   _LIBUNWIND_ABORT("or1k float support not implemented");
2611 }
2612 
2613 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
2614   return false;
2615 }
2616 
2617 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
2618   _LIBUNWIND_ABORT("or1k vector support not implemented");
2619 }
2620 
2621 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
2622   _LIBUNWIND_ABORT("or1k vector support not implemented");
2623 }
2624 
2625 inline const char *Registers_or1k::getRegisterName(int regNum) {
2626   switch (regNum) {
2627   case UNW_OR1K_R0:
2628     return "r0";
2629   case UNW_OR1K_R1:
2630     return "r1";
2631   case UNW_OR1K_R2:
2632     return "r2";
2633   case UNW_OR1K_R3:
2634     return "r3";
2635   case UNW_OR1K_R4:
2636     return "r4";
2637   case UNW_OR1K_R5:
2638     return "r5";
2639   case UNW_OR1K_R6:
2640     return "r6";
2641   case UNW_OR1K_R7:
2642     return "r7";
2643   case UNW_OR1K_R8:
2644     return "r8";
2645   case UNW_OR1K_R9:
2646     return "r9";
2647   case UNW_OR1K_R10:
2648     return "r10";
2649   case UNW_OR1K_R11:
2650     return "r11";
2651   case UNW_OR1K_R12:
2652     return "r12";
2653   case UNW_OR1K_R13:
2654     return "r13";
2655   case UNW_OR1K_R14:
2656     return "r14";
2657   case UNW_OR1K_R15:
2658     return "r15";
2659   case UNW_OR1K_R16:
2660     return "r16";
2661   case UNW_OR1K_R17:
2662     return "r17";
2663   case UNW_OR1K_R18:
2664     return "r18";
2665   case UNW_OR1K_R19:
2666     return "r19";
2667   case UNW_OR1K_R20:
2668     return "r20";
2669   case UNW_OR1K_R21:
2670     return "r21";
2671   case UNW_OR1K_R22:
2672     return "r22";
2673   case UNW_OR1K_R23:
2674     return "r23";
2675   case UNW_OR1K_R24:
2676     return "r24";
2677   case UNW_OR1K_R25:
2678     return "r25";
2679   case UNW_OR1K_R26:
2680     return "r26";
2681   case UNW_OR1K_R27:
2682     return "r27";
2683   case UNW_OR1K_R28:
2684     return "r28";
2685   case UNW_OR1K_R29:
2686     return "r29";
2687   case UNW_OR1K_R30:
2688     return "r30";
2689   case UNW_OR1K_R31:
2690     return "r31";
2691   case UNW_OR1K_EPCR:
2692     return "EPCR";
2693   default:
2694     return "unknown register";
2695   }
2696 
2697 }
2698 #endif // _LIBUNWIND_TARGET_OR1K
2699 
2700 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
2701 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
2702 /// process.
2703 class _LIBUNWIND_HIDDEN Registers_mips_o32 {
2704 public:
2705   Registers_mips_o32();
2706   Registers_mips_o32(const void *registers);
2707 
2708   bool        validRegister(int num) const;
2709   uint32_t    getRegister(int num) const;
2710   void        setRegister(int num, uint32_t value);
2711   bool        validFloatRegister(int num) const;
2712   double      getFloatRegister(int num) const;
2713   void        setFloatRegister(int num, double value);
2714   bool        validVectorRegister(int num) const;
2715   v128        getVectorRegister(int num) const;
2716   void        setVectorRegister(int num, v128 value);
2717   const char *getRegisterName(int num);
2718   void        jumpto();
2719   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
2720 
2721   uint32_t  getSP() const         { return _registers.__r[29]; }
2722   void      setSP(uint32_t value) { _registers.__r[29] = value; }
2723   uint32_t  getIP() const         { return _registers.__pc; }
2724   void      setIP(uint32_t value) { _registers.__pc = value; }
2725 
2726 private:
2727   struct mips_o32_thread_state_t {
2728     uint32_t __r[32];
2729     uint32_t __pc;
2730     uint32_t __hi;
2731     uint32_t __lo;
2732   };
2733 
2734   mips_o32_thread_state_t _registers;
2735 #ifdef __mips_hard_float
2736   /// O32 with 32-bit floating point registers only uses half of this
2737   /// space.  However, using the same layout for 32-bit vs 64-bit
2738   /// floating point registers results in a single context size for
2739   /// O32 with hard float.
2740   uint32_t _padding;
2741   double _floats[32];
2742 #endif
2743 };
2744 
2745 inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
2746   static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
2747                 "mips_o32 registers do not fit into unw_context_t");
2748   memcpy(&_registers, static_cast<const uint8_t *>(registers),
2749          sizeof(_registers));
2750 }
2751 
2752 inline Registers_mips_o32::Registers_mips_o32() {
2753   memset(&_registers, 0, sizeof(_registers));
2754 }
2755 
2756 inline bool Registers_mips_o32::validRegister(int regNum) const {
2757   if (regNum == UNW_REG_IP)
2758     return true;
2759   if (regNum == UNW_REG_SP)
2760     return true;
2761   if (regNum < 0)
2762     return false;
2763   if (regNum <= UNW_MIPS_R31)
2764     return true;
2765 #if __mips_isa_rev != 6
2766   if (regNum == UNW_MIPS_HI)
2767     return true;
2768   if (regNum == UNW_MIPS_LO)
2769     return true;
2770 #endif
2771 #if defined(__mips_hard_float) && __mips_fpr == 32
2772   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2773     return true;
2774 #endif
2775   // FIXME: DSP accumulator registers, MSA registers
2776   return false;
2777 }
2778 
2779 inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
2780   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
2781     return _registers.__r[regNum - UNW_MIPS_R0];
2782 #if defined(__mips_hard_float) && __mips_fpr == 32
2783   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2784     uint32_t *p;
2785 
2786     if (regNum % 2 == 0)
2787       p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2788     else
2789       p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2790     return *p;
2791   }
2792 #endif
2793 
2794   switch (regNum) {
2795   case UNW_REG_IP:
2796     return _registers.__pc;
2797   case UNW_REG_SP:
2798     return _registers.__r[29];
2799   case UNW_MIPS_HI:
2800     return _registers.__hi;
2801   case UNW_MIPS_LO:
2802     return _registers.__lo;
2803   }
2804   _LIBUNWIND_ABORT("unsupported mips_o32 register");
2805 }
2806 
2807 inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
2808   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
2809     _registers.__r[regNum - UNW_MIPS_R0] = value;
2810     return;
2811   }
2812 #if defined(__mips_hard_float) && __mips_fpr == 32
2813   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2814     uint32_t *p;
2815 
2816     if (regNum % 2 == 0)
2817       p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2818     else
2819       p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2820     *p = value;
2821     return;
2822   }
2823 #endif
2824 
2825   switch (regNum) {
2826   case UNW_REG_IP:
2827     _registers.__pc = value;
2828     return;
2829   case UNW_REG_SP:
2830     _registers.__r[29] = value;
2831     return;
2832   case UNW_MIPS_HI:
2833     _registers.__hi = value;
2834     return;
2835   case UNW_MIPS_LO:
2836     _registers.__lo = value;
2837     return;
2838   }
2839   _LIBUNWIND_ABORT("unsupported mips_o32 register");
2840 }
2841 
2842 inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
2843 #if defined(__mips_hard_float) && __mips_fpr == 64
2844   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2845     return true;
2846 #endif
2847   return false;
2848 }
2849 
2850 inline double Registers_mips_o32::getFloatRegister(int regNum) const {
2851 #if defined(__mips_hard_float) && __mips_fpr == 64
2852   assert(validFloatRegister(regNum));
2853   return _floats[regNum - UNW_MIPS_F0];
2854 #else
2855   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2856 #endif
2857 }
2858 
2859 inline void Registers_mips_o32::setFloatRegister(int regNum,
2860                                                  double value) {
2861 #if defined(__mips_hard_float) && __mips_fpr == 64
2862   assert(validFloatRegister(regNum));
2863   _floats[regNum - UNW_MIPS_F0] = value;
2864 #else
2865   _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2866 #endif
2867 }
2868 
2869 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
2870   return false;
2871 }
2872 
2873 inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
2874   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2875 }
2876 
2877 inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
2878   _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2879 }
2880 
2881 inline const char *Registers_mips_o32::getRegisterName(int regNum) {
2882   switch (regNum) {
2883   case UNW_MIPS_R0:
2884     return "$0";
2885   case UNW_MIPS_R1:
2886     return "$1";
2887   case UNW_MIPS_R2:
2888     return "$2";
2889   case UNW_MIPS_R3:
2890     return "$3";
2891   case UNW_MIPS_R4:
2892     return "$4";
2893   case UNW_MIPS_R5:
2894     return "$5";
2895   case UNW_MIPS_R6:
2896     return "$6";
2897   case UNW_MIPS_R7:
2898     return "$7";
2899   case UNW_MIPS_R8:
2900     return "$8";
2901   case UNW_MIPS_R9:
2902     return "$9";
2903   case UNW_MIPS_R10:
2904     return "$10";
2905   case UNW_MIPS_R11:
2906     return "$11";
2907   case UNW_MIPS_R12:
2908     return "$12";
2909   case UNW_MIPS_R13:
2910     return "$13";
2911   case UNW_MIPS_R14:
2912     return "$14";
2913   case UNW_MIPS_R15:
2914     return "$15";
2915   case UNW_MIPS_R16:
2916     return "$16";
2917   case UNW_MIPS_R17:
2918     return "$17";
2919   case UNW_MIPS_R18:
2920     return "$18";
2921   case UNW_MIPS_R19:
2922     return "$19";
2923   case UNW_MIPS_R20:
2924     return "$20";
2925   case UNW_MIPS_R21:
2926     return "$21";
2927   case UNW_MIPS_R22:
2928     return "$22";
2929   case UNW_MIPS_R23:
2930     return "$23";
2931   case UNW_MIPS_R24:
2932     return "$24";
2933   case UNW_MIPS_R25:
2934     return "$25";
2935   case UNW_MIPS_R26:
2936     return "$26";
2937   case UNW_MIPS_R27:
2938     return "$27";
2939   case UNW_MIPS_R28:
2940     return "$28";
2941   case UNW_MIPS_R29:
2942     return "$29";
2943   case UNW_MIPS_R30:
2944     return "$30";
2945   case UNW_MIPS_R31:
2946     return "$31";
2947   case UNW_MIPS_F0:
2948     return "$f0";
2949   case UNW_MIPS_F1:
2950     return "$f1";
2951   case UNW_MIPS_F2:
2952     return "$f2";
2953   case UNW_MIPS_F3:
2954     return "$f3";
2955   case UNW_MIPS_F4:
2956     return "$f4";
2957   case UNW_MIPS_F5:
2958     return "$f5";
2959   case UNW_MIPS_F6:
2960     return "$f6";
2961   case UNW_MIPS_F7:
2962     return "$f7";
2963   case UNW_MIPS_F8:
2964     return "$f8";
2965   case UNW_MIPS_F9:
2966     return "$f9";
2967   case UNW_MIPS_F10:
2968     return "$f10";
2969   case UNW_MIPS_F11:
2970     return "$f11";
2971   case UNW_MIPS_F12:
2972     return "$f12";
2973   case UNW_MIPS_F13:
2974     return "$f13";
2975   case UNW_MIPS_F14:
2976     return "$f14";
2977   case UNW_MIPS_F15:
2978     return "$f15";
2979   case UNW_MIPS_F16:
2980     return "$f16";
2981   case UNW_MIPS_F17:
2982     return "$f17";
2983   case UNW_MIPS_F18:
2984     return "$f18";
2985   case UNW_MIPS_F19:
2986     return "$f19";
2987   case UNW_MIPS_F20:
2988     return "$f20";
2989   case UNW_MIPS_F21:
2990     return "$f21";
2991   case UNW_MIPS_F22:
2992     return "$f22";
2993   case UNW_MIPS_F23:
2994     return "$f23";
2995   case UNW_MIPS_F24:
2996     return "$f24";
2997   case UNW_MIPS_F25:
2998     return "$f25";
2999   case UNW_MIPS_F26:
3000     return "$f26";
3001   case UNW_MIPS_F27:
3002     return "$f27";
3003   case UNW_MIPS_F28:
3004     return "$f28";
3005   case UNW_MIPS_F29:
3006     return "$f29";
3007   case UNW_MIPS_F30:
3008     return "$f30";
3009   case UNW_MIPS_F31:
3010     return "$f31";
3011   case UNW_MIPS_HI:
3012     return "$hi";
3013   case UNW_MIPS_LO:
3014     return "$lo";
3015   default:
3016     return "unknown register";
3017   }
3018 }
3019 #endif // _LIBUNWIND_TARGET_MIPS_O32
3020 
3021 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
3022 /// Registers_mips_newabi holds the register state of a thread in a
3023 /// MIPS process using NEWABI (the N32 or N64 ABIs).
3024 class _LIBUNWIND_HIDDEN Registers_mips_newabi {
3025 public:
3026   Registers_mips_newabi();
3027   Registers_mips_newabi(const void *registers);
3028 
3029   bool        validRegister(int num) const;
3030   uint64_t    getRegister(int num) const;
3031   void        setRegister(int num, uint64_t value);
3032   bool        validFloatRegister(int num) const;
3033   double      getFloatRegister(int num) const;
3034   void        setFloatRegister(int num, double value);
3035   bool        validVectorRegister(int num) const;
3036   v128        getVectorRegister(int num) const;
3037   void        setVectorRegister(int num, v128 value);
3038   const char *getRegisterName(int num);
3039   void        jumpto();
3040   static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
3041 
3042   uint64_t  getSP() const         { return _registers.__r[29]; }
3043   void      setSP(uint64_t value) { _registers.__r[29] = value; }
3044   uint64_t  getIP() const         { return _registers.__pc; }
3045   void      setIP(uint64_t value) { _registers.__pc = value; }
3046 
3047 private:
3048   struct mips_newabi_thread_state_t {
3049     uint64_t __r[32];
3050     uint64_t __pc;
3051     uint64_t __hi;
3052     uint64_t __lo;
3053   };
3054 
3055   mips_newabi_thread_state_t _registers;
3056 #ifdef __mips_hard_float
3057   double _floats[32];
3058 #endif
3059 };
3060 
3061 inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {
3062   static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),
3063                 "mips_newabi registers do not fit into unw_context_t");
3064   memcpy(&_registers, static_cast<const uint8_t *>(registers),
3065          sizeof(_registers));
3066 }
3067 
3068 inline Registers_mips_newabi::Registers_mips_newabi() {
3069   memset(&_registers, 0, sizeof(_registers));
3070 }
3071 
3072 inline bool Registers_mips_newabi::validRegister(int regNum) const {
3073   if (regNum == UNW_REG_IP)
3074     return true;
3075   if (regNum == UNW_REG_SP)
3076     return true;
3077   if (regNum < 0)
3078     return false;
3079   if (regNum <= UNW_MIPS_R31)
3080     return true;
3081 #if __mips_isa_rev != 6
3082   if (regNum == UNW_MIPS_HI)
3083     return true;
3084   if (regNum == UNW_MIPS_LO)
3085     return true;
3086 #endif
3087   // FIXME: Hard float, DSP accumulator registers, MSA registers
3088   return false;
3089 }
3090 
3091 inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
3092   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3093     return _registers.__r[regNum - UNW_MIPS_R0];
3094 
3095   switch (regNum) {
3096   case UNW_REG_IP:
3097     return _registers.__pc;
3098   case UNW_REG_SP:
3099     return _registers.__r[29];
3100   case UNW_MIPS_HI:
3101     return _registers.__hi;
3102   case UNW_MIPS_LO:
3103     return _registers.__lo;
3104   }
3105   _LIBUNWIND_ABORT("unsupported mips_newabi register");
3106 }
3107 
3108 inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
3109   if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3110     _registers.__r[regNum - UNW_MIPS_R0] = value;
3111     return;
3112   }
3113 
3114   switch (regNum) {
3115   case UNW_REG_IP:
3116     _registers.__pc = value;
3117     return;
3118   case UNW_REG_SP:
3119     _registers.__r[29] = value;
3120     return;
3121   case UNW_MIPS_HI:
3122     _registers.__hi = value;
3123     return;
3124   case UNW_MIPS_LO:
3125     _registers.__lo = value;
3126     return;
3127   }
3128   _LIBUNWIND_ABORT("unsupported mips_newabi register");
3129 }
3130 
3131 inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {
3132 #ifdef __mips_hard_float
3133   if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3134     return true;
3135 #endif
3136   return false;
3137 }
3138 
3139 inline double Registers_mips_newabi::getFloatRegister(int regNum) const {
3140 #ifdef __mips_hard_float
3141   assert(validFloatRegister(regNum));
3142   return _floats[regNum - UNW_MIPS_F0];
3143 #else
3144   _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3145 #endif
3146 }
3147 
3148 inline void Registers_mips_newabi::setFloatRegister(int regNum,
3149                                                     double value) {
3150 #ifdef __mips_hard_float
3151   assert(validFloatRegister(regNum));
3152   _floats[regNum - UNW_MIPS_F0] = value;
3153 #else
3154   _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3155 #endif
3156 }
3157 
3158 inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {
3159   return false;
3160 }
3161 
3162 inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {
3163   _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3164 }
3165 
3166 inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {
3167   _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3168 }
3169 
3170 inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
3171   switch (regNum) {
3172   case UNW_MIPS_R0:
3173     return "$0";
3174   case UNW_MIPS_R1:
3175     return "$1";
3176   case UNW_MIPS_R2:
3177     return "$2";
3178   case UNW_MIPS_R3:
3179     return "$3";
3180   case UNW_MIPS_R4:
3181     return "$4";
3182   case UNW_MIPS_R5:
3183     return "$5";
3184   case UNW_MIPS_R6:
3185     return "$6";
3186   case UNW_MIPS_R7:
3187     return "$7";
3188   case UNW_MIPS_R8:
3189     return "$8";
3190   case UNW_MIPS_R9:
3191     return "$9";
3192   case UNW_MIPS_R10:
3193     return "$10";
3194   case UNW_MIPS_R11:
3195     return "$11";
3196   case UNW_MIPS_R12:
3197     return "$12";
3198   case UNW_MIPS_R13:
3199     return "$13";
3200   case UNW_MIPS_R14:
3201     return "$14";
3202   case UNW_MIPS_R15:
3203     return "$15";
3204   case UNW_MIPS_R16:
3205     return "$16";
3206   case UNW_MIPS_R17:
3207     return "$17";
3208   case UNW_MIPS_R18:
3209     return "$18";
3210   case UNW_MIPS_R19:
3211     return "$19";
3212   case UNW_MIPS_R20:
3213     return "$20";
3214   case UNW_MIPS_R21:
3215     return "$21";
3216   case UNW_MIPS_R22:
3217     return "$22";
3218   case UNW_MIPS_R23:
3219     return "$23";
3220   case UNW_MIPS_R24:
3221     return "$24";
3222   case UNW_MIPS_R25:
3223     return "$25";
3224   case UNW_MIPS_R26:
3225     return "$26";
3226   case UNW_MIPS_R27:
3227     return "$27";
3228   case UNW_MIPS_R28:
3229     return "$28";
3230   case UNW_MIPS_R29:
3231     return "$29";
3232   case UNW_MIPS_R30:
3233     return "$30";
3234   case UNW_MIPS_R31:
3235     return "$31";
3236   case UNW_MIPS_F0:
3237     return "$f0";
3238   case UNW_MIPS_F1:
3239     return "$f1";
3240   case UNW_MIPS_F2:
3241     return "$f2";
3242   case UNW_MIPS_F3:
3243     return "$f3";
3244   case UNW_MIPS_F4:
3245     return "$f4";
3246   case UNW_MIPS_F5:
3247     return "$f5";
3248   case UNW_MIPS_F6:
3249     return "$f6";
3250   case UNW_MIPS_F7:
3251     return "$f7";
3252   case UNW_MIPS_F8:
3253     return "$f8";
3254   case UNW_MIPS_F9:
3255     return "$f9";
3256   case UNW_MIPS_F10:
3257     return "$f10";
3258   case UNW_MIPS_F11:
3259     return "$f11";
3260   case UNW_MIPS_F12:
3261     return "$f12";
3262   case UNW_MIPS_F13:
3263     return "$f13";
3264   case UNW_MIPS_F14:
3265     return "$f14";
3266   case UNW_MIPS_F15:
3267     return "$f15";
3268   case UNW_MIPS_F16:
3269     return "$f16";
3270   case UNW_MIPS_F17:
3271     return "$f17";
3272   case UNW_MIPS_F18:
3273     return "$f18";
3274   case UNW_MIPS_F19:
3275     return "$f19";
3276   case UNW_MIPS_F20:
3277     return "$f20";
3278   case UNW_MIPS_F21:
3279     return "$f21";
3280   case UNW_MIPS_F22:
3281     return "$f22";
3282   case UNW_MIPS_F23:
3283     return "$f23";
3284   case UNW_MIPS_F24:
3285     return "$f24";
3286   case UNW_MIPS_F25:
3287     return "$f25";
3288   case UNW_MIPS_F26:
3289     return "$f26";
3290   case UNW_MIPS_F27:
3291     return "$f27";
3292   case UNW_MIPS_F28:
3293     return "$f28";
3294   case UNW_MIPS_F29:
3295     return "$f29";
3296   case UNW_MIPS_F30:
3297     return "$f30";
3298   case UNW_MIPS_F31:
3299     return "$f31";
3300   case UNW_MIPS_HI:
3301     return "$hi";
3302   case UNW_MIPS_LO:
3303     return "$lo";
3304   default:
3305     return "unknown register";
3306   }
3307 }
3308 #endif // _LIBUNWIND_TARGET_MIPS_NEWABI
3309 } // namespace libunwind
3310 
3311 #endif // __REGISTERS_HPP__
3312