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 8; }
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   case UNW_X86_EBP:
126     return _registers.__ebp;
127   case UNW_X86_ESP:
128     return _registers.__esp;
129   case UNW_X86_ESI:
130     return _registers.__esi;
131   case UNW_X86_EDI:
132     return _registers.__edi;
133   }
134   _LIBUNWIND_ABORT("unsupported x86 register");
135 }
136 
137 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
138   switch (regNum) {
139   case UNW_REG_IP:
140     _registers.__eip = value;
141     return;
142   case UNW_REG_SP:
143     _registers.__esp = value;
144     return;
145   case UNW_X86_EAX:
146     _registers.__eax = value;
147     return;
148   case UNW_X86_ECX:
149     _registers.__ecx = value;
150     return;
151   case UNW_X86_EDX:
152     _registers.__edx = value;
153     return;
154   case UNW_X86_EBX:
155     _registers.__ebx = value;
156     return;
157   case UNW_X86_EBP:
158     _registers.__ebp = value;
159     return;
160   case UNW_X86_ESP:
161     _registers.__esp = value;
162     return;
163   case UNW_X86_ESI:
164     _registers.__esi = value;
165     return;
166   case UNW_X86_EDI:
167     _registers.__edi = value;
168     return;
169   }
170   _LIBUNWIND_ABORT("unsupported x86 register");
171 }
172 
173 inline const char *Registers_x86::getRegisterName(int regNum) {
174   switch (regNum) {
175   case UNW_REG_IP:
176     return "ip";
177   case UNW_REG_SP:
178     return "esp";
179   case UNW_X86_EAX:
180     return "eax";
181   case UNW_X86_ECX:
182     return "ecx";
183   case UNW_X86_EDX:
184     return "edx";
185   case UNW_X86_EBX:
186     return "ebx";
187   case UNW_X86_EBP:
188     return "ebp";
189   case UNW_X86_ESP:
190     return "esp";
191   case UNW_X86_ESI:
192     return "esi";
193   case UNW_X86_EDI:
194     return "edi";
195   default:
196     return "unknown register";
197   }
198 }
199 
200 inline double Registers_x86::getFloatRegister(int) const {
201   _LIBUNWIND_ABORT("no x86 float registers");
202 }
203 
204 inline void Registers_x86::setFloatRegister(int, double) {
205   _LIBUNWIND_ABORT("no x86 float registers");
206 }
207 
208 inline v128 Registers_x86::getVectorRegister(int) const {
209   _LIBUNWIND_ABORT("no x86 vector registers");
210 }
211 
212 inline void Registers_x86::setVectorRegister(int, v128) {
213   _LIBUNWIND_ABORT("no x86 vector registers");
214 }
215 #endif // _LIBUNWIND_TARGET_I386
216 
217 
218 #if defined(_LIBUNWIND_TARGET_X86_64)
219 /// Registers_x86_64  holds the register state of a thread in a 64-bit intel
220 /// process.
221 class _LIBUNWIND_HIDDEN Registers_x86_64 {
222 public:
223   Registers_x86_64();
224   Registers_x86_64(const void *registers);
225 
226   bool        validRegister(int num) const;
227   uint64_t    getRegister(int num) const;
228   void        setRegister(int num, uint64_t value);
229   bool        validFloatRegister(int) const { return false; }
230   double      getFloatRegister(int num) const;
231   void        setFloatRegister(int num, double value);
232   bool        validVectorRegister(int) const { return false; }
233   v128        getVectorRegister(int num) const;
234   void        setVectorRegister(int num, v128 value);
235   const char *getRegisterName(int num);
236   void        jumpto();
237   static int  lastDwarfRegNum() { return 16; }
238 
239   uint64_t  getSP() const          { return _registers.__rsp; }
240   void      setSP(uint64_t value)  { _registers.__rsp = value; }
241   uint64_t  getIP() const          { return _registers.__rip; }
242   void      setIP(uint64_t value)  { _registers.__rip = value; }
243   uint64_t  getRBP() const         { return _registers.__rbp; }
244   void      setRBP(uint64_t value) { _registers.__rbp = value; }
245   uint64_t  getRBX() const         { return _registers.__rbx; }
246   void      setRBX(uint64_t value) { _registers.__rbx = value; }
247   uint64_t  getR12() const         { return _registers.__r12; }
248   void      setR12(uint64_t value) { _registers.__r12 = value; }
249   uint64_t  getR13() const         { return _registers.__r13; }
250   void      setR13(uint64_t value) { _registers.__r13 = value; }
251   uint64_t  getR14() const         { return _registers.__r14; }
252   void      setR14(uint64_t value) { _registers.__r14 = value; }
253   uint64_t  getR15() const         { return _registers.__r15; }
254   void      setR15(uint64_t value) { _registers.__r15 = value; }
255 
256 private:
257   struct GPRs {
258     uint64_t __rax;
259     uint64_t __rbx;
260     uint64_t __rcx;
261     uint64_t __rdx;
262     uint64_t __rdi;
263     uint64_t __rsi;
264     uint64_t __rbp;
265     uint64_t __rsp;
266     uint64_t __r8;
267     uint64_t __r9;
268     uint64_t __r10;
269     uint64_t __r11;
270     uint64_t __r12;
271     uint64_t __r13;
272     uint64_t __r14;
273     uint64_t __r15;
274     uint64_t __rip;
275     uint64_t __rflags;
276     uint64_t __cs;
277     uint64_t __fs;
278     uint64_t __gs;
279   };
280   GPRs _registers;
281 };
282 
283 inline Registers_x86_64::Registers_x86_64(const void *registers) {
284   static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
285                 "x86_64 registers do not fit into unw_context_t");
286   memcpy(&_registers, registers, sizeof(_registers));
287 }
288 
289 inline Registers_x86_64::Registers_x86_64() {
290   memset(&_registers, 0, sizeof(_registers));
291 }
292 
293 inline bool Registers_x86_64::validRegister(int regNum) const {
294   if (regNum == UNW_REG_IP)
295     return true;
296   if (regNum == UNW_REG_SP)
297     return true;
298   if (regNum < 0)
299     return false;
300   if (regNum > 15)
301     return false;
302   return true;
303 }
304 
305 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
306   switch (regNum) {
307   case UNW_REG_IP:
308     return _registers.__rip;
309   case UNW_REG_SP:
310     return _registers.__rsp;
311   case UNW_X86_64_RAX:
312     return _registers.__rax;
313   case UNW_X86_64_RDX:
314     return _registers.__rdx;
315   case UNW_X86_64_RCX:
316     return _registers.__rcx;
317   case UNW_X86_64_RBX:
318     return _registers.__rbx;
319   case UNW_X86_64_RSI:
320     return _registers.__rsi;
321   case UNW_X86_64_RDI:
322     return _registers.__rdi;
323   case UNW_X86_64_RBP:
324     return _registers.__rbp;
325   case UNW_X86_64_RSP:
326     return _registers.__rsp;
327   case UNW_X86_64_R8:
328     return _registers.__r8;
329   case UNW_X86_64_R9:
330     return _registers.__r9;
331   case UNW_X86_64_R10:
332     return _registers.__r10;
333   case UNW_X86_64_R11:
334     return _registers.__r11;
335   case UNW_X86_64_R12:
336     return _registers.__r12;
337   case UNW_X86_64_R13:
338     return _registers.__r13;
339   case UNW_X86_64_R14:
340     return _registers.__r14;
341   case UNW_X86_64_R15:
342     return _registers.__r15;
343   }
344   _LIBUNWIND_ABORT("unsupported x86_64 register");
345 }
346 
347 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
348   switch (regNum) {
349   case UNW_REG_IP:
350     _registers.__rip = value;
351     return;
352   case UNW_REG_SP:
353     _registers.__rsp = value;
354     return;
355   case UNW_X86_64_RAX:
356     _registers.__rax = value;
357     return;
358   case UNW_X86_64_RDX:
359     _registers.__rdx = value;
360     return;
361   case UNW_X86_64_RCX:
362     _registers.__rcx = value;
363     return;
364   case UNW_X86_64_RBX:
365     _registers.__rbx = value;
366     return;
367   case UNW_X86_64_RSI:
368     _registers.__rsi = value;
369     return;
370   case UNW_X86_64_RDI:
371     _registers.__rdi = value;
372     return;
373   case UNW_X86_64_RBP:
374     _registers.__rbp = value;
375     return;
376   case UNW_X86_64_RSP:
377     _registers.__rsp = value;
378     return;
379   case UNW_X86_64_R8:
380     _registers.__r8 = value;
381     return;
382   case UNW_X86_64_R9:
383     _registers.__r9 = value;
384     return;
385   case UNW_X86_64_R10:
386     _registers.__r10 = value;
387     return;
388   case UNW_X86_64_R11:
389     _registers.__r11 = value;
390     return;
391   case UNW_X86_64_R12:
392     _registers.__r12 = value;
393     return;
394   case UNW_X86_64_R13:
395     _registers.__r13 = value;
396     return;
397   case UNW_X86_64_R14:
398     _registers.__r14 = value;
399     return;
400   case UNW_X86_64_R15:
401     _registers.__r15 = value;
402     return;
403   }
404   _LIBUNWIND_ABORT("unsupported x86_64 register");
405 }
406 
407 inline const char *Registers_x86_64::getRegisterName(int regNum) {
408   switch (regNum) {
409   case UNW_REG_IP:
410     return "rip";
411   case UNW_REG_SP:
412     return "rsp";
413   case UNW_X86_64_RAX:
414     return "rax";
415   case UNW_X86_64_RDX:
416     return "rdx";
417   case UNW_X86_64_RCX:
418     return "rcx";
419   case UNW_X86_64_RBX:
420     return "rbx";
421   case UNW_X86_64_RSI:
422     return "rsi";
423   case UNW_X86_64_RDI:
424     return "rdi";
425   case UNW_X86_64_RBP:
426     return "rbp";
427   case UNW_X86_64_RSP:
428     return "rsp";
429   case UNW_X86_64_R8:
430     return "r8";
431   case UNW_X86_64_R9:
432     return "r9";
433   case UNW_X86_64_R10:
434     return "r10";
435   case UNW_X86_64_R11:
436     return "r11";
437   case UNW_X86_64_R12:
438     return "r12";
439   case UNW_X86_64_R13:
440     return "r13";
441   case UNW_X86_64_R14:
442     return "r14";
443   case UNW_X86_64_R15:
444     return "r15";
445   default:
446     return "unknown register";
447   }
448 }
449 
450 inline double Registers_x86_64::getFloatRegister(int) const {
451   _LIBUNWIND_ABORT("no x86_64 float registers");
452 }
453 
454 inline void Registers_x86_64::setFloatRegister(int, double) {
455   _LIBUNWIND_ABORT("no x86_64 float registers");
456 }
457 
458 inline v128 Registers_x86_64::getVectorRegister(int) const {
459   _LIBUNWIND_ABORT("no x86_64 vector registers");
460 }
461 
462 inline void Registers_x86_64::setVectorRegister(int, v128) {
463   _LIBUNWIND_ABORT("no x86_64 vector registers");
464 }
465 #endif // _LIBUNWIND_TARGET_X86_64
466 
467 
468 #if defined(_LIBUNWIND_TARGET_PPC)
469 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
470 /// process.
471 class _LIBUNWIND_HIDDEN Registers_ppc {
472 public:
473   Registers_ppc();
474   Registers_ppc(const void *registers);
475 
476   bool        validRegister(int num) const;
477   uint32_t    getRegister(int num) const;
478   void        setRegister(int num, uint32_t value);
479   bool        validFloatRegister(int num) const;
480   double      getFloatRegister(int num) const;
481   void        setFloatRegister(int num, double value);
482   bool        validVectorRegister(int num) const;
483   v128        getVectorRegister(int num) const;
484   void        setVectorRegister(int num, v128 value);
485   const char *getRegisterName(int num);
486   void        jumpto();
487   static int  lastDwarfRegNum() { return 112; }
488 
489   uint64_t  getSP() const         { return _registers.__r1; }
490   void      setSP(uint32_t value) { _registers.__r1 = value; }
491   uint64_t  getIP() const         { return _registers.__srr0; }
492   void      setIP(uint32_t value) { _registers.__srr0 = value; }
493 
494 private:
495   struct ppc_thread_state_t {
496     unsigned int __srr0; /* Instruction address register (PC) */
497     unsigned int __srr1; /* Machine state register (supervisor) */
498     unsigned int __r0;
499     unsigned int __r1;
500     unsigned int __r2;
501     unsigned int __r3;
502     unsigned int __r4;
503     unsigned int __r5;
504     unsigned int __r6;
505     unsigned int __r7;
506     unsigned int __r8;
507     unsigned int __r9;
508     unsigned int __r10;
509     unsigned int __r11;
510     unsigned int __r12;
511     unsigned int __r13;
512     unsigned int __r14;
513     unsigned int __r15;
514     unsigned int __r16;
515     unsigned int __r17;
516     unsigned int __r18;
517     unsigned int __r19;
518     unsigned int __r20;
519     unsigned int __r21;
520     unsigned int __r22;
521     unsigned int __r23;
522     unsigned int __r24;
523     unsigned int __r25;
524     unsigned int __r26;
525     unsigned int __r27;
526     unsigned int __r28;
527     unsigned int __r29;
528     unsigned int __r30;
529     unsigned int __r31;
530     unsigned int __cr;     /* Condition register */
531     unsigned int __xer;    /* User's integer exception register */
532     unsigned int __lr;     /* Link register */
533     unsigned int __ctr;    /* Count register */
534     unsigned int __mq;     /* MQ register (601 only) */
535     unsigned int __vrsave; /* Vector Save Register */
536   };
537 
538   struct ppc_float_state_t {
539     double __fpregs[32];
540 
541     unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
542     unsigned int __fpscr;     /* floating point status register */
543   };
544 
545   ppc_thread_state_t _registers;
546   ppc_float_state_t  _floatRegisters;
547   v128               _vectorRegisters[32]; // offset 424
548 };
549 
550 inline Registers_ppc::Registers_ppc(const void *registers) {
551   static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
552                 "ppc registers do not fit into unw_context_t");
553   memcpy(&_registers, static_cast<const uint8_t *>(registers),
554          sizeof(_registers));
555   static_assert(sizeof(ppc_thread_state_t) == 160,
556                 "expected float register offset to be 160");
557   memcpy(&_floatRegisters,
558          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
559          sizeof(_floatRegisters));
560   static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
561                 "expected vector register offset to be 424 bytes");
562   memcpy(_vectorRegisters,
563          static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
564              sizeof(ppc_float_state_t),
565          sizeof(_vectorRegisters));
566 }
567 
568 inline Registers_ppc::Registers_ppc() {
569   memset(&_registers, 0, sizeof(_registers));
570   memset(&_floatRegisters, 0, sizeof(_floatRegisters));
571   memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
572 }
573 
574 inline bool Registers_ppc::validRegister(int regNum) const {
575   if (regNum == UNW_REG_IP)
576     return true;
577   if (regNum == UNW_REG_SP)
578     return true;
579   if (regNum == UNW_PPC_VRSAVE)
580     return true;
581   if (regNum < 0)
582     return false;
583   if (regNum <= UNW_PPC_R31)
584     return true;
585   if (regNum == UNW_PPC_MQ)
586     return true;
587   if (regNum == UNW_PPC_LR)
588     return true;
589   if (regNum == UNW_PPC_CTR)
590     return true;
591   if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
592     return true;
593   return false;
594 }
595 
596 inline uint32_t Registers_ppc::getRegister(int regNum) const {
597   switch (regNum) {
598   case UNW_REG_IP:
599     return _registers.__srr0;
600   case UNW_REG_SP:
601     return _registers.__r1;
602   case UNW_PPC_R0:
603     return _registers.__r0;
604   case UNW_PPC_R1:
605     return _registers.__r1;
606   case UNW_PPC_R2:
607     return _registers.__r2;
608   case UNW_PPC_R3:
609     return _registers.__r3;
610   case UNW_PPC_R4:
611     return _registers.__r4;
612   case UNW_PPC_R5:
613     return _registers.__r5;
614   case UNW_PPC_R6:
615     return _registers.__r6;
616   case UNW_PPC_R7:
617     return _registers.__r7;
618   case UNW_PPC_R8:
619     return _registers.__r8;
620   case UNW_PPC_R9:
621     return _registers.__r9;
622   case UNW_PPC_R10:
623     return _registers.__r10;
624   case UNW_PPC_R11:
625     return _registers.__r11;
626   case UNW_PPC_R12:
627     return _registers.__r12;
628   case UNW_PPC_R13:
629     return _registers.__r13;
630   case UNW_PPC_R14:
631     return _registers.__r14;
632   case UNW_PPC_R15:
633     return _registers.__r15;
634   case UNW_PPC_R16:
635     return _registers.__r16;
636   case UNW_PPC_R17:
637     return _registers.__r17;
638   case UNW_PPC_R18:
639     return _registers.__r18;
640   case UNW_PPC_R19:
641     return _registers.__r19;
642   case UNW_PPC_R20:
643     return _registers.__r20;
644   case UNW_PPC_R21:
645     return _registers.__r21;
646   case UNW_PPC_R22:
647     return _registers.__r22;
648   case UNW_PPC_R23:
649     return _registers.__r23;
650   case UNW_PPC_R24:
651     return _registers.__r24;
652   case UNW_PPC_R25:
653     return _registers.__r25;
654   case UNW_PPC_R26:
655     return _registers.__r26;
656   case UNW_PPC_R27:
657     return _registers.__r27;
658   case UNW_PPC_R28:
659     return _registers.__r28;
660   case UNW_PPC_R29:
661     return _registers.__r29;
662   case UNW_PPC_R30:
663     return _registers.__r30;
664   case UNW_PPC_R31:
665     return _registers.__r31;
666   case UNW_PPC_LR:
667     return _registers.__lr;
668   case UNW_PPC_CR0:
669     return (_registers.__cr & 0xF0000000);
670   case UNW_PPC_CR1:
671     return (_registers.__cr & 0x0F000000);
672   case UNW_PPC_CR2:
673     return (_registers.__cr & 0x00F00000);
674   case UNW_PPC_CR3:
675     return (_registers.__cr & 0x000F0000);
676   case UNW_PPC_CR4:
677     return (_registers.__cr & 0x0000F000);
678   case UNW_PPC_CR5:
679     return (_registers.__cr & 0x00000F00);
680   case UNW_PPC_CR6:
681     return (_registers.__cr & 0x000000F0);
682   case UNW_PPC_CR7:
683     return (_registers.__cr & 0x0000000F);
684   case UNW_PPC_VRSAVE:
685     return _registers.__vrsave;
686   }
687   _LIBUNWIND_ABORT("unsupported ppc register");
688 }
689 
690 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
691   //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
692   switch (regNum) {
693   case UNW_REG_IP:
694     _registers.__srr0 = value;
695     return;
696   case UNW_REG_SP:
697     _registers.__r1 = value;
698     return;
699   case UNW_PPC_R0:
700     _registers.__r0 = value;
701     return;
702   case UNW_PPC_R1:
703     _registers.__r1 = value;
704     return;
705   case UNW_PPC_R2:
706     _registers.__r2 = value;
707     return;
708   case UNW_PPC_R3:
709     _registers.__r3 = value;
710     return;
711   case UNW_PPC_R4:
712     _registers.__r4 = value;
713     return;
714   case UNW_PPC_R5:
715     _registers.__r5 = value;
716     return;
717   case UNW_PPC_R6:
718     _registers.__r6 = value;
719     return;
720   case UNW_PPC_R7:
721     _registers.__r7 = value;
722     return;
723   case UNW_PPC_R8:
724     _registers.__r8 = value;
725     return;
726   case UNW_PPC_R9:
727     _registers.__r9 = value;
728     return;
729   case UNW_PPC_R10:
730     _registers.__r10 = value;
731     return;
732   case UNW_PPC_R11:
733     _registers.__r11 = value;
734     return;
735   case UNW_PPC_R12:
736     _registers.__r12 = value;
737     return;
738   case UNW_PPC_R13:
739     _registers.__r13 = value;
740     return;
741   case UNW_PPC_R14:
742     _registers.__r14 = value;
743     return;
744   case UNW_PPC_R15:
745     _registers.__r15 = value;
746     return;
747   case UNW_PPC_R16:
748     _registers.__r16 = value;
749     return;
750   case UNW_PPC_R17:
751     _registers.__r17 = value;
752     return;
753   case UNW_PPC_R18:
754     _registers.__r18 = value;
755     return;
756   case UNW_PPC_R19:
757     _registers.__r19 = value;
758     return;
759   case UNW_PPC_R20:
760     _registers.__r20 = value;
761     return;
762   case UNW_PPC_R21:
763     _registers.__r21 = value;
764     return;
765   case UNW_PPC_R22:
766     _registers.__r22 = value;
767     return;
768   case UNW_PPC_R23:
769     _registers.__r23 = value;
770     return;
771   case UNW_PPC_R24:
772     _registers.__r24 = value;
773     return;
774   case UNW_PPC_R25:
775     _registers.__r25 = value;
776     return;
777   case UNW_PPC_R26:
778     _registers.__r26 = value;
779     return;
780   case UNW_PPC_R27:
781     _registers.__r27 = value;
782     return;
783   case UNW_PPC_R28:
784     _registers.__r28 = value;
785     return;
786   case UNW_PPC_R29:
787     _registers.__r29 = value;
788     return;
789   case UNW_PPC_R30:
790     _registers.__r30 = value;
791     return;
792   case UNW_PPC_R31:
793     _registers.__r31 = value;
794     return;
795   case UNW_PPC_MQ:
796     _registers.__mq = value;
797     return;
798   case UNW_PPC_LR:
799     _registers.__lr = value;
800     return;
801   case UNW_PPC_CTR:
802     _registers.__ctr = value;
803     return;
804   case UNW_PPC_CR0:
805     _registers.__cr &= 0x0FFFFFFF;
806     _registers.__cr |= (value & 0xF0000000);
807     return;
808   case UNW_PPC_CR1:
809     _registers.__cr &= 0xF0FFFFFF;
810     _registers.__cr |= (value & 0x0F000000);
811     return;
812   case UNW_PPC_CR2:
813     _registers.__cr &= 0xFF0FFFFF;
814     _registers.__cr |= (value & 0x00F00000);
815     return;
816   case UNW_PPC_CR3:
817     _registers.__cr &= 0xFFF0FFFF;
818     _registers.__cr |= (value & 0x000F0000);
819     return;
820   case UNW_PPC_CR4:
821     _registers.__cr &= 0xFFFF0FFF;
822     _registers.__cr |= (value & 0x0000F000);
823     return;
824   case UNW_PPC_CR5:
825     _registers.__cr &= 0xFFFFF0FF;
826     _registers.__cr |= (value & 0x00000F00);
827     return;
828   case UNW_PPC_CR6:
829     _registers.__cr &= 0xFFFFFF0F;
830     _registers.__cr |= (value & 0x000000F0);
831     return;
832   case UNW_PPC_CR7:
833     _registers.__cr &= 0xFFFFFFF0;
834     _registers.__cr |= (value & 0x0000000F);
835     return;
836   case UNW_PPC_VRSAVE:
837     _registers.__vrsave = value;
838     return;
839     // not saved
840     return;
841   case UNW_PPC_XER:
842     _registers.__xer = value;
843     return;
844   case UNW_PPC_AP:
845   case UNW_PPC_VSCR:
846   case UNW_PPC_SPEFSCR:
847     // not saved
848     return;
849   }
850   _LIBUNWIND_ABORT("unsupported ppc register");
851 }
852 
853 inline bool Registers_ppc::validFloatRegister(int regNum) const {
854   if (regNum < UNW_PPC_F0)
855     return false;
856   if (regNum > UNW_PPC_F31)
857     return false;
858   return true;
859 }
860 
861 inline double Registers_ppc::getFloatRegister(int regNum) const {
862   assert(validFloatRegister(regNum));
863   return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
864 }
865 
866 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
867   assert(validFloatRegister(regNum));
868   _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
869 }
870 
871 inline bool Registers_ppc::validVectorRegister(int regNum) const {
872   if (regNum < UNW_PPC_V0)
873     return false;
874   if (regNum > UNW_PPC_V31)
875     return false;
876   return true;
877 }
878 
879 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
880   assert(validVectorRegister(regNum));
881   v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
882   return result;
883 }
884 
885 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
886   assert(validVectorRegister(regNum));
887   _vectorRegisters[regNum - UNW_PPC_V0] = value;
888 }
889 
890 inline const char *Registers_ppc::getRegisterName(int regNum) {
891   switch (regNum) {
892   case UNW_REG_IP:
893     return "ip";
894   case UNW_REG_SP:
895     return "sp";
896   case UNW_PPC_R0:
897     return "r0";
898   case UNW_PPC_R1:
899     return "r1";
900   case UNW_PPC_R2:
901     return "r2";
902   case UNW_PPC_R3:
903     return "r3";
904   case UNW_PPC_R4:
905     return "r4";
906   case UNW_PPC_R5:
907     return "r5";
908   case UNW_PPC_R6:
909     return "r6";
910   case UNW_PPC_R7:
911     return "r7";
912   case UNW_PPC_R8:
913     return "r8";
914   case UNW_PPC_R9:
915     return "r9";
916   case UNW_PPC_R10:
917     return "r10";
918   case UNW_PPC_R11:
919     return "r11";
920   case UNW_PPC_R12:
921     return "r12";
922   case UNW_PPC_R13:
923     return "r13";
924   case UNW_PPC_R14:
925     return "r14";
926   case UNW_PPC_R15:
927     return "r15";
928   case UNW_PPC_R16:
929     return "r16";
930   case UNW_PPC_R17:
931     return "r17";
932   case UNW_PPC_R18:
933     return "r18";
934   case UNW_PPC_R19:
935     return "r19";
936   case UNW_PPC_R20:
937     return "r20";
938   case UNW_PPC_R21:
939     return "r21";
940   case UNW_PPC_R22:
941     return "r22";
942   case UNW_PPC_R23:
943     return "r23";
944   case UNW_PPC_R24:
945     return "r24";
946   case UNW_PPC_R25:
947     return "r25";
948   case UNW_PPC_R26:
949     return "r26";
950   case UNW_PPC_R27:
951     return "r27";
952   case UNW_PPC_R28:
953     return "r28";
954   case UNW_PPC_R29:
955     return "r29";
956   case UNW_PPC_R30:
957     return "r30";
958   case UNW_PPC_R31:
959     return "r31";
960   case UNW_PPC_F0:
961     return "fp0";
962   case UNW_PPC_F1:
963     return "fp1";
964   case UNW_PPC_F2:
965     return "fp2";
966   case UNW_PPC_F3:
967     return "fp3";
968   case UNW_PPC_F4:
969     return "fp4";
970   case UNW_PPC_F5:
971     return "fp5";
972   case UNW_PPC_F6:
973     return "fp6";
974   case UNW_PPC_F7:
975     return "fp7";
976   case UNW_PPC_F8:
977     return "fp8";
978   case UNW_PPC_F9:
979     return "fp9";
980   case UNW_PPC_F10:
981     return "fp10";
982   case UNW_PPC_F11:
983     return "fp11";
984   case UNW_PPC_F12:
985     return "fp12";
986   case UNW_PPC_F13:
987     return "fp13";
988   case UNW_PPC_F14:
989     return "fp14";
990   case UNW_PPC_F15:
991     return "fp15";
992   case UNW_PPC_F16:
993     return "fp16";
994   case UNW_PPC_F17:
995     return "fp17";
996   case UNW_PPC_F18:
997     return "fp18";
998   case UNW_PPC_F19:
999     return "fp19";
1000   case UNW_PPC_F20:
1001     return "fp20";
1002   case UNW_PPC_F21:
1003     return "fp21";
1004   case UNW_PPC_F22:
1005     return "fp22";
1006   case UNW_PPC_F23:
1007     return "fp23";
1008   case UNW_PPC_F24:
1009     return "fp24";
1010   case UNW_PPC_F25:
1011     return "fp25";
1012   case UNW_PPC_F26:
1013     return "fp26";
1014   case UNW_PPC_F27:
1015     return "fp27";
1016   case UNW_PPC_F28:
1017     return "fp28";
1018   case UNW_PPC_F29:
1019     return "fp29";
1020   case UNW_PPC_F30:
1021     return "fp30";
1022   case UNW_PPC_F31:
1023     return "fp31";
1024   case UNW_PPC_LR:
1025     return "lr";
1026   default:
1027     return "unknown register";
1028   }
1029 
1030 }
1031 #endif // _LIBUNWIND_TARGET_PPC
1032 
1033 
1034 #if defined(_LIBUNWIND_TARGET_AARCH64)
1035 /// Registers_arm64  holds the register state of a thread in a 64-bit arm
1036 /// process.
1037 class _LIBUNWIND_HIDDEN Registers_arm64 {
1038 public:
1039   Registers_arm64();
1040   Registers_arm64(const void *registers);
1041 
1042   bool        validRegister(int num) const;
1043   uint64_t    getRegister(int num) const;
1044   void        setRegister(int num, uint64_t value);
1045   bool        validFloatRegister(int num) const;
1046   double      getFloatRegister(int num) const;
1047   void        setFloatRegister(int num, double value);
1048   bool        validVectorRegister(int num) const;
1049   v128        getVectorRegister(int num) const;
1050   void        setVectorRegister(int num, v128 value);
1051   const char *getRegisterName(int num);
1052   void        jumpto();
1053   static int  lastDwarfRegNum() { return 95; }
1054 
1055   uint64_t  getSP() const         { return _registers.__sp; }
1056   void      setSP(uint64_t value) { _registers.__sp = value; }
1057   uint64_t  getIP() const         { return _registers.__pc; }
1058   void      setIP(uint64_t value) { _registers.__pc = value; }
1059   uint64_t  getFP() const         { return _registers.__fp; }
1060   void      setFP(uint64_t value) { _registers.__fp = value; }
1061 
1062 private:
1063   struct GPRs {
1064     uint64_t __x[29]; // x0-x28
1065     uint64_t __fp;    // Frame pointer x29
1066     uint64_t __lr;    // Link register x30
1067     uint64_t __sp;    // Stack pointer x31
1068     uint64_t __pc;    // Program counter
1069     uint64_t padding; // 16-byte align
1070   };
1071 
1072   GPRs    _registers;
1073   double  _vectorHalfRegisters[32];
1074   // Currently only the lower double in 128-bit vectore registers
1075   // is perserved during unwinding.  We could define new register
1076   // numbers (> 96) which mean whole vector registers, then this
1077   // struct would need to change to contain whole vector registers.
1078 };
1079 
1080 inline Registers_arm64::Registers_arm64(const void *registers) {
1081   static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
1082                 "arm64 registers do not fit into unw_context_t");
1083   memcpy(&_registers, registers, sizeof(_registers));
1084   static_assert(sizeof(GPRs) == 0x110,
1085                 "expected VFP registers to be at offset 272");
1086   memcpy(_vectorHalfRegisters,
1087          static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1088          sizeof(_vectorHalfRegisters));
1089 }
1090 
1091 inline Registers_arm64::Registers_arm64() {
1092   memset(&_registers, 0, sizeof(_registers));
1093   memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1094 }
1095 
1096 inline bool Registers_arm64::validRegister(int regNum) const {
1097   if (regNum == UNW_REG_IP)
1098     return true;
1099   if (regNum == UNW_REG_SP)
1100     return true;
1101   if (regNum < 0)
1102     return false;
1103   if (regNum > 95)
1104     return false;
1105   if ((regNum > 31) && (regNum < 64))
1106     return false;
1107   return true;
1108 }
1109 
1110 inline uint64_t Registers_arm64::getRegister(int regNum) const {
1111   if (regNum == UNW_REG_IP)
1112     return _registers.__pc;
1113   if (regNum == UNW_REG_SP)
1114     return _registers.__sp;
1115   if ((regNum >= 0) && (regNum < 32))
1116     return _registers.__x[regNum];
1117   _LIBUNWIND_ABORT("unsupported arm64 register");
1118 }
1119 
1120 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1121   if (regNum == UNW_REG_IP)
1122     _registers.__pc = value;
1123   else if (regNum == UNW_REG_SP)
1124     _registers.__sp = value;
1125   else if ((regNum >= 0) && (regNum < 32))
1126     _registers.__x[regNum] = value;
1127   else
1128     _LIBUNWIND_ABORT("unsupported arm64 register");
1129 }
1130 
1131 inline const char *Registers_arm64::getRegisterName(int regNum) {
1132   switch (regNum) {
1133   case UNW_REG_IP:
1134     return "pc";
1135   case UNW_REG_SP:
1136     return "sp";
1137   case UNW_ARM64_X0:
1138     return "x0";
1139   case UNW_ARM64_X1:
1140     return "x1";
1141   case UNW_ARM64_X2:
1142     return "x2";
1143   case UNW_ARM64_X3:
1144     return "x3";
1145   case UNW_ARM64_X4:
1146     return "x4";
1147   case UNW_ARM64_X5:
1148     return "x5";
1149   case UNW_ARM64_X6:
1150     return "x6";
1151   case UNW_ARM64_X7:
1152     return "x7";
1153   case UNW_ARM64_X8:
1154     return "x8";
1155   case UNW_ARM64_X9:
1156     return "x9";
1157   case UNW_ARM64_X10:
1158     return "x10";
1159   case UNW_ARM64_X11:
1160     return "x11";
1161   case UNW_ARM64_X12:
1162     return "x12";
1163   case UNW_ARM64_X13:
1164     return "x13";
1165   case UNW_ARM64_X14:
1166     return "x14";
1167   case UNW_ARM64_X15:
1168     return "x15";
1169   case UNW_ARM64_X16:
1170     return "x16";
1171   case UNW_ARM64_X17:
1172     return "x17";
1173   case UNW_ARM64_X18:
1174     return "x18";
1175   case UNW_ARM64_X19:
1176     return "x19";
1177   case UNW_ARM64_X20:
1178     return "x20";
1179   case UNW_ARM64_X21:
1180     return "x21";
1181   case UNW_ARM64_X22:
1182     return "x22";
1183   case UNW_ARM64_X23:
1184     return "x23";
1185   case UNW_ARM64_X24:
1186     return "x24";
1187   case UNW_ARM64_X25:
1188     return "x25";
1189   case UNW_ARM64_X26:
1190     return "x26";
1191   case UNW_ARM64_X27:
1192     return "x27";
1193   case UNW_ARM64_X28:
1194     return "x28";
1195   case UNW_ARM64_X29:
1196     return "fp";
1197   case UNW_ARM64_X30:
1198     return "lr";
1199   case UNW_ARM64_X31:
1200     return "sp";
1201   case UNW_ARM64_D0:
1202     return "d0";
1203   case UNW_ARM64_D1:
1204     return "d1";
1205   case UNW_ARM64_D2:
1206     return "d2";
1207   case UNW_ARM64_D3:
1208     return "d3";
1209   case UNW_ARM64_D4:
1210     return "d4";
1211   case UNW_ARM64_D5:
1212     return "d5";
1213   case UNW_ARM64_D6:
1214     return "d6";
1215   case UNW_ARM64_D7:
1216     return "d7";
1217   case UNW_ARM64_D8:
1218     return "d8";
1219   case UNW_ARM64_D9:
1220     return "d9";
1221   case UNW_ARM64_D10:
1222     return "d10";
1223   case UNW_ARM64_D11:
1224     return "d11";
1225   case UNW_ARM64_D12:
1226     return "d12";
1227   case UNW_ARM64_D13:
1228     return "d13";
1229   case UNW_ARM64_D14:
1230     return "d14";
1231   case UNW_ARM64_D15:
1232     return "d15";
1233   case UNW_ARM64_D16:
1234     return "d16";
1235   case UNW_ARM64_D17:
1236     return "d17";
1237   case UNW_ARM64_D18:
1238     return "d18";
1239   case UNW_ARM64_D19:
1240     return "d19";
1241   case UNW_ARM64_D20:
1242     return "d20";
1243   case UNW_ARM64_D21:
1244     return "d21";
1245   case UNW_ARM64_D22:
1246     return "d22";
1247   case UNW_ARM64_D23:
1248     return "d23";
1249   case UNW_ARM64_D24:
1250     return "d24";
1251   case UNW_ARM64_D25:
1252     return "d25";
1253   case UNW_ARM64_D26:
1254     return "d26";
1255   case UNW_ARM64_D27:
1256     return "d27";
1257   case UNW_ARM64_D28:
1258     return "d28";
1259   case UNW_ARM64_D29:
1260     return "d29";
1261   case UNW_ARM64_D30:
1262     return "d30";
1263   case UNW_ARM64_D31:
1264     return "d31";
1265   default:
1266     return "unknown register";
1267   }
1268 }
1269 
1270 inline bool Registers_arm64::validFloatRegister(int regNum) const {
1271   if (regNum < UNW_ARM64_D0)
1272     return false;
1273   if (regNum > UNW_ARM64_D31)
1274     return false;
1275   return true;
1276 }
1277 
1278 inline double Registers_arm64::getFloatRegister(int regNum) const {
1279   assert(validFloatRegister(regNum));
1280   return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
1281 }
1282 
1283 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
1284   assert(validFloatRegister(regNum));
1285   _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
1286 }
1287 
1288 inline bool Registers_arm64::validVectorRegister(int) const {
1289   return false;
1290 }
1291 
1292 inline v128 Registers_arm64::getVectorRegister(int) const {
1293   _LIBUNWIND_ABORT("no arm64 vector register support yet");
1294 }
1295 
1296 inline void Registers_arm64::setVectorRegister(int, v128) {
1297   _LIBUNWIND_ABORT("no arm64 vector register support yet");
1298 }
1299 #endif // _LIBUNWIND_TARGET_AARCH64
1300 
1301 #if defined(_LIBUNWIND_TARGET_ARM)
1302 /// Registers_arm holds the register state of a thread in a 32-bit arm
1303 /// process.
1304 ///
1305 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
1306 /// this uses more memory than required.
1307 class _LIBUNWIND_HIDDEN Registers_arm {
1308 public:
1309   Registers_arm();
1310   Registers_arm(const void *registers);
1311 
1312   bool        validRegister(int num) const;
1313   uint32_t    getRegister(int num);
1314   void        setRegister(int num, uint32_t value);
1315   bool        validFloatRegister(int num) const;
1316   unw_fpreg_t getFloatRegister(int num);
1317   void        setFloatRegister(int num, unw_fpreg_t value);
1318   bool        validVectorRegister(int num) const;
1319   v128        getVectorRegister(int num) const;
1320   void        setVectorRegister(int num, v128 value);
1321   const char *getRegisterName(int num);
1322   void        jumpto() {
1323     restoreSavedFloatRegisters();
1324     restoreCoreAndJumpTo();
1325   }
1326 
1327   uint32_t  getSP() const         { return _registers.__sp; }
1328   void      setSP(uint32_t value) { _registers.__sp = value; }
1329   uint32_t  getIP() const         { return _registers.__pc; }
1330   void      setIP(uint32_t value) { _registers.__pc = value; }
1331 
1332   void saveVFPAsX() {
1333     assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
1334     _use_X_for_vfp_save = true;
1335   }
1336 
1337   void restoreSavedFloatRegisters() {
1338     if (_saved_vfp_d0_d15) {
1339       if (_use_X_for_vfp_save)
1340         restoreVFPWithFLDMX(_vfp_d0_d15_pad);
1341       else
1342         restoreVFPWithFLDMD(_vfp_d0_d15_pad);
1343     }
1344     if (_saved_vfp_d16_d31)
1345       restoreVFPv3(_vfp_d16_d31);
1346 #if defined(__ARM_WMMX)
1347     if (_saved_iwmmx)
1348       restoreiWMMX(_iwmmx);
1349     if (_saved_iwmmx_control)
1350       restoreiWMMXControl(_iwmmx_control);
1351 #endif
1352   }
1353 
1354 private:
1355   struct GPRs {
1356     uint32_t __r[13]; // r0-r12
1357     uint32_t __sp;    // Stack pointer r13
1358     uint32_t __lr;    // Link register r14
1359     uint32_t __pc;    // Program counter r15
1360   };
1361 
1362   static void saveVFPWithFSTMD(unw_fpreg_t*);
1363   static void saveVFPWithFSTMX(unw_fpreg_t*);
1364   static void saveVFPv3(unw_fpreg_t*);
1365   static void restoreVFPWithFLDMD(unw_fpreg_t*);
1366   static void restoreVFPWithFLDMX(unw_fpreg_t*);
1367   static void restoreVFPv3(unw_fpreg_t*);
1368 #if defined(__ARM_WMMX)
1369   static void saveiWMMX(unw_fpreg_t*);
1370   static void saveiWMMXControl(uint32_t*);
1371   static void restoreiWMMX(unw_fpreg_t*);
1372   static void restoreiWMMXControl(uint32_t*);
1373 #endif
1374   void restoreCoreAndJumpTo();
1375 
1376   // ARM registers
1377   GPRs _registers;
1378 
1379   // We save floating point registers lazily because we can't know ahead of
1380   // time which ones are used. See EHABI #4.7.
1381 
1382   // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
1383   //
1384   // See EHABI #7.5 that explains how matching instruction sequences for load
1385   // and store need to be used to correctly restore the exact register bits.
1386   bool _use_X_for_vfp_save;
1387   // Whether VFP D0-D15 are saved.
1388   bool _saved_vfp_d0_d15;
1389   // Whether VFPv3 D16-D31 are saved.
1390   bool _saved_vfp_d16_d31;
1391   // VFP registers D0-D15, + padding if saved using FSTMX
1392   unw_fpreg_t _vfp_d0_d15_pad[17];
1393   // VFPv3 registers D16-D31, always saved using FSTMD
1394   unw_fpreg_t _vfp_d16_d31[16];
1395 #if defined(__ARM_WMMX)
1396   // Whether iWMMX data registers are saved.
1397   bool _saved_iwmmx;
1398   // Whether iWMMX control registers are saved.
1399   bool _saved_iwmmx_control;
1400   // iWMMX registers
1401   unw_fpreg_t _iwmmx[16];
1402   // iWMMX control registers
1403   uint32_t _iwmmx_control[4];
1404 #endif
1405 };
1406 
1407 inline Registers_arm::Registers_arm(const void *registers)
1408   : _use_X_for_vfp_save(false),
1409     _saved_vfp_d0_d15(false),
1410     _saved_vfp_d16_d31(false) {
1411   static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
1412                 "arm registers do not fit into unw_context_t");
1413   // See unw_getcontext() note about data.
1414   memcpy(&_registers, registers, sizeof(_registers));
1415   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
1416   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
1417 #if defined(__ARM_WMMX)
1418   _saved_iwmmx = false;
1419   _saved_iwmmx_control = false;
1420   memset(&_iwmmx, 0, sizeof(_iwmmx));
1421   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
1422 #endif
1423 }
1424 
1425 inline Registers_arm::Registers_arm()
1426   : _use_X_for_vfp_save(false),
1427     _saved_vfp_d0_d15(false),
1428     _saved_vfp_d16_d31(false) {
1429   memset(&_registers, 0, sizeof(_registers));
1430   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
1431   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
1432 #if defined(__ARM_WMMX)
1433   _saved_iwmmx = false;
1434   _saved_iwmmx_control = false;
1435   memset(&_iwmmx, 0, sizeof(_iwmmx));
1436   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
1437 #endif
1438 }
1439 
1440 inline bool Registers_arm::validRegister(int regNum) const {
1441   // Returns true for all non-VFP registers supported by the EHABI
1442   // virtual register set (VRS).
1443   if (regNum == UNW_REG_IP)
1444     return true;
1445 
1446   if (regNum == UNW_REG_SP)
1447     return true;
1448 
1449   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
1450     return true;
1451 
1452 #if defined(__ARM_WMMX)
1453   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
1454     return true;
1455 #endif
1456 
1457   return false;
1458 }
1459 
1460 inline uint32_t Registers_arm::getRegister(int regNum) {
1461   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
1462     return _registers.__sp;
1463 
1464   if (regNum == UNW_ARM_LR)
1465     return _registers.__lr;
1466 
1467   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
1468     return _registers.__pc;
1469 
1470   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
1471     return _registers.__r[regNum];
1472 
1473 #if defined(__ARM_WMMX)
1474   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
1475     if (!_saved_iwmmx_control) {
1476       _saved_iwmmx_control = true;
1477       saveiWMMXControl(_iwmmx_control);
1478     }
1479     return _iwmmx_control[regNum - UNW_ARM_WC0];
1480   }
1481 #endif
1482 
1483   _LIBUNWIND_ABORT("unsupported arm register");
1484 }
1485 
1486 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
1487   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
1488     _registers.__sp = value;
1489     return;
1490   }
1491 
1492   if (regNum == UNW_ARM_LR) {
1493     _registers.__lr = value;
1494     return;
1495   }
1496 
1497   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
1498     _registers.__pc = value;
1499     return;
1500   }
1501 
1502   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
1503     _registers.__r[regNum] = value;
1504     return;
1505   }
1506 
1507 #if defined(__ARM_WMMX)
1508   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
1509     if (!_saved_iwmmx_control) {
1510       _saved_iwmmx_control = true;
1511       saveiWMMXControl(_iwmmx_control);
1512     }
1513     _iwmmx_control[regNum - UNW_ARM_WC0] = value;
1514     return;
1515   }
1516 #endif
1517 
1518   _LIBUNWIND_ABORT("unsupported arm register");
1519 }
1520 
1521 inline const char *Registers_arm::getRegisterName(int regNum) {
1522   switch (regNum) {
1523   case UNW_REG_IP:
1524   case UNW_ARM_IP: // UNW_ARM_R15 is alias
1525     return "pc";
1526   case UNW_ARM_LR: // UNW_ARM_R14 is alias
1527     return "lr";
1528   case UNW_REG_SP:
1529   case UNW_ARM_SP: // UNW_ARM_R13 is alias
1530     return "sp";
1531   case UNW_ARM_R0:
1532     return "r0";
1533   case UNW_ARM_R1:
1534     return "r1";
1535   case UNW_ARM_R2:
1536     return "r2";
1537   case UNW_ARM_R3:
1538     return "r3";
1539   case UNW_ARM_R4:
1540     return "r4";
1541   case UNW_ARM_R5:
1542     return "r5";
1543   case UNW_ARM_R6:
1544     return "r6";
1545   case UNW_ARM_R7:
1546     return "r7";
1547   case UNW_ARM_R8:
1548     return "r8";
1549   case UNW_ARM_R9:
1550     return "r9";
1551   case UNW_ARM_R10:
1552     return "r10";
1553   case UNW_ARM_R11:
1554     return "r11";
1555   case UNW_ARM_R12:
1556     return "r12";
1557   case UNW_ARM_S0:
1558     return "s0";
1559   case UNW_ARM_S1:
1560     return "s1";
1561   case UNW_ARM_S2:
1562     return "s2";
1563   case UNW_ARM_S3:
1564     return "s3";
1565   case UNW_ARM_S4:
1566     return "s4";
1567   case UNW_ARM_S5:
1568     return "s5";
1569   case UNW_ARM_S6:
1570     return "s6";
1571   case UNW_ARM_S7:
1572     return "s7";
1573   case UNW_ARM_S8:
1574     return "s8";
1575   case UNW_ARM_S9:
1576     return "s9";
1577   case UNW_ARM_S10:
1578     return "s10";
1579   case UNW_ARM_S11:
1580     return "s11";
1581   case UNW_ARM_S12:
1582     return "s12";
1583   case UNW_ARM_S13:
1584     return "s13";
1585   case UNW_ARM_S14:
1586     return "s14";
1587   case UNW_ARM_S15:
1588     return "s15";
1589   case UNW_ARM_S16:
1590     return "s16";
1591   case UNW_ARM_S17:
1592     return "s17";
1593   case UNW_ARM_S18:
1594     return "s18";
1595   case UNW_ARM_S19:
1596     return "s19";
1597   case UNW_ARM_S20:
1598     return "s20";
1599   case UNW_ARM_S21:
1600     return "s21";
1601   case UNW_ARM_S22:
1602     return "s22";
1603   case UNW_ARM_S23:
1604     return "s23";
1605   case UNW_ARM_S24:
1606     return "s24";
1607   case UNW_ARM_S25:
1608     return "s25";
1609   case UNW_ARM_S26:
1610     return "s26";
1611   case UNW_ARM_S27:
1612     return "s27";
1613   case UNW_ARM_S28:
1614     return "s28";
1615   case UNW_ARM_S29:
1616     return "s29";
1617   case UNW_ARM_S30:
1618     return "s30";
1619   case UNW_ARM_S31:
1620     return "s31";
1621   case UNW_ARM_D0:
1622     return "d0";
1623   case UNW_ARM_D1:
1624     return "d1";
1625   case UNW_ARM_D2:
1626     return "d2";
1627   case UNW_ARM_D3:
1628     return "d3";
1629   case UNW_ARM_D4:
1630     return "d4";
1631   case UNW_ARM_D5:
1632     return "d5";
1633   case UNW_ARM_D6:
1634     return "d6";
1635   case UNW_ARM_D7:
1636     return "d7";
1637   case UNW_ARM_D8:
1638     return "d8";
1639   case UNW_ARM_D9:
1640     return "d9";
1641   case UNW_ARM_D10:
1642     return "d10";
1643   case UNW_ARM_D11:
1644     return "d11";
1645   case UNW_ARM_D12:
1646     return "d12";
1647   case UNW_ARM_D13:
1648     return "d13";
1649   case UNW_ARM_D14:
1650     return "d14";
1651   case UNW_ARM_D15:
1652     return "d15";
1653   case UNW_ARM_D16:
1654     return "d16";
1655   case UNW_ARM_D17:
1656     return "d17";
1657   case UNW_ARM_D18:
1658     return "d18";
1659   case UNW_ARM_D19:
1660     return "d19";
1661   case UNW_ARM_D20:
1662     return "d20";
1663   case UNW_ARM_D21:
1664     return "d21";
1665   case UNW_ARM_D22:
1666     return "d22";
1667   case UNW_ARM_D23:
1668     return "d23";
1669   case UNW_ARM_D24:
1670     return "d24";
1671   case UNW_ARM_D25:
1672     return "d25";
1673   case UNW_ARM_D26:
1674     return "d26";
1675   case UNW_ARM_D27:
1676     return "d27";
1677   case UNW_ARM_D28:
1678     return "d28";
1679   case UNW_ARM_D29:
1680     return "d29";
1681   case UNW_ARM_D30:
1682     return "d30";
1683   case UNW_ARM_D31:
1684     return "d31";
1685   default:
1686     return "unknown register";
1687   }
1688 }
1689 
1690 inline bool Registers_arm::validFloatRegister(int regNum) const {
1691   // NOTE: Consider the intel MMX registers floating points so the
1692   // unw_get_fpreg can be used to transmit the 64-bit data back.
1693   return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
1694 #if defined(__ARM_WMMX)
1695       || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
1696 #endif
1697       ;
1698 }
1699 
1700 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
1701   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
1702     if (!_saved_vfp_d0_d15) {
1703       _saved_vfp_d0_d15 = true;
1704       if (_use_X_for_vfp_save)
1705         saveVFPWithFSTMX(_vfp_d0_d15_pad);
1706       else
1707         saveVFPWithFSTMD(_vfp_d0_d15_pad);
1708     }
1709     return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
1710   }
1711 
1712   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
1713     if (!_saved_vfp_d16_d31) {
1714       _saved_vfp_d16_d31 = true;
1715       saveVFPv3(_vfp_d16_d31);
1716     }
1717     return _vfp_d16_d31[regNum - UNW_ARM_D16];
1718   }
1719 
1720 #if defined(__ARM_WMMX)
1721   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
1722     if (!_saved_iwmmx) {
1723       _saved_iwmmx = true;
1724       saveiWMMX(_iwmmx);
1725     }
1726     return _iwmmx[regNum - UNW_ARM_WR0];
1727   }
1728 #endif
1729 
1730   _LIBUNWIND_ABORT("Unknown ARM float register");
1731 }
1732 
1733 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
1734   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
1735     if (!_saved_vfp_d0_d15) {
1736       _saved_vfp_d0_d15 = true;
1737       if (_use_X_for_vfp_save)
1738         saveVFPWithFSTMX(_vfp_d0_d15_pad);
1739       else
1740         saveVFPWithFSTMD(_vfp_d0_d15_pad);
1741     }
1742     _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
1743     return;
1744   }
1745 
1746   if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
1747     if (!_saved_vfp_d16_d31) {
1748       _saved_vfp_d16_d31 = true;
1749       saveVFPv3(_vfp_d16_d31);
1750     }
1751     _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
1752     return;
1753   }
1754 
1755 #if defined(__ARM_WMMX)
1756   if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
1757     if (!_saved_iwmmx) {
1758       _saved_iwmmx = true;
1759       saveiWMMX(_iwmmx);
1760     }
1761     _iwmmx[regNum - UNW_ARM_WR0] = value;
1762     return;
1763   }
1764 #endif
1765 
1766   _LIBUNWIND_ABORT("Unknown ARM float register");
1767 }
1768 
1769 inline bool Registers_arm::validVectorRegister(int) const {
1770   return false;
1771 }
1772 
1773 inline v128 Registers_arm::getVectorRegister(int) const {
1774   _LIBUNWIND_ABORT("ARM vector support not implemented");
1775 }
1776 
1777 inline void Registers_arm::setVectorRegister(int, v128) {
1778   _LIBUNWIND_ABORT("ARM vector support not implemented");
1779 }
1780 #endif // _LIBUNWIND_TARGET_ARM
1781 
1782 
1783 #if defined(_LIBUNWIND_TARGET_OR1K)
1784 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
1785 /// process.
1786 class _LIBUNWIND_HIDDEN Registers_or1k {
1787 public:
1788   Registers_or1k();
1789   Registers_or1k(const void *registers);
1790 
1791   bool        validRegister(int num) const;
1792   uint32_t    getRegister(int num) const;
1793   void        setRegister(int num, uint32_t value);
1794   bool        validFloatRegister(int num) const;
1795   double      getFloatRegister(int num) const;
1796   void        setFloatRegister(int num, double value);
1797   bool        validVectorRegister(int num) const;
1798   v128        getVectorRegister(int num) const;
1799   void        setVectorRegister(int num, v128 value);
1800   const char *getRegisterName(int num);
1801   void        jumpto();
1802   static int  lastDwarfRegNum() { return 31; }
1803 
1804   uint64_t  getSP() const         { return _registers.__r[1]; }
1805   void      setSP(uint32_t value) { _registers.__r[1] = value; }
1806   uint64_t  getIP() const         { return _registers.__r[9]; }
1807   void      setIP(uint32_t value) { _registers.__r[9] = value; }
1808 
1809 private:
1810   struct or1k_thread_state_t {
1811     unsigned int __r[32];
1812   };
1813 
1814   or1k_thread_state_t _registers;
1815 };
1816 
1817 inline Registers_or1k::Registers_or1k(const void *registers) {
1818   static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
1819                 "or1k registers do not fit into unw_context_t");
1820   memcpy(&_registers, static_cast<const uint8_t *>(registers),
1821          sizeof(_registers));
1822 }
1823 
1824 inline Registers_or1k::Registers_or1k() {
1825   memset(&_registers, 0, sizeof(_registers));
1826 }
1827 
1828 inline bool Registers_or1k::validRegister(int regNum) const {
1829   if (regNum == UNW_REG_IP)
1830     return true;
1831   if (regNum == UNW_REG_SP)
1832     return true;
1833   if (regNum < 0)
1834     return false;
1835   if (regNum <= UNW_OR1K_R31)
1836     return true;
1837   return false;
1838 }
1839 
1840 inline uint32_t Registers_or1k::getRegister(int regNum) const {
1841   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
1842     return _registers.__r[regNum - UNW_OR1K_R0];
1843 
1844   switch (regNum) {
1845   case UNW_REG_IP:
1846     return _registers.__r[9];
1847   case UNW_REG_SP:
1848     return _registers.__r[1];
1849   }
1850   _LIBUNWIND_ABORT("unsupported or1k register");
1851 }
1852 
1853 inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
1854   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
1855     _registers.__r[regNum - UNW_OR1K_R0] = value;
1856     return;
1857   }
1858 
1859   switch (regNum) {
1860   case UNW_REG_IP:
1861     _registers.__r[9] = value;
1862     return;
1863   case UNW_REG_SP:
1864     _registers.__r[1] = value;
1865     return;
1866   }
1867   _LIBUNWIND_ABORT("unsupported or1k register");
1868 }
1869 
1870 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
1871   return false;
1872 }
1873 
1874 inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
1875   _LIBUNWIND_ABORT("or1k float support not implemented");
1876 }
1877 
1878 inline void Registers_or1k::setFloatRegister(int /* regNum */,
1879                                              double /* value */) {
1880   _LIBUNWIND_ABORT("or1k float support not implemented");
1881 }
1882 
1883 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
1884   return false;
1885 }
1886 
1887 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
1888   _LIBUNWIND_ABORT("or1k vector support not implemented");
1889 }
1890 
1891 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
1892   _LIBUNWIND_ABORT("or1k vector support not implemented");
1893 }
1894 
1895 inline const char *Registers_or1k::getRegisterName(int regNum) {
1896   switch (regNum) {
1897   case UNW_OR1K_R0:
1898     return "r0";
1899   case UNW_OR1K_R1:
1900     return "r1";
1901   case UNW_OR1K_R2:
1902     return "r2";
1903   case UNW_OR1K_R3:
1904     return "r3";
1905   case UNW_OR1K_R4:
1906     return "r4";
1907   case UNW_OR1K_R5:
1908     return "r5";
1909   case UNW_OR1K_R6:
1910     return "r6";
1911   case UNW_OR1K_R7:
1912     return "r7";
1913   case UNW_OR1K_R8:
1914     return "r8";
1915   case UNW_OR1K_R9:
1916     return "r9";
1917   case UNW_OR1K_R10:
1918     return "r10";
1919   case UNW_OR1K_R11:
1920     return "r11";
1921   case UNW_OR1K_R12:
1922     return "r12";
1923   case UNW_OR1K_R13:
1924     return "r13";
1925   case UNW_OR1K_R14:
1926     return "r14";
1927   case UNW_OR1K_R15:
1928     return "r15";
1929   case UNW_OR1K_R16:
1930     return "r16";
1931   case UNW_OR1K_R17:
1932     return "r17";
1933   case UNW_OR1K_R18:
1934     return "r18";
1935   case UNW_OR1K_R19:
1936     return "r19";
1937   case UNW_OR1K_R20:
1938     return "r20";
1939   case UNW_OR1K_R21:
1940     return "r21";
1941   case UNW_OR1K_R22:
1942     return "r22";
1943   case UNW_OR1K_R23:
1944     return "r23";
1945   case UNW_OR1K_R24:
1946     return "r24";
1947   case UNW_OR1K_R25:
1948     return "r25";
1949   case UNW_OR1K_R26:
1950     return "r26";
1951   case UNW_OR1K_R27:
1952     return "r27";
1953   case UNW_OR1K_R28:
1954     return "r28";
1955   case UNW_OR1K_R29:
1956     return "r29";
1957   case UNW_OR1K_R30:
1958     return "r30";
1959   case UNW_OR1K_R31:
1960     return "r31";
1961   default:
1962     return "unknown register";
1963   }
1964 
1965 }
1966 #endif // _LIBUNWIND_TARGET_OR1K
1967 } // namespace libunwind
1968 
1969 #endif // __REGISTERS_HPP__
1970