libunwind: update to upstream snapshot r272680
[freebsd.git] / contrib / llvm / projects / libunwind / src / Registers.hpp
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 (_saved_iwmmx)
1347       restoreiWMMX(_iwmmx);
1348     if (_saved_iwmmx_control)
1349       restoreiWMMXControl(_iwmmx_control);
1350   }
1351
1352 private:
1353   struct GPRs {
1354     uint32_t __r[13]; // r0-r12
1355     uint32_t __sp;    // Stack pointer r13
1356     uint32_t __lr;    // Link register r14
1357     uint32_t __pc;    // Program counter r15
1358   };
1359
1360   static void saveVFPWithFSTMD(unw_fpreg_t*);
1361   static void saveVFPWithFSTMX(unw_fpreg_t*);
1362   static void saveVFPv3(unw_fpreg_t*);
1363   static void saveiWMMX(unw_fpreg_t*);
1364   static void saveiWMMXControl(uint32_t*);
1365   static void restoreVFPWithFLDMD(unw_fpreg_t*);
1366   static void restoreVFPWithFLDMX(unw_fpreg_t*);
1367   static void restoreVFPv3(unw_fpreg_t*);
1368   static void restoreiWMMX(unw_fpreg_t*);
1369   static void restoreiWMMXControl(uint32_t*);
1370   void restoreCoreAndJumpTo();
1371
1372   // ARM registers
1373   GPRs _registers;
1374
1375   // We save floating point registers lazily because we can't know ahead of
1376   // time which ones are used. See EHABI #4.7.
1377
1378   // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
1379   //
1380   // See EHABI #7.5 that explains how matching instruction sequences for load
1381   // and store need to be used to correctly restore the exact register bits.
1382   bool _use_X_for_vfp_save;
1383   // Whether VFP D0-D15 are saved.
1384   bool _saved_vfp_d0_d15;
1385   // Whether VFPv3 D16-D31 are saved.
1386   bool _saved_vfp_d16_d31;
1387   // Whether iWMMX data registers are saved.
1388   bool _saved_iwmmx;
1389   // Whether iWMMX control registers are saved.
1390   bool _saved_iwmmx_control;
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   // iWMMX registers
1396   unw_fpreg_t _iwmmx[16];
1397   // iWMMX control registers
1398   uint32_t _iwmmx_control[4];
1399 };
1400
1401 inline Registers_arm::Registers_arm(const void *registers)
1402   : _use_X_for_vfp_save(false),
1403     _saved_vfp_d0_d15(false),
1404     _saved_vfp_d16_d31(false),
1405     _saved_iwmmx(false),
1406     _saved_iwmmx_control(false) {
1407   static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
1408                 "arm registers do not fit into unw_context_t");
1409   // See unw_getcontext() note about data.
1410   memcpy(&_registers, registers, sizeof(_registers));
1411   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
1412   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
1413   memset(&_iwmmx, 0, sizeof(_iwmmx));
1414   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
1415 }
1416
1417 inline Registers_arm::Registers_arm()
1418   : _use_X_for_vfp_save(false),
1419     _saved_vfp_d0_d15(false),
1420     _saved_vfp_d16_d31(false),
1421     _saved_iwmmx(false),
1422     _saved_iwmmx_control(false) {
1423   memset(&_registers, 0, sizeof(_registers));
1424   memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
1425   memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
1426   memset(&_iwmmx, 0, sizeof(_iwmmx));
1427   memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
1428 }
1429
1430 inline bool Registers_arm::validRegister(int regNum) const {
1431   // Returns true for all non-VFP registers supported by the EHABI
1432   // virtual register set (VRS).
1433   if (regNum == UNW_REG_IP)
1434     return true;
1435   if (regNum == UNW_REG_SP)
1436     return true;
1437   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
1438     return true;
1439   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
1440     return true;
1441   return false;
1442 }
1443
1444 inline uint32_t Registers_arm::getRegister(int regNum) {
1445   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
1446     return _registers.__sp;
1447   if (regNum == UNW_ARM_LR)
1448     return _registers.__lr;
1449   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
1450     return _registers.__pc;
1451   if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
1452     return _registers.__r[regNum];
1453   if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
1454     if (!_saved_iwmmx_control) {
1455       _saved_iwmmx_control = true;
1456       saveiWMMXControl(_iwmmx_control);
1457     }
1458     return _iwmmx_control[regNum - UNW_ARM_WC0];
1459   }
1460   _LIBUNWIND_ABORT("unsupported arm register");
1461 }
1462
1463 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
1464   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
1465     _registers.__sp = value;
1466   else if (regNum == UNW_ARM_LR)
1467     _registers.__lr = value;
1468   else if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
1469     _registers.__pc = value;
1470   else if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
1471     _registers.__r[regNum] = value;
1472   else if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
1473     if (!_saved_iwmmx_control) {
1474       _saved_iwmmx_control = true;
1475       saveiWMMXControl(_iwmmx_control);
1476     }
1477     _iwmmx_control[regNum - UNW_ARM_WC0] = value;
1478   } else
1479     _LIBUNWIND_ABORT("unsupported arm register");
1480 }
1481
1482 inline const char *Registers_arm::getRegisterName(int regNum) {
1483   switch (regNum) {
1484   case UNW_REG_IP:
1485   case UNW_ARM_IP: // UNW_ARM_R15 is alias
1486     return "pc";
1487   case UNW_ARM_LR: // UNW_ARM_R14 is alias
1488     return "lr";
1489   case UNW_REG_SP:
1490   case UNW_ARM_SP: // UNW_ARM_R13 is alias
1491     return "sp";
1492   case UNW_ARM_R0:
1493     return "r0";
1494   case UNW_ARM_R1:
1495     return "r1";
1496   case UNW_ARM_R2:
1497     return "r2";
1498   case UNW_ARM_R3:
1499     return "r3";
1500   case UNW_ARM_R4:
1501     return "r4";
1502   case UNW_ARM_R5:
1503     return "r5";
1504   case UNW_ARM_R6:
1505     return "r6";
1506   case UNW_ARM_R7:
1507     return "r7";
1508   case UNW_ARM_R8:
1509     return "r8";
1510   case UNW_ARM_R9:
1511     return "r9";
1512   case UNW_ARM_R10:
1513     return "r10";
1514   case UNW_ARM_R11:
1515     return "r11";
1516   case UNW_ARM_R12:
1517     return "r12";
1518   case UNW_ARM_S0:
1519     return "s0";
1520   case UNW_ARM_S1:
1521     return "s1";
1522   case UNW_ARM_S2:
1523     return "s2";
1524   case UNW_ARM_S3:
1525     return "s3";
1526   case UNW_ARM_S4:
1527     return "s4";
1528   case UNW_ARM_S5:
1529     return "s5";
1530   case UNW_ARM_S6:
1531     return "s6";
1532   case UNW_ARM_S7:
1533     return "s7";
1534   case UNW_ARM_S8:
1535     return "s8";
1536   case UNW_ARM_S9:
1537     return "s9";
1538   case UNW_ARM_S10:
1539     return "s10";
1540   case UNW_ARM_S11:
1541     return "s11";
1542   case UNW_ARM_S12:
1543     return "s12";
1544   case UNW_ARM_S13:
1545     return "s13";
1546   case UNW_ARM_S14:
1547     return "s14";
1548   case UNW_ARM_S15:
1549     return "s15";
1550   case UNW_ARM_S16:
1551     return "s16";
1552   case UNW_ARM_S17:
1553     return "s17";
1554   case UNW_ARM_S18:
1555     return "s18";
1556   case UNW_ARM_S19:
1557     return "s19";
1558   case UNW_ARM_S20:
1559     return "s20";
1560   case UNW_ARM_S21:
1561     return "s21";
1562   case UNW_ARM_S22:
1563     return "s22";
1564   case UNW_ARM_S23:
1565     return "s23";
1566   case UNW_ARM_S24:
1567     return "s24";
1568   case UNW_ARM_S25:
1569     return "s25";
1570   case UNW_ARM_S26:
1571     return "s26";
1572   case UNW_ARM_S27:
1573     return "s27";
1574   case UNW_ARM_S28:
1575     return "s28";
1576   case UNW_ARM_S29:
1577     return "s29";
1578   case UNW_ARM_S30:
1579     return "s30";
1580   case UNW_ARM_S31:
1581     return "s31";
1582   case UNW_ARM_D0:
1583     return "d0";
1584   case UNW_ARM_D1:
1585     return "d1";
1586   case UNW_ARM_D2:
1587     return "d2";
1588   case UNW_ARM_D3:
1589     return "d3";
1590   case UNW_ARM_D4:
1591     return "d4";
1592   case UNW_ARM_D5:
1593     return "d5";
1594   case UNW_ARM_D6:
1595     return "d6";
1596   case UNW_ARM_D7:
1597     return "d7";
1598   case UNW_ARM_D8:
1599     return "d8";
1600   case UNW_ARM_D9:
1601     return "d9";
1602   case UNW_ARM_D10:
1603     return "d10";
1604   case UNW_ARM_D11:
1605     return "d11";
1606   case UNW_ARM_D12:
1607     return "d12";
1608   case UNW_ARM_D13:
1609     return "d13";
1610   case UNW_ARM_D14:
1611     return "d14";
1612   case UNW_ARM_D15:
1613     return "d15";
1614   case UNW_ARM_D16:
1615     return "d16";
1616   case UNW_ARM_D17:
1617     return "d17";
1618   case UNW_ARM_D18:
1619     return "d18";
1620   case UNW_ARM_D19:
1621     return "d19";
1622   case UNW_ARM_D20:
1623     return "d20";
1624   case UNW_ARM_D21:
1625     return "d21";
1626   case UNW_ARM_D22:
1627     return "d22";
1628   case UNW_ARM_D23:
1629     return "d23";
1630   case UNW_ARM_D24:
1631     return "d24";
1632   case UNW_ARM_D25:
1633     return "d25";
1634   case UNW_ARM_D26:
1635     return "d26";
1636   case UNW_ARM_D27:
1637     return "d27";
1638   case UNW_ARM_D28:
1639     return "d28";
1640   case UNW_ARM_D29:
1641     return "d29";
1642   case UNW_ARM_D30:
1643     return "d30";
1644   case UNW_ARM_D31:
1645     return "d31";
1646   default:
1647     return "unknown register";
1648   }
1649 }
1650
1651 inline bool Registers_arm::validFloatRegister(int regNum) const {
1652   // NOTE: Consider the intel MMX registers floating points so the
1653   // unw_get_fpreg can be used to transmit the 64-bit data back.
1654   return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
1655       || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15));
1656 }
1657
1658 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
1659   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
1660     if (!_saved_vfp_d0_d15) {
1661       _saved_vfp_d0_d15 = true;
1662       if (_use_X_for_vfp_save)
1663         saveVFPWithFSTMX(_vfp_d0_d15_pad);
1664       else
1665         saveVFPWithFSTMD(_vfp_d0_d15_pad);
1666     }
1667     return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
1668   } else if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
1669     if (!_saved_vfp_d16_d31) {
1670       _saved_vfp_d16_d31 = true;
1671       saveVFPv3(_vfp_d16_d31);
1672     }
1673     return _vfp_d16_d31[regNum - UNW_ARM_D16];
1674   } else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
1675     if (!_saved_iwmmx) {
1676       _saved_iwmmx = true;
1677       saveiWMMX(_iwmmx);
1678     }
1679     return _iwmmx[regNum - UNW_ARM_WR0];
1680   } else {
1681     _LIBUNWIND_ABORT("Unknown ARM float register");
1682   }
1683 }
1684
1685 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
1686   if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
1687     if (!_saved_vfp_d0_d15) {
1688       _saved_vfp_d0_d15 = true;
1689       if (_use_X_for_vfp_save)
1690         saveVFPWithFSTMX(_vfp_d0_d15_pad);
1691       else
1692         saveVFPWithFSTMD(_vfp_d0_d15_pad);
1693     }
1694     _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
1695   } else if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
1696     if (!_saved_vfp_d16_d31) {
1697       _saved_vfp_d16_d31 = true;
1698       saveVFPv3(_vfp_d16_d31);
1699     }
1700     _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
1701   } else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
1702     if (!_saved_iwmmx) {
1703       _saved_iwmmx = true;
1704       saveiWMMX(_iwmmx);
1705     }
1706     _iwmmx[regNum - UNW_ARM_WR0] = value;
1707   } else {
1708     _LIBUNWIND_ABORT("Unknown ARM float register");
1709   }
1710 }
1711
1712 inline bool Registers_arm::validVectorRegister(int) const {
1713   return false;
1714 }
1715
1716 inline v128 Registers_arm::getVectorRegister(int) const {
1717   _LIBUNWIND_ABORT("ARM vector support not implemented");
1718 }
1719
1720 inline void Registers_arm::setVectorRegister(int, v128) {
1721   _LIBUNWIND_ABORT("ARM vector support not implemented");
1722 }
1723 #endif // _LIBUNWIND_TARGET_ARM
1724
1725
1726 #if defined(_LIBUNWIND_TARGET_OR1K)
1727 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
1728 /// process.
1729 class _LIBUNWIND_HIDDEN Registers_or1k {
1730 public:
1731   Registers_or1k();
1732   Registers_or1k(const void *registers);
1733
1734   bool        validRegister(int num) const;
1735   uint32_t    getRegister(int num) const;
1736   void        setRegister(int num, uint32_t value);
1737   bool        validFloatRegister(int num) const;
1738   double      getFloatRegister(int num) const;
1739   void        setFloatRegister(int num, double value);
1740   bool        validVectorRegister(int num) const;
1741   v128        getVectorRegister(int num) const;
1742   void        setVectorRegister(int num, v128 value);
1743   const char *getRegisterName(int num);
1744   void        jumpto();
1745   static int  lastDwarfRegNum() { return 31; }
1746
1747   uint64_t  getSP() const         { return _registers.__r[1]; }
1748   void      setSP(uint32_t value) { _registers.__r[1] = value; }
1749   uint64_t  getIP() const         { return _registers.__r[9]; }
1750   void      setIP(uint32_t value) { _registers.__r[9] = value; }
1751
1752 private:
1753   struct or1k_thread_state_t {
1754     unsigned int __r[32];
1755   };
1756
1757   or1k_thread_state_t _registers;
1758 };
1759
1760 inline Registers_or1k::Registers_or1k(const void *registers) {
1761   static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
1762                 "or1k registers do not fit into unw_context_t");
1763   memcpy(&_registers, static_cast<const uint8_t *>(registers),
1764          sizeof(_registers));
1765 }
1766
1767 inline Registers_or1k::Registers_or1k() {
1768   memset(&_registers, 0, sizeof(_registers));
1769 }
1770
1771 inline bool Registers_or1k::validRegister(int regNum) const {
1772   if (regNum == UNW_REG_IP)
1773     return true;
1774   if (regNum == UNW_REG_SP)
1775     return true;
1776   if (regNum < 0)
1777     return false;
1778   if (regNum <= UNW_OR1K_R31)
1779     return true;
1780   return false;
1781 }
1782
1783 inline uint32_t Registers_or1k::getRegister(int regNum) const {
1784   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
1785     return _registers.__r[regNum - UNW_OR1K_R0];
1786
1787   switch (regNum) {
1788   case UNW_REG_IP:
1789     return _registers.__r[9];
1790   case UNW_REG_SP:
1791     return _registers.__r[1];
1792   }
1793   _LIBUNWIND_ABORT("unsupported or1k register");
1794 }
1795
1796 inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
1797   if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
1798     _registers.__r[regNum - UNW_OR1K_R0] = value;
1799     return;
1800   }
1801
1802   switch (regNum) {
1803   case UNW_REG_IP:
1804     _registers.__r[9] = value;
1805     return;
1806   case UNW_REG_SP:
1807     _registers.__r[1] = value;
1808     return;
1809   }
1810   _LIBUNWIND_ABORT("unsupported or1k register");
1811 }
1812
1813 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
1814   return false;
1815 }
1816
1817 inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
1818   _LIBUNWIND_ABORT("or1k float support not implemented");
1819 }
1820
1821 inline void Registers_or1k::setFloatRegister(int /* regNum */,
1822                                              double /* value */) {
1823   _LIBUNWIND_ABORT("or1k float support not implemented");
1824 }
1825
1826 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
1827   return false;
1828 }
1829
1830 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
1831   _LIBUNWIND_ABORT("or1k vector support not implemented");
1832 }
1833
1834 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
1835   _LIBUNWIND_ABORT("or1k vector support not implemented");
1836 }
1837
1838 inline const char *Registers_or1k::getRegisterName(int regNum) {
1839   switch (regNum) {
1840   case UNW_OR1K_R0:
1841     return "r0";
1842   case UNW_OR1K_R1:
1843     return "r1";
1844   case UNW_OR1K_R2:
1845     return "r2";
1846   case UNW_OR1K_R3:
1847     return "r3";
1848   case UNW_OR1K_R4:
1849     return "r4";
1850   case UNW_OR1K_R5:
1851     return "r5";
1852   case UNW_OR1K_R6:
1853     return "r6";
1854   case UNW_OR1K_R7:
1855     return "r7";
1856   case UNW_OR1K_R8:
1857     return "r8";
1858   case UNW_OR1K_R9:
1859     return "r9";
1860   case UNW_OR1K_R10:
1861     return "r10";
1862   case UNW_OR1K_R11:
1863     return "r11";
1864   case UNW_OR1K_R12:
1865     return "r12";
1866   case UNW_OR1K_R13:
1867     return "r13";
1868   case UNW_OR1K_R14:
1869     return "r14";
1870   case UNW_OR1K_R15:
1871     return "r15";
1872   case UNW_OR1K_R16:
1873     return "r16";
1874   case UNW_OR1K_R17:
1875     return "r17";
1876   case UNW_OR1K_R18:
1877     return "r18";
1878   case UNW_OR1K_R19:
1879     return "r19";
1880   case UNW_OR1K_R20:
1881     return "r20";
1882   case UNW_OR1K_R21:
1883     return "r21";
1884   case UNW_OR1K_R22:
1885     return "r22";
1886   case UNW_OR1K_R23:
1887     return "r23";
1888   case UNW_OR1K_R24:
1889     return "r24";
1890   case UNW_OR1K_R25:
1891     return "r25";
1892   case UNW_OR1K_R26:
1893     return "r26";
1894   case UNW_OR1K_R27:
1895     return "r27";
1896   case UNW_OR1K_R28:
1897     return "r28";
1898   case UNW_OR1K_R29:
1899     return "r29";
1900   case UNW_OR1K_R30:
1901     return "r30";
1902   case UNW_OR1K_R31:
1903     return "r31";
1904   default:
1905     return "unknown register";
1906   }
1907
1908 }
1909 #endif // _LIBUNWIND_TARGET_OR1K
1910
1911
1912 #if defined(_LIBUNWIND_TARGET_RISCV)
1913 /// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
1914 /// process.
1915 class _LIBUNWIND_HIDDEN Registers_riscv {
1916 public:
1917   Registers_riscv();
1918   Registers_riscv(const void *registers);
1919
1920   bool        validRegister(int num) const;
1921   uint64_t    getRegister(int num) const;
1922   void        setRegister(int num, uint64_t value);
1923   bool        validFloatRegister(int num) const;
1924   double      getFloatRegister(int num) const;
1925   void        setFloatRegister(int num, double value);
1926   bool        validVectorRegister(int num) const;
1927   v128        getVectorRegister(int num) const;
1928   void        setVectorRegister(int num, v128 value);
1929   const char *getRegisterName(int num);
1930   void        jumpto();
1931   static int  lastDwarfRegNum() { return 95; }
1932
1933   uint64_t  getSP() const         { return _registers.__x[2]; }
1934   void      setSP(uint64_t value) { _registers.__x[2] = value; }
1935   uint64_t  getIP() const         { return _registers.__x[1]; }
1936   void      setIP(uint64_t value) { _registers.__x[1] = value; }
1937
1938 private:
1939   struct GPRs {
1940     uint64_t __x[32]; // x0-x31
1941   };
1942
1943   GPRs    _registers;
1944   double  _vectorHalfRegisters[32];
1945   // Currently only the lower double in 128-bit vectore registers
1946   // is perserved during unwinding.  We could define new register
1947   // numbers (> 96) which mean whole vector registers, then this
1948   // struct would need to change to contain whole vector registers.
1949 };
1950
1951 inline Registers_riscv::Registers_riscv(const void *registers) {
1952   static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
1953                 "riscv registers do not fit into unw_context_t");
1954   memcpy(&_registers, registers, sizeof(_registers));
1955   static_assert(sizeof(GPRs) == 0x100,
1956                 "expected VFP registers to be at offset 256");
1957   memcpy(_vectorHalfRegisters,
1958          static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1959          sizeof(_vectorHalfRegisters));
1960 }
1961
1962 inline Registers_riscv::Registers_riscv() {
1963   memset(&_registers, 0, sizeof(_registers));
1964   memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1965 }
1966
1967 inline bool Registers_riscv::validRegister(int regNum) const {
1968   if (regNum == UNW_REG_IP)
1969     return true;
1970   if (regNum == UNW_REG_SP)
1971     return true;
1972   if (regNum < 0)
1973     return false;
1974   if (regNum > 95)
1975     return false;
1976   if ((regNum > 31) && (regNum < 64))
1977     return false;
1978   return true;
1979 }
1980
1981 inline uint64_t Registers_riscv::getRegister(int regNum) const {
1982   if (regNum == UNW_REG_IP)
1983     return _registers.__x[1];
1984   if (regNum == UNW_REG_SP)
1985     return _registers.__x[2];
1986   if ((regNum >= 0) && (regNum < 32))
1987     return _registers.__x[regNum];
1988   _LIBUNWIND_ABORT("unsupported riscv register");
1989 }
1990
1991 inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
1992   if (regNum == UNW_REG_IP)
1993     _registers.__x[1] = value;
1994   else if (regNum == UNW_REG_SP)
1995     _registers.__x[2] = value;
1996   else if ((regNum >= 0) && (regNum < 32))
1997     _registers.__x[regNum] = value;
1998   else
1999     _LIBUNWIND_ABORT("unsupported riscv register");
2000 }
2001
2002 inline const char *Registers_riscv::getRegisterName(int regNum) {
2003   switch (regNum) {
2004   case UNW_REG_IP:
2005     return "ra";
2006   case UNW_REG_SP:
2007     return "sp";
2008   case UNW_RISCV_X0:
2009     return "x0";
2010   case UNW_RISCV_X1:
2011     return "ra";
2012   case UNW_RISCV_X2:
2013     return "sp";
2014   case UNW_RISCV_X3:
2015     return "x3";
2016   case UNW_RISCV_X4:
2017     return "x4";
2018   case UNW_RISCV_X5:
2019     return "x5";
2020   case UNW_RISCV_X6:
2021     return "x6";
2022   case UNW_RISCV_X7:
2023     return "x7";
2024   case UNW_RISCV_X8:
2025     return "x8";
2026   case UNW_RISCV_X9:
2027     return "x9";
2028   case UNW_RISCV_X10:
2029     return "x10";
2030   case UNW_RISCV_X11:
2031     return "x11";
2032   case UNW_RISCV_X12:
2033     return "x12";
2034   case UNW_RISCV_X13:
2035     return "x13";
2036   case UNW_RISCV_X14:
2037     return "x14";
2038   case UNW_RISCV_X15:
2039     return "x15";
2040   case UNW_RISCV_X16:
2041     return "x16";
2042   case UNW_RISCV_X17:
2043     return "x17";
2044   case UNW_RISCV_X18:
2045     return "x18";
2046   case UNW_RISCV_X19:
2047     return "x19";
2048   case UNW_RISCV_X20:
2049     return "x20";
2050   case UNW_RISCV_X21:
2051     return "x21";
2052   case UNW_RISCV_X22:
2053     return "x22";
2054   case UNW_RISCV_X23:
2055     return "x23";
2056   case UNW_RISCV_X24:
2057     return "x24";
2058   case UNW_RISCV_X25:
2059     return "x25";
2060   case UNW_RISCV_X26:
2061     return "x26";
2062   case UNW_RISCV_X27:
2063     return "x27";
2064   case UNW_RISCV_X28:
2065     return "x28";
2066   case UNW_RISCV_X29:
2067     return "x29";
2068   case UNW_RISCV_X30:
2069     return "x30";
2070   case UNW_RISCV_X31:
2071     return "x31";
2072   case UNW_RISCV_D0:
2073     return "d0";
2074   case UNW_RISCV_D1:
2075     return "d1";
2076   case UNW_RISCV_D2:
2077     return "d2";
2078   case UNW_RISCV_D3:
2079     return "d3";
2080   case UNW_RISCV_D4:
2081     return "d4";
2082   case UNW_RISCV_D5:
2083     return "d5";
2084   case UNW_RISCV_D6:
2085     return "d6";
2086   case UNW_RISCV_D7:
2087     return "d7";
2088   case UNW_RISCV_D8:
2089     return "d8";
2090   case UNW_RISCV_D9:
2091     return "d9";
2092   case UNW_RISCV_D10:
2093     return "d10";
2094   case UNW_RISCV_D11:
2095     return "d11";
2096   case UNW_RISCV_D12:
2097     return "d12";
2098   case UNW_RISCV_D13:
2099     return "d13";
2100   case UNW_RISCV_D14:
2101     return "d14";
2102   case UNW_RISCV_D15:
2103     return "d15";
2104   case UNW_RISCV_D16:
2105     return "d16";
2106   case UNW_RISCV_D17:
2107     return "d17";
2108   case UNW_RISCV_D18:
2109     return "d18";
2110   case UNW_RISCV_D19:
2111     return "d19";
2112   case UNW_RISCV_D20:
2113     return "d20";
2114   case UNW_RISCV_D21:
2115     return "d21";
2116   case UNW_RISCV_D22:
2117     return "d22";
2118   case UNW_RISCV_D23:
2119     return "d23";
2120   case UNW_RISCV_D24:
2121     return "d24";
2122   case UNW_RISCV_D25:
2123     return "d25";
2124   case UNW_RISCV_D26:
2125     return "d26";
2126   case UNW_RISCV_D27:
2127     return "d27";
2128   case UNW_RISCV_D28:
2129     return "d28";
2130   case UNW_RISCV_D29:
2131     return "d29";
2132   case UNW_RISCV_D30:
2133     return "d30";
2134   case UNW_RISCV_D31:
2135     return "d31";
2136   default:
2137     return "unknown register";
2138   }
2139 }
2140
2141 inline bool Registers_riscv::validFloatRegister(int regNum) const {
2142   if (regNum < UNW_RISCV_D0)
2143     return false;
2144   if (regNum > UNW_RISCV_D31)
2145     return false;
2146   return true;
2147 }
2148
2149 inline double Registers_riscv::getFloatRegister(int regNum) const {
2150   assert(validFloatRegister(regNum));
2151   return _vectorHalfRegisters[regNum - UNW_RISCV_D0];
2152 }
2153
2154 inline void Registers_riscv::setFloatRegister(int regNum, double value) {
2155   assert(validFloatRegister(regNum));
2156   _vectorHalfRegisters[regNum - UNW_RISCV_D0] = value;
2157 }
2158
2159 inline bool Registers_riscv::validVectorRegister(int) const {
2160   return false;
2161 }
2162
2163 inline v128 Registers_riscv::getVectorRegister(int) const {
2164   _LIBUNWIND_ABORT("no riscv vector register support yet");
2165 }
2166
2167 inline void Registers_riscv::setVectorRegister(int, v128) {
2168   _LIBUNWIND_ABORT("no riscv vector register support yet");
2169 }
2170 #endif // _LIBUNWIND_TARGET_RISCV
2171 } // namespace libunwind
2172
2173 #endif // __REGISTERS_HPP__