Upstream version 8.36.169.0
[platform/framework/web/crosswalk.git] / src / third_party / libc++abi / trunk / src / Unwind / 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 <strings.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 /// Registers_x86 holds the register state of a thread in a 32-bit intel
29 /// process.
30 class _LIBUNWIND_HIDDEN Registers_x86 {
31 public:
32   Registers_x86();
33   Registers_x86(const void *registers);
34
35   bool        validRegister(int num) const;
36   uint32_t    getRegister(int num) const;
37   void        setRegister(int num, uint32_t value);
38   bool        validFloatRegister(int) const { return false; }
39   double      getFloatRegister(int num) const;
40   void        setFloatRegister(int num, double value);
41   bool        validVectorRegister(int) const { return false; }
42   v128        getVectorRegister(int num) const;
43   void        setVectorRegister(int num, v128 value);
44   const char *getRegisterName(int num);
45   void        jumpto();
46
47   uint32_t  getSP() const          { return _registers.__esp; }
48   void      setSP(uint32_t value)  { _registers.__esp = value; }
49   uint32_t  getIP() const          { return _registers.__eip; }
50   void      setIP(uint32_t value)  { _registers.__eip = value; }
51   uint32_t  getEBP() const         { return _registers.__ebp; }
52   void      setEBP(uint32_t value) { _registers.__ebp = value; }
53   uint32_t  getEBX() const         { return _registers.__ebx; }
54   void      setEBX(uint32_t value) { _registers.__ebx = value; }
55   uint32_t  getECX() const         { return _registers.__ecx; }
56   void      setECX(uint32_t value) { _registers.__ecx = value; }
57   uint32_t  getEDX() const         { return _registers.__edx; }
58   void      setEDX(uint32_t value) { _registers.__edx = value; }
59   uint32_t  getESI() const         { return _registers.__esi; }
60   void      setESI(uint32_t value) { _registers.__esi = value; }
61   uint32_t  getEDI() const         { return _registers.__edi; }
62   void      setEDI(uint32_t value) { _registers.__edi = value; }
63
64 private:
65   struct GPRs {
66     unsigned int __eax;
67     unsigned int __ebx;
68     unsigned int __ecx;
69     unsigned int __edx;
70     unsigned int __edi;
71     unsigned int __esi;
72     unsigned int __ebp;
73     unsigned int __esp;
74     unsigned int __ss;
75     unsigned int __eflags;
76     unsigned int __eip;
77     unsigned int __cs;
78     unsigned int __ds;
79     unsigned int __es;
80     unsigned int __fs;
81     unsigned int __gs;
82   };
83
84   GPRs _registers;
85 };
86
87 inline Registers_x86::Registers_x86(const void *registers) {
88   static_assert(sizeof(Registers_x86) < sizeof(unw_context_t),
89                     "x86 registers do not fit into unw_context_t");
90   _registers = *((GPRs *)registers);
91 }
92
93 inline Registers_x86::Registers_x86() {
94   bzero(&_registers, sizeof(_registers));
95 }
96
97 inline bool Registers_x86::validRegister(int regNum) const {
98   if (regNum == UNW_REG_IP)
99     return true;
100   if (regNum == UNW_REG_SP)
101     return true;
102   if (regNum < 0)
103     return false;
104   if (regNum > 7)
105     return false;
106   return true;
107 }
108
109 inline uint32_t Registers_x86::getRegister(int regNum) const {
110   switch (regNum) {
111   case UNW_REG_IP:
112     return _registers.__eip;
113   case UNW_REG_SP:
114     return _registers.__esp;
115   case UNW_X86_EAX:
116     return _registers.__eax;
117   case UNW_X86_ECX:
118     return _registers.__ecx;
119   case UNW_X86_EDX:
120     return _registers.__edx;
121   case UNW_X86_EBX:
122     return _registers.__ebx;
123   case UNW_X86_EBP:
124     return _registers.__ebp;
125   case UNW_X86_ESP:
126     return _registers.__esp;
127   case UNW_X86_ESI:
128     return _registers.__esi;
129   case UNW_X86_EDI:
130     return _registers.__edi;
131   }
132   _LIBUNWIND_ABORT("unsupported x86 register");
133 }
134
135 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
136   switch (regNum) {
137   case UNW_REG_IP:
138     _registers.__eip = value;
139     return;
140   case UNW_REG_SP:
141     _registers.__esp = value;
142     return;
143   case UNW_X86_EAX:
144     _registers.__eax = value;
145     return;
146   case UNW_X86_ECX:
147     _registers.__ecx = value;
148     return;
149   case UNW_X86_EDX:
150     _registers.__edx = value;
151     return;
152   case UNW_X86_EBX:
153     _registers.__ebx = value;
154     return;
155   case UNW_X86_EBP:
156     _registers.__ebp = value;
157     return;
158   case UNW_X86_ESP:
159     _registers.__esp = value;
160     return;
161   case UNW_X86_ESI:
162     _registers.__esi = value;
163     return;
164   case UNW_X86_EDI:
165     _registers.__edi = value;
166     return;
167   }
168   _LIBUNWIND_ABORT("unsupported x86 register");
169 }
170
171 inline const char *Registers_x86::getRegisterName(int regNum) {
172   switch (regNum) {
173   case UNW_REG_IP:
174     return "ip";
175   case UNW_REG_SP:
176     return "esp";
177   case UNW_X86_EAX:
178     return "eax";
179   case UNW_X86_ECX:
180     return "ecx";
181   case UNW_X86_EDX:
182     return "edx";
183   case UNW_X86_EBX:
184     return "ebx";
185   case UNW_X86_EBP:
186     return "ebp";
187   case UNW_X86_ESP:
188     return "esp";
189   case UNW_X86_ESI:
190     return "esi";
191   case UNW_X86_EDI:
192     return "edi";
193   default:
194     return "unknown register";
195   }
196 }
197
198 inline double Registers_x86::getFloatRegister(int) const {
199   _LIBUNWIND_ABORT("no x86 float registers");
200 }
201
202 inline void Registers_x86::setFloatRegister(int, double) {
203   _LIBUNWIND_ABORT("no x86 float registers");
204 }
205
206 inline v128 Registers_x86::getVectorRegister(int) const {
207   _LIBUNWIND_ABORT("no x86 vector registers");
208 }
209
210 inline void Registers_x86::setVectorRegister(int, v128) {
211   _LIBUNWIND_ABORT("no x86 vector registers");
212 }
213
214
215 /// Registers_x86_64  holds the register state of a thread in a 64-bit intel
216 /// process.
217 class _LIBUNWIND_HIDDEN Registers_x86_64 {
218 public:
219   Registers_x86_64();
220   Registers_x86_64(const void *registers);
221
222   bool        validRegister(int num) const;
223   uint64_t    getRegister(int num) const;
224   void        setRegister(int num, uint64_t value);
225   bool        validFloatRegister(int) const { return false; }
226   double      getFloatRegister(int num) const;
227   void        setFloatRegister(int num, double value);
228   bool        validVectorRegister(int) const { return false; }
229   v128        getVectorRegister(int num) const;
230   void        setVectorRegister(int num, v128 value);
231   const char *getRegisterName(int num);
232   void        jumpto();
233
234   uint64_t  getSP() const          { return _registers.__rsp; }
235   void      setSP(uint64_t value)  { _registers.__rsp = value; }
236   uint64_t  getIP() const          { return _registers.__rip; }
237   void      setIP(uint64_t value)  { _registers.__rip = value; }
238   uint64_t  getRBP() const         { return _registers.__rbp; }
239   void      setRBP(uint64_t value) { _registers.__rbp = value; }
240   uint64_t  getRBX() const         { return _registers.__rbx; }
241   void      setRBX(uint64_t value) { _registers.__rbx = value; }
242   uint64_t  getR12() const         { return _registers.__r12; }
243   void      setR12(uint64_t value) { _registers.__r12 = value; }
244   uint64_t  getR13() const         { return _registers.__r13; }
245   void      setR13(uint64_t value) { _registers.__r13 = value; }
246   uint64_t  getR14() const         { return _registers.__r14; }
247   void      setR14(uint64_t value) { _registers.__r14 = value; }
248   uint64_t  getR15() const         { return _registers.__r15; }
249   void      setR15(uint64_t value) { _registers.__r15 = value; }
250
251 private:
252   struct GPRs {
253     uint64_t __rax;
254     uint64_t __rbx;
255     uint64_t __rcx;
256     uint64_t __rdx;
257     uint64_t __rdi;
258     uint64_t __rsi;
259     uint64_t __rbp;
260     uint64_t __rsp;
261     uint64_t __r8;
262     uint64_t __r9;
263     uint64_t __r10;
264     uint64_t __r11;
265     uint64_t __r12;
266     uint64_t __r13;
267     uint64_t __r14;
268     uint64_t __r15;
269     uint64_t __rip;
270     uint64_t __rflags;
271     uint64_t __cs;
272     uint64_t __fs;
273     uint64_t __gs;
274   };
275   GPRs _registers;
276 };
277
278 inline Registers_x86_64::Registers_x86_64(const void *registers) {
279   static_assert(sizeof(Registers_x86_64) < sizeof(unw_context_t),
280                     "x86_64 registers do not fit into unw_context_t");
281   _registers = *((GPRs *)registers);
282 }
283
284 inline Registers_x86_64::Registers_x86_64() {
285   bzero(&_registers, sizeof(_registers));
286 }
287
288 inline bool Registers_x86_64::validRegister(int regNum) const {
289   if (regNum == UNW_REG_IP)
290     return true;
291   if (regNum == UNW_REG_SP)
292     return true;
293   if (regNum < 0)
294     return false;
295   if (regNum > 15)
296     return false;
297   return true;
298 }
299
300 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
301   switch (regNum) {
302   case UNW_REG_IP:
303     return _registers.__rip;
304   case UNW_REG_SP:
305     return _registers.__rsp;
306   case UNW_X86_64_RAX:
307     return _registers.__rax;
308   case UNW_X86_64_RDX:
309     return _registers.__rdx;
310   case UNW_X86_64_RCX:
311     return _registers.__rcx;
312   case UNW_X86_64_RBX:
313     return _registers.__rbx;
314   case UNW_X86_64_RSI:
315     return _registers.__rsi;
316   case UNW_X86_64_RDI:
317     return _registers.__rdi;
318   case UNW_X86_64_RBP:
319     return _registers.__rbp;
320   case UNW_X86_64_RSP:
321     return _registers.__rsp;
322   case UNW_X86_64_R8:
323     return _registers.__r8;
324   case UNW_X86_64_R9:
325     return _registers.__r9;
326   case UNW_X86_64_R10:
327     return _registers.__r10;
328   case UNW_X86_64_R11:
329     return _registers.__r11;
330   case UNW_X86_64_R12:
331     return _registers.__r12;
332   case UNW_X86_64_R13:
333     return _registers.__r13;
334   case UNW_X86_64_R14:
335     return _registers.__r14;
336   case UNW_X86_64_R15:
337     return _registers.__r15;
338   }
339   _LIBUNWIND_ABORT("unsupported x86_64 register");
340 }
341
342 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
343   switch (regNum) {
344   case UNW_REG_IP:
345     _registers.__rip = value;
346     return;
347   case UNW_REG_SP:
348     _registers.__rsp = value;
349     return;
350   case UNW_X86_64_RAX:
351     _registers.__rax = value;
352     return;
353   case UNW_X86_64_RDX:
354     _registers.__rdx = value;
355     return;
356   case UNW_X86_64_RCX:
357     _registers.__rcx = value;
358     return;
359   case UNW_X86_64_RBX:
360     _registers.__rbx = value;
361     return;
362   case UNW_X86_64_RSI:
363     _registers.__rsi = value;
364     return;
365   case UNW_X86_64_RDI:
366     _registers.__rdi = value;
367     return;
368   case UNW_X86_64_RBP:
369     _registers.__rbp = value;
370     return;
371   case UNW_X86_64_RSP:
372     _registers.__rsp = value;
373     return;
374   case UNW_X86_64_R8:
375     _registers.__r8 = value;
376     return;
377   case UNW_X86_64_R9:
378     _registers.__r9 = value;
379     return;
380   case UNW_X86_64_R10:
381     _registers.__r10 = value;
382     return;
383   case UNW_X86_64_R11:
384     _registers.__r11 = value;
385     return;
386   case UNW_X86_64_R12:
387     _registers.__r12 = value;
388     return;
389   case UNW_X86_64_R13:
390     _registers.__r13 = value;
391     return;
392   case UNW_X86_64_R14:
393     _registers.__r14 = value;
394     return;
395   case UNW_X86_64_R15:
396     _registers.__r15 = value;
397     return;
398   }
399   _LIBUNWIND_ABORT("unsupported x86_64 register");
400 }
401
402 inline const char *Registers_x86_64::getRegisterName(int regNum) {
403   switch (regNum) {
404   case UNW_REG_IP:
405     return "rip";
406   case UNW_REG_SP:
407     return "rsp";
408   case UNW_X86_64_RAX:
409     return "rax";
410   case UNW_X86_64_RDX:
411     return "rdx";
412   case UNW_X86_64_RCX:
413     return "rcx";
414   case UNW_X86_64_RBX:
415     return "rbx";
416   case UNW_X86_64_RSI:
417     return "rsi";
418   case UNW_X86_64_RDI:
419     return "rdi";
420   case UNW_X86_64_RBP:
421     return "rbp";
422   case UNW_X86_64_RSP:
423     return "rsp";
424   case UNW_X86_64_R8:
425     return "r8";
426   case UNW_X86_64_R9:
427     return "r9";
428   case UNW_X86_64_R10:
429     return "r10";
430   case UNW_X86_64_R11:
431     return "r11";
432   case UNW_X86_64_R12:
433     return "r12";
434   case UNW_X86_64_R13:
435     return "r13";
436   case UNW_X86_64_R14:
437     return "r14";
438   case UNW_X86_64_R15:
439     return "r15";
440   default:
441     return "unknown register";
442   }
443 }
444
445 inline double Registers_x86_64::getFloatRegister(int) const {
446   _LIBUNWIND_ABORT("no x86_64 float registers");
447 }
448
449 inline void Registers_x86_64::setFloatRegister(int, double) {
450   _LIBUNWIND_ABORT("no x86_64 float registers");
451 }
452
453 inline v128 Registers_x86_64::getVectorRegister(int) const {
454   _LIBUNWIND_ABORT("no x86_64 vector registers");
455 }
456
457 inline void Registers_x86_64::setVectorRegister(int, v128) {
458   _LIBUNWIND_ABORT("no x86_64 vector registers");
459 }
460
461
462 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
463 /// process.
464 class _LIBUNWIND_HIDDEN Registers_ppc {
465 public:
466   Registers_ppc();
467   Registers_ppc(const void *registers);
468
469   bool        validRegister(int num) const;
470   uint32_t    getRegister(int num) const;
471   void        setRegister(int num, uint32_t value);
472   bool        validFloatRegister(int num) const;
473   double      getFloatRegister(int num) const;
474   void        setFloatRegister(int num, double value);
475   bool        validVectorRegister(int num) const;
476   v128        getVectorRegister(int num) const;
477   void        setVectorRegister(int num, v128 value);
478   const char *getRegisterName(int num);
479   void        jumpto();
480
481   uint64_t  getSP() const         { return _registers.__r1; }
482   void      setSP(uint32_t value) { _registers.__r1 = value; }
483   uint64_t  getIP() const         { return _registers.__srr0; }
484   void      setIP(uint32_t value) { _registers.__srr0 = value; }
485
486 private:
487   struct ppc_thread_state_t {
488     unsigned int __srr0; /* Instruction address register (PC) */
489     unsigned int __srr1; /* Machine state register (supervisor) */
490     unsigned int __r0;
491     unsigned int __r1;
492     unsigned int __r2;
493     unsigned int __r3;
494     unsigned int __r4;
495     unsigned int __r5;
496     unsigned int __r6;
497     unsigned int __r7;
498     unsigned int __r8;
499     unsigned int __r9;
500     unsigned int __r10;
501     unsigned int __r11;
502     unsigned int __r12;
503     unsigned int __r13;
504     unsigned int __r14;
505     unsigned int __r15;
506     unsigned int __r16;
507     unsigned int __r17;
508     unsigned int __r18;
509     unsigned int __r19;
510     unsigned int __r20;
511     unsigned int __r21;
512     unsigned int __r22;
513     unsigned int __r23;
514     unsigned int __r24;
515     unsigned int __r25;
516     unsigned int __r26;
517     unsigned int __r27;
518     unsigned int __r28;
519     unsigned int __r29;
520     unsigned int __r30;
521     unsigned int __r31;
522     unsigned int __cr;     /* Condition register */
523     unsigned int __xer;    /* User's integer exception register */
524     unsigned int __lr;     /* Link register */
525     unsigned int __ctr;    /* Count register */
526     unsigned int __mq;     /* MQ register (601 only) */
527     unsigned int __vrsave; /* Vector Save Register */
528   };
529
530   struct ppc_float_state_t {
531     double __fpregs[32];
532
533     unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
534     unsigned int __fpscr;     /* floating point status register */
535   };
536
537   ppc_thread_state_t _registers;
538   ppc_float_state_t  _floatRegisters;
539   v128               _vectorRegisters[32]; // offset 424
540 };
541
542 inline Registers_ppc::Registers_ppc(const void *registers) {
543   static_assert(sizeof(Registers_ppc) < sizeof(unw_context_t),
544                     "ppc registers do not fit into unw_context_t");
545   _registers = *((ppc_thread_state_t *)registers);
546   _floatRegisters = *((ppc_float_state_t *)((char *)registers + 160));
547   memcpy(_vectorRegisters, ((char *)registers + 424), sizeof(_vectorRegisters));
548 }
549
550 inline Registers_ppc::Registers_ppc() {
551   bzero(&_registers, sizeof(_registers));
552   bzero(&_floatRegisters, sizeof(_floatRegisters));
553   bzero(&_vectorRegisters, sizeof(_vectorRegisters));
554 }
555
556 inline bool Registers_ppc::validRegister(int regNum) const {
557   if (regNum == UNW_REG_IP)
558     return true;
559   if (regNum == UNW_REG_SP)
560     return true;
561   if (regNum == UNW_PPC_VRSAVE)
562     return true;
563   if (regNum < 0)
564     return false;
565   if (regNum <= UNW_PPC_R31)
566     return true;
567   if (regNum == UNW_PPC_MQ)
568     return true;
569   if (regNum == UNW_PPC_LR)
570     return true;
571   if (regNum == UNW_PPC_CTR)
572     return true;
573   if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
574     return true;
575   return false;
576 }
577
578 inline uint32_t Registers_ppc::getRegister(int regNum) const {
579   switch (regNum) {
580   case UNW_REG_IP:
581     return _registers.__srr0;
582   case UNW_REG_SP:
583     return _registers.__r1;
584   case UNW_PPC_R0:
585     return _registers.__r0;
586   case UNW_PPC_R1:
587     return _registers.__r1;
588   case UNW_PPC_R2:
589     return _registers.__r2;
590   case UNW_PPC_R3:
591     return _registers.__r3;
592   case UNW_PPC_R4:
593     return _registers.__r4;
594   case UNW_PPC_R5:
595     return _registers.__r5;
596   case UNW_PPC_R6:
597     return _registers.__r6;
598   case UNW_PPC_R7:
599     return _registers.__r7;
600   case UNW_PPC_R8:
601     return _registers.__r8;
602   case UNW_PPC_R9:
603     return _registers.__r9;
604   case UNW_PPC_R10:
605     return _registers.__r10;
606   case UNW_PPC_R11:
607     return _registers.__r11;
608   case UNW_PPC_R12:
609     return _registers.__r12;
610   case UNW_PPC_R13:
611     return _registers.__r13;
612   case UNW_PPC_R14:
613     return _registers.__r14;
614   case UNW_PPC_R15:
615     return _registers.__r15;
616   case UNW_PPC_R16:
617     return _registers.__r16;
618   case UNW_PPC_R17:
619     return _registers.__r17;
620   case UNW_PPC_R18:
621     return _registers.__r18;
622   case UNW_PPC_R19:
623     return _registers.__r19;
624   case UNW_PPC_R20:
625     return _registers.__r20;
626   case UNW_PPC_R21:
627     return _registers.__r21;
628   case UNW_PPC_R22:
629     return _registers.__r22;
630   case UNW_PPC_R23:
631     return _registers.__r23;
632   case UNW_PPC_R24:
633     return _registers.__r24;
634   case UNW_PPC_R25:
635     return _registers.__r25;
636   case UNW_PPC_R26:
637     return _registers.__r26;
638   case UNW_PPC_R27:
639     return _registers.__r27;
640   case UNW_PPC_R28:
641     return _registers.__r28;
642   case UNW_PPC_R29:
643     return _registers.__r29;
644   case UNW_PPC_R30:
645     return _registers.__r30;
646   case UNW_PPC_R31:
647     return _registers.__r31;
648   case UNW_PPC_LR:
649     return _registers.__lr;
650   case UNW_PPC_CR0:
651     return (_registers.__cr & 0xF0000000);
652   case UNW_PPC_CR1:
653     return (_registers.__cr & 0x0F000000);
654   case UNW_PPC_CR2:
655     return (_registers.__cr & 0x00F00000);
656   case UNW_PPC_CR3:
657     return (_registers.__cr & 0x000F0000);
658   case UNW_PPC_CR4:
659     return (_registers.__cr & 0x0000F000);
660   case UNW_PPC_CR5:
661     return (_registers.__cr & 0x00000F00);
662   case UNW_PPC_CR6:
663     return (_registers.__cr & 0x000000F0);
664   case UNW_PPC_CR7:
665     return (_registers.__cr & 0x0000000F);
666   case UNW_PPC_VRSAVE:
667     return _registers.__vrsave;
668   }
669   _LIBUNWIND_ABORT("unsupported ppc register");
670 }
671
672 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
673   //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
674   switch (regNum) {
675   case UNW_REG_IP:
676     _registers.__srr0 = value;
677     return;
678   case UNW_REG_SP:
679     _registers.__r1 = value;
680     return;
681   case UNW_PPC_R0:
682     _registers.__r0 = value;
683     return;
684   case UNW_PPC_R1:
685     _registers.__r1 = value;
686     return;
687   case UNW_PPC_R2:
688     _registers.__r2 = value;
689     return;
690   case UNW_PPC_R3:
691     _registers.__r3 = value;
692     return;
693   case UNW_PPC_R4:
694     _registers.__r4 = value;
695     return;
696   case UNW_PPC_R5:
697     _registers.__r5 = value;
698     return;
699   case UNW_PPC_R6:
700     _registers.__r6 = value;
701     return;
702   case UNW_PPC_R7:
703     _registers.__r7 = value;
704     return;
705   case UNW_PPC_R8:
706     _registers.__r8 = value;
707     return;
708   case UNW_PPC_R9:
709     _registers.__r9 = value;
710     return;
711   case UNW_PPC_R10:
712     _registers.__r10 = value;
713     return;
714   case UNW_PPC_R11:
715     _registers.__r11 = value;
716     return;
717   case UNW_PPC_R12:
718     _registers.__r12 = value;
719     return;
720   case UNW_PPC_R13:
721     _registers.__r13 = value;
722     return;
723   case UNW_PPC_R14:
724     _registers.__r14 = value;
725     return;
726   case UNW_PPC_R15:
727     _registers.__r15 = value;
728     return;
729   case UNW_PPC_R16:
730     _registers.__r16 = value;
731     return;
732   case UNW_PPC_R17:
733     _registers.__r17 = value;
734     return;
735   case UNW_PPC_R18:
736     _registers.__r18 = value;
737     return;
738   case UNW_PPC_R19:
739     _registers.__r19 = value;
740     return;
741   case UNW_PPC_R20:
742     _registers.__r20 = value;
743     return;
744   case UNW_PPC_R21:
745     _registers.__r21 = value;
746     return;
747   case UNW_PPC_R22:
748     _registers.__r22 = value;
749     return;
750   case UNW_PPC_R23:
751     _registers.__r23 = value;
752     return;
753   case UNW_PPC_R24:
754     _registers.__r24 = value;
755     return;
756   case UNW_PPC_R25:
757     _registers.__r25 = value;
758     return;
759   case UNW_PPC_R26:
760     _registers.__r26 = value;
761     return;
762   case UNW_PPC_R27:
763     _registers.__r27 = value;
764     return;
765   case UNW_PPC_R28:
766     _registers.__r28 = value;
767     return;
768   case UNW_PPC_R29:
769     _registers.__r29 = value;
770     return;
771   case UNW_PPC_R30:
772     _registers.__r30 = value;
773     return;
774   case UNW_PPC_R31:
775     _registers.__r31 = value;
776     return;
777   case UNW_PPC_MQ:
778     _registers.__mq = value;
779     return;
780   case UNW_PPC_LR:
781     _registers.__lr = value;
782     return;
783   case UNW_PPC_CTR:
784     _registers.__ctr = value;
785     return;
786   case UNW_PPC_CR0:
787     _registers.__cr &= 0x0FFFFFFF;
788     _registers.__cr |= (value & 0xF0000000);
789     return;
790   case UNW_PPC_CR1:
791     _registers.__cr &= 0xF0FFFFFF;
792     _registers.__cr |= (value & 0x0F000000);
793     return;
794   case UNW_PPC_CR2:
795     _registers.__cr &= 0xFF0FFFFF;
796     _registers.__cr |= (value & 0x00F00000);
797     return;
798   case UNW_PPC_CR3:
799     _registers.__cr &= 0xFFF0FFFF;
800     _registers.__cr |= (value & 0x000F0000);
801     return;
802   case UNW_PPC_CR4:
803     _registers.__cr &= 0xFFFF0FFF;
804     _registers.__cr |= (value & 0x0000F000);
805     return;
806   case UNW_PPC_CR5:
807     _registers.__cr &= 0xFFFFF0FF;
808     _registers.__cr |= (value & 0x00000F00);
809     return;
810   case UNW_PPC_CR6:
811     _registers.__cr &= 0xFFFFFF0F;
812     _registers.__cr |= (value & 0x000000F0);
813     return;
814   case UNW_PPC_CR7:
815     _registers.__cr &= 0xFFFFFFF0;
816     _registers.__cr |= (value & 0x0000000F);
817     return;
818   case UNW_PPC_VRSAVE:
819     _registers.__vrsave = value;
820     return;
821     // not saved
822     return;
823   case UNW_PPC_XER:
824     _registers.__xer = value;
825     return;
826   case UNW_PPC_AP:
827   case UNW_PPC_VSCR:
828   case UNW_PPC_SPEFSCR:
829     // not saved
830     return;
831   }
832   _LIBUNWIND_ABORT("unsupported ppc register");
833 }
834
835 inline bool Registers_ppc::validFloatRegister(int regNum) const {
836   if (regNum < UNW_PPC_F0)
837     return false;
838   if (regNum > UNW_PPC_F31)
839     return false;
840   return true;
841 }
842
843 inline double Registers_ppc::getFloatRegister(int regNum) const {
844   assert(validFloatRegister(regNum));
845   return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
846 }
847
848 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
849   assert(validFloatRegister(regNum));
850   _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
851 }
852
853 inline bool Registers_ppc::validVectorRegister(int regNum) const {
854   if (regNum < UNW_PPC_V0)
855     return false;
856   if (regNum > UNW_PPC_V31)
857     return false;
858   return true;
859 }
860
861 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
862   assert(validVectorRegister(regNum));
863   v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
864   return result;
865 }
866
867 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
868   assert(validVectorRegister(regNum));
869   _vectorRegisters[regNum - UNW_PPC_V0] = value;
870 }
871
872 inline const char *Registers_ppc::getRegisterName(int regNum) {
873   switch (regNum) {
874   case UNW_REG_IP:
875     return "ip";
876   case UNW_REG_SP:
877     return "sp";
878   case UNW_PPC_R0:
879     return "r0";
880   case UNW_PPC_R1:
881     return "r1";
882   case UNW_PPC_R2:
883     return "r2";
884   case UNW_PPC_R3:
885     return "r3";
886   case UNW_PPC_R4:
887     return "r4";
888   case UNW_PPC_R5:
889     return "r5";
890   case UNW_PPC_R6:
891     return "r6";
892   case UNW_PPC_R7:
893     return "r7";
894   case UNW_PPC_R8:
895     return "r8";
896   case UNW_PPC_R9:
897     return "r9";
898   case UNW_PPC_R10:
899     return "r10";
900   case UNW_PPC_R11:
901     return "r11";
902   case UNW_PPC_R12:
903     return "r12";
904   case UNW_PPC_R13:
905     return "r13";
906   case UNW_PPC_R14:
907     return "r14";
908   case UNW_PPC_R15:
909     return "r15";
910   case UNW_PPC_R16:
911     return "r16";
912   case UNW_PPC_R17:
913     return "r17";
914   case UNW_PPC_R18:
915     return "r18";
916   case UNW_PPC_R19:
917     return "r19";
918   case UNW_PPC_R20:
919     return "r20";
920   case UNW_PPC_R21:
921     return "r21";
922   case UNW_PPC_R22:
923     return "r22";
924   case UNW_PPC_R23:
925     return "r23";
926   case UNW_PPC_R24:
927     return "r24";
928   case UNW_PPC_R25:
929     return "r25";
930   case UNW_PPC_R26:
931     return "r26";
932   case UNW_PPC_R27:
933     return "r27";
934   case UNW_PPC_R28:
935     return "r28";
936   case UNW_PPC_R29:
937     return "r29";
938   case UNW_PPC_R30:
939     return "r30";
940   case UNW_PPC_R31:
941     return "r31";
942   case UNW_PPC_F0:
943     return "fp0";
944   case UNW_PPC_F1:
945     return "fp1";
946   case UNW_PPC_F2:
947     return "fp2";
948   case UNW_PPC_F3:
949     return "fp3";
950   case UNW_PPC_F4:
951     return "fp4";
952   case UNW_PPC_F5:
953     return "fp5";
954   case UNW_PPC_F6:
955     return "fp6";
956   case UNW_PPC_F7:
957     return "fp7";
958   case UNW_PPC_F8:
959     return "fp8";
960   case UNW_PPC_F9:
961     return "fp9";
962   case UNW_PPC_F10:
963     return "fp10";
964   case UNW_PPC_F11:
965     return "fp11";
966   case UNW_PPC_F12:
967     return "fp12";
968   case UNW_PPC_F13:
969     return "fp13";
970   case UNW_PPC_F14:
971     return "fp14";
972   case UNW_PPC_F15:
973     return "fp15";
974   case UNW_PPC_F16:
975     return "fp16";
976   case UNW_PPC_F17:
977     return "fp17";
978   case UNW_PPC_F18:
979     return "fp18";
980   case UNW_PPC_F19:
981     return "fp19";
982   case UNW_PPC_F20:
983     return "fp20";
984   case UNW_PPC_F21:
985     return "fp21";
986   case UNW_PPC_F22:
987     return "fp22";
988   case UNW_PPC_F23:
989     return "fp23";
990   case UNW_PPC_F24:
991     return "fp24";
992   case UNW_PPC_F25:
993     return "fp25";
994   case UNW_PPC_F26:
995     return "fp26";
996   case UNW_PPC_F27:
997     return "fp27";
998   case UNW_PPC_F28:
999     return "fp28";
1000   case UNW_PPC_F29:
1001     return "fp29";
1002   case UNW_PPC_F30:
1003     return "fp30";
1004   case UNW_PPC_F31:
1005     return "fp31";
1006   case UNW_PPC_LR:
1007     return "lr";
1008   default:
1009     return "unknown register";
1010   }
1011
1012 }
1013
1014
1015 /// Registers_arm64  holds the register state of a thread in a 64-bit arm
1016 /// process.
1017 class _LIBUNWIND_HIDDEN Registers_arm64 {
1018 public:
1019   Registers_arm64();
1020   Registers_arm64(const void *registers);
1021
1022   bool        validRegister(int num) const;
1023   uint64_t    getRegister(int num) const;
1024   void        setRegister(int num, uint64_t value);
1025   bool        validFloatRegister(int num) const;
1026   double      getFloatRegister(int num) const;
1027   void        setFloatRegister(int num, double value);
1028   bool        validVectorRegister(int num) const;
1029   v128        getVectorRegister(int num) const;
1030   void        setVectorRegister(int num, v128 value);
1031   const char *getRegisterName(int num);
1032   void        jumpto();
1033
1034   uint64_t  getSP() const         { return _registers.__sp; }
1035   void      setSP(uint64_t value) { _registers.__sp = value; }
1036   uint64_t  getIP() const         { return _registers.__pc; }
1037   void      setIP(uint64_t value) { _registers.__pc = value; }
1038   uint64_t  getFP() const         { return _registers.__fp; }
1039   void      setFP(uint64_t value) { _registers.__fp = value; }
1040
1041 private:
1042   struct GPRs {
1043     uint64_t __x[29]; // x0-x28
1044     uint64_t __fp;    // Frame pointer x29
1045     uint64_t __lr;    // Link register x30
1046     uint64_t __sp;    // Stack pointer x31
1047     uint64_t __pc;    // Program counter
1048     uint64_t padding; // 16-byte align
1049   };
1050
1051   GPRs    _registers;
1052   double  _vectorHalfRegisters[32];
1053   // Currently only the lower double in 128-bit vectore registers
1054   // is perserved during unwinding.  We could define new register
1055   // numbers (> 96) which mean whole vector registers, then this
1056   // struct would need to change to contain whole vector registers.
1057 };
1058
1059 inline Registers_arm64::Registers_arm64(const void *registers) {
1060   static_assert(sizeof(Registers_arm64) < sizeof(unw_context_t),
1061                     "arm64 registers do not fit into unw_context_t");
1062   memcpy(&_registers, registers, sizeof(_registers));
1063   memcpy(_vectorHalfRegisters, (((char *)registers) + 0x110),
1064          sizeof(_vectorHalfRegisters));
1065 }
1066
1067 inline Registers_arm64::Registers_arm64() {
1068   bzero(&_registers, sizeof(_registers));
1069   bzero(&_vectorHalfRegisters, sizeof(_vectorHalfRegisters));
1070 }
1071
1072 inline bool Registers_arm64::validRegister(int regNum) const {
1073   if (regNum == UNW_REG_IP)
1074     return true;
1075   if (regNum == UNW_REG_SP)
1076     return true;
1077   if (regNum < 0)
1078     return false;
1079   if (regNum > 95)
1080     return false;
1081   if ((regNum > 31) && (regNum < 64))
1082     return false;
1083   return true;
1084 }
1085
1086 inline uint64_t Registers_arm64::getRegister(int regNum) const {
1087   if (regNum == UNW_REG_IP)
1088     return _registers.__pc;
1089   if (regNum == UNW_REG_SP)
1090     return _registers.__sp;
1091   if ((regNum >= 0) && (regNum < 32))
1092     return _registers.__x[regNum];
1093   _LIBUNWIND_ABORT("unsupported arm64 register");
1094 }
1095
1096 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1097   if (regNum == UNW_REG_IP)
1098     _registers.__pc = value;
1099   else if (regNum == UNW_REG_SP)
1100     _registers.__sp = value;
1101   else if ((regNum >= 0) && (regNum < 32))
1102     _registers.__x[regNum] = value;
1103   else
1104     _LIBUNWIND_ABORT("unsupported arm64 register");
1105 }
1106
1107 inline const char *Registers_arm64::getRegisterName(int regNum) {
1108   switch (regNum) {
1109   case UNW_REG_IP:
1110     return "pc";
1111   case UNW_REG_SP:
1112     return "sp";
1113   case UNW_ARM64_X0:
1114     return "x0";
1115   case UNW_ARM64_X1:
1116     return "x1";
1117   case UNW_ARM64_X2:
1118     return "x2";
1119   case UNW_ARM64_X3:
1120     return "x3";
1121   case UNW_ARM64_X4:
1122     return "x4";
1123   case UNW_ARM64_X5:
1124     return "x5";
1125   case UNW_ARM64_X6:
1126     return "x6";
1127   case UNW_ARM64_X7:
1128     return "x7";
1129   case UNW_ARM64_X8:
1130     return "x8";
1131   case UNW_ARM64_X9:
1132     return "x9";
1133   case UNW_ARM64_X10:
1134     return "x10";
1135   case UNW_ARM64_X11:
1136     return "x11";
1137   case UNW_ARM64_X12:
1138     return "x12";
1139   case UNW_ARM64_X13:
1140     return "x13";
1141   case UNW_ARM64_X14:
1142     return "x14";
1143   case UNW_ARM64_X15:
1144     return "x15";
1145   case UNW_ARM64_X16:
1146     return "x16";
1147   case UNW_ARM64_X17:
1148     return "x17";
1149   case UNW_ARM64_X18:
1150     return "x18";
1151   case UNW_ARM64_X19:
1152     return "x19";
1153   case UNW_ARM64_X20:
1154     return "x20";
1155   case UNW_ARM64_X21:
1156     return "x21";
1157   case UNW_ARM64_X22:
1158     return "x22";
1159   case UNW_ARM64_X23:
1160     return "x23";
1161   case UNW_ARM64_X24:
1162     return "x24";
1163   case UNW_ARM64_X25:
1164     return "x25";
1165   case UNW_ARM64_X26:
1166     return "x26";
1167   case UNW_ARM64_X27:
1168     return "x27";
1169   case UNW_ARM64_X28:
1170     return "x28";
1171   case UNW_ARM64_X29:
1172     return "fp";
1173   case UNW_ARM64_X30:
1174     return "lr";
1175   case UNW_ARM64_X31:
1176     return "sp";
1177   case UNW_ARM64_D0:
1178     return "d0";
1179   case UNW_ARM64_D1:
1180     return "d1";
1181   case UNW_ARM64_D2:
1182     return "d2";
1183   case UNW_ARM64_D3:
1184     return "d3";
1185   case UNW_ARM64_D4:
1186     return "d4";
1187   case UNW_ARM64_D5:
1188     return "d5";
1189   case UNW_ARM64_D6:
1190     return "d6";
1191   case UNW_ARM64_D7:
1192     return "d7";
1193   case UNW_ARM64_D8:
1194     return "d8";
1195   case UNW_ARM64_D9:
1196     return "d9";
1197   case UNW_ARM64_D10:
1198     return "d10";
1199   case UNW_ARM64_D11:
1200     return "d11";
1201   case UNW_ARM64_D12:
1202     return "d12";
1203   case UNW_ARM64_D13:
1204     return "d13";
1205   case UNW_ARM64_D14:
1206     return "d14";
1207   case UNW_ARM64_D15:
1208     return "d15";
1209   case UNW_ARM64_D16:
1210     return "d16";
1211   case UNW_ARM64_D17:
1212     return "d17";
1213   case UNW_ARM64_D18:
1214     return "d18";
1215   case UNW_ARM64_D19:
1216     return "d19";
1217   case UNW_ARM64_D20:
1218     return "d20";
1219   case UNW_ARM64_D21:
1220     return "d21";
1221   case UNW_ARM64_D22:
1222     return "d22";
1223   case UNW_ARM64_D23:
1224     return "d23";
1225   case UNW_ARM64_D24:
1226     return "d24";
1227   case UNW_ARM64_D25:
1228     return "d25";
1229   case UNW_ARM64_D26:
1230     return "d26";
1231   case UNW_ARM64_D27:
1232     return "d27";
1233   case UNW_ARM64_D28:
1234     return "d28";
1235   case UNW_ARM64_D29:
1236     return "d29";
1237   case UNW_ARM64_D30:
1238     return "d30";
1239   case UNW_ARM64_D31:
1240     return "d31";
1241   default:
1242     return "unknown register";
1243   }
1244 }
1245
1246 inline bool Registers_arm64::validFloatRegister(int regNum) const {
1247   if (regNum < UNW_ARM64_D0)
1248     return false;
1249   if (regNum > UNW_ARM64_D31)
1250     return false;
1251   return true;
1252 }
1253
1254 inline double Registers_arm64::getFloatRegister(int regNum) const {
1255   assert(validFloatRegister(regNum));
1256   return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
1257 }
1258
1259 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
1260   assert(validFloatRegister(regNum));
1261   _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
1262 }
1263
1264 inline bool Registers_arm64::validVectorRegister(int) const {
1265   return false;
1266 }
1267
1268 inline v128 Registers_arm64::getVectorRegister(int) const {
1269   _LIBUNWIND_ABORT("no arm64 vector register support yet");
1270 }
1271
1272 inline void Registers_arm64::setVectorRegister(int, v128) {
1273   _LIBUNWIND_ABORT("no arm64 vector register support yet");
1274 }
1275
1276 /// Registers_arm holds the register state of a thread in a 32-bit arm
1277 /// process.
1278 ///
1279 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
1280 /// this uses more memory than required.
1281 ///
1282 /// FIXME: Support MMX Data Registers, Control registers, and load/stores
1283 /// for different representations in the VFP registers as listed in
1284 /// Table 1 of EHABI #7.5.2
1285 class _LIBUNWIND_HIDDEN Registers_arm {
1286 public:
1287   Registers_arm();
1288   Registers_arm(const void *registers);
1289
1290   bool        validRegister(int num) const;
1291   uint32_t    getRegister(int num) const;
1292   void        setRegister(int num, uint32_t value);
1293   // FIXME: Due to ARM VRS's support for reading/writing different
1294   // representations into the VFP registers this set of accessors seem wrong.
1295   // If {get,set}FloatRegister() is the backing store for
1296   // _Unwind_VRS_{Get,Set} then it might be best to return a tagged union
1297   // with types for each representation in _Unwind_VRS_DataRepresentation.
1298   // Similarly, unw_{get,set}_fpreg in the public libunwind API may want to
1299   // use a similar tagged union to back the unw_fpreg_t output parameter type.
1300   bool        validFloatRegister(int num) const;
1301   unw_fpreg_t getFloatRegister(int num) const;
1302   void        setFloatRegister(int num, unw_fpreg_t value);
1303   bool        validVectorRegister(int num) const;
1304   v128        getVectorRegister(int num) const;
1305   void        setVectorRegister(int num, v128 value);
1306   const char *getRegisterName(int num);
1307   void        jumpto();
1308
1309   uint32_t  getSP() const         { return _registers.__sp; }
1310   void      setSP(uint32_t value) { _registers.__sp = value; }
1311   uint32_t  getIP() const         { return _registers.__pc; }
1312   void      setIP(uint32_t value) { _registers.__pc = value; }
1313
1314 private:
1315   struct GPRs {
1316     uint32_t __r[13]; // r0-r12
1317     uint32_t __sp;    // Stack pointer r13
1318     uint32_t __lr;    // Link register r14
1319     uint32_t __pc;    // Program counter r15
1320   };
1321
1322   GPRs    _registers;
1323 };
1324
1325 inline Registers_arm::Registers_arm(const void *registers) {
1326   static_assert(sizeof(Registers_arm) < sizeof(unw_context_t),
1327                     "arm registers do not fit into unw_context_t");
1328   memcpy(&_registers, registers, sizeof(_registers));
1329 }
1330
1331 inline Registers_arm::Registers_arm() {
1332   bzero(&_registers, sizeof(_registers));
1333 }
1334
1335 inline bool Registers_arm::validRegister(int regNum) const {
1336   // Returns true for all non-VFP registers supported by the EHABI
1337   // virtual register set (VRS).
1338   if (regNum == UNW_REG_IP)
1339     return true;
1340   if (regNum == UNW_REG_SP)
1341     return true;
1342   if ((regNum >= UNW_ARM_R0) && (regNum <= UNW_ARM_R15))
1343     return true;
1344   return false;
1345 }
1346
1347 inline uint32_t Registers_arm::getRegister(int regNum) const {
1348   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
1349     return _registers.__sp;
1350   if (regNum == UNW_ARM_LR)
1351     return _registers.__lr;
1352   if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
1353     return _registers.__pc;
1354   if ((regNum >= UNW_ARM_R0) && (regNum <= UNW_ARM_R12))
1355     return _registers.__r[regNum];
1356   _LIBUNWIND_ABORT("unsupported arm register");
1357 }
1358
1359 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
1360   if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
1361     _registers.__sp = value;
1362   else if (regNum == UNW_ARM_LR)
1363     _registers.__lr = value;
1364   else if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
1365     _registers.__pc = value;
1366   else if ((regNum >= UNW_ARM_R0) && (regNum <= UNW_ARM_R12))
1367     _registers.__r[regNum] = value;
1368   else
1369     _LIBUNWIND_ABORT("unsupported arm register");
1370 }
1371
1372 inline const char *Registers_arm::getRegisterName(int regNum) {
1373   switch (regNum) {
1374   case UNW_REG_IP:
1375   case UNW_ARM_IP: // UNW_ARM_R15 is alias
1376     return "pc";
1377   case UNW_ARM_LR: // UNW_ARM_R14 is alias
1378     return "lr";
1379   case UNW_REG_SP:
1380   case UNW_ARM_SP: // UNW_ARM_R13 is alias
1381     return "sp";
1382   case UNW_ARM_R0:
1383     return "r0";
1384   case UNW_ARM_R1:
1385     return "r1";
1386   case UNW_ARM_R2:
1387     return "r2";
1388   case UNW_ARM_R3:
1389     return "r3";
1390   case UNW_ARM_R4:
1391     return "r4";
1392   case UNW_ARM_R5:
1393     return "r5";
1394   case UNW_ARM_R6:
1395     return "r6";
1396   case UNW_ARM_R7:
1397     return "r7";
1398   case UNW_ARM_R8:
1399     return "r8";
1400   case UNW_ARM_R9:
1401     return "r9";
1402   case UNW_ARM_R10:
1403     return "r10";
1404   case UNW_ARM_R11:
1405     return "r11";
1406   case UNW_ARM_R12:
1407     return "r12";
1408   case UNW_ARM_S0:
1409     return "s0";
1410   case UNW_ARM_S1:
1411     return "s1";
1412   case UNW_ARM_S2:
1413     return "s2";
1414   case UNW_ARM_S3:
1415     return "s3";
1416   case UNW_ARM_S4:
1417     return "s4";
1418   case UNW_ARM_S5:
1419     return "s5";
1420   case UNW_ARM_S6:
1421     return "s6";
1422   case UNW_ARM_S7:
1423     return "s7";
1424   case UNW_ARM_S8:
1425     return "s8";
1426   case UNW_ARM_S9:
1427     return "s9";
1428   case UNW_ARM_S10:
1429     return "s10";
1430   case UNW_ARM_S11:
1431     return "s11";
1432   case UNW_ARM_S12:
1433     return "s12";
1434   case UNW_ARM_S13:
1435     return "s13";
1436   case UNW_ARM_S14:
1437     return "s14";
1438   case UNW_ARM_S15:
1439     return "s15";
1440   case UNW_ARM_S16:
1441     return "s16";
1442   case UNW_ARM_S17:
1443     return "s17";
1444   case UNW_ARM_S18:
1445     return "s18";
1446   case UNW_ARM_S19:
1447     return "s19";
1448   case UNW_ARM_S20:
1449     return "s20";
1450   case UNW_ARM_S21:
1451     return "s21";
1452   case UNW_ARM_S22:
1453     return "s22";
1454   case UNW_ARM_S23:
1455     return "s23";
1456   case UNW_ARM_S24:
1457     return "s24";
1458   case UNW_ARM_S25:
1459     return "s25";
1460   case UNW_ARM_S26:
1461     return "s26";
1462   case UNW_ARM_S27:
1463     return "s27";
1464   case UNW_ARM_S28:
1465     return "s28";
1466   case UNW_ARM_S29:
1467     return "s29";
1468   case UNW_ARM_S30:
1469     return "s30";
1470   case UNW_ARM_S31:
1471     return "s31";
1472   case UNW_ARM_D0:
1473     return "d0";
1474   case UNW_ARM_D1:
1475     return "d1";
1476   case UNW_ARM_D2:
1477     return "d2";
1478   case UNW_ARM_D3:
1479     return "d3";
1480   case UNW_ARM_D4:
1481     return "d4";
1482   case UNW_ARM_D5:
1483     return "d5";
1484   case UNW_ARM_D6:
1485     return "d6";
1486   case UNW_ARM_D7:
1487     return "d7";
1488   case UNW_ARM_D8:
1489     return "d8";
1490   case UNW_ARM_D9:
1491     return "d9";
1492   case UNW_ARM_D10:
1493     return "d10";
1494   case UNW_ARM_D11:
1495     return "d11";
1496   case UNW_ARM_D12:
1497     return "d12";
1498   case UNW_ARM_D13:
1499     return "d13";
1500   case UNW_ARM_D14:
1501     return "d14";
1502   case UNW_ARM_D15:
1503     return "d15";
1504   case UNW_ARM_D16:
1505     return "d16";
1506   case UNW_ARM_D17:
1507     return "d17";
1508   case UNW_ARM_D18:
1509     return "d18";
1510   case UNW_ARM_D19:
1511     return "d19";
1512   case UNW_ARM_D20:
1513     return "d20";
1514   case UNW_ARM_D21:
1515     return "d21";
1516   case UNW_ARM_D22:
1517     return "d22";
1518   case UNW_ARM_D23:
1519     return "d23";
1520   case UNW_ARM_D24:
1521     return "d24";
1522   case UNW_ARM_D25:
1523     return "d25";
1524   case UNW_ARM_D26:
1525     return "d26";
1526   case UNW_ARM_D27:
1527     return "d27";
1528   case UNW_ARM_D28:
1529     return "d28";
1530   case UNW_ARM_D29:
1531     return "d29";
1532   case UNW_ARM_D30:
1533     return "d30";
1534   case UNW_ARM_D31:
1535     return "d31";
1536   default:
1537     return "unknown register";
1538   }
1539 }
1540
1541 inline bool Registers_arm::validFloatRegister(int) const {
1542   // FIXME: Implement float register support.
1543   return false;
1544 }
1545
1546 inline unw_fpreg_t Registers_arm::getFloatRegister(int) const {
1547   _LIBUNWIND_ABORT("ARM float register support not yet implemented");
1548 }
1549
1550 inline void Registers_arm::setFloatRegister(int, unw_fpreg_t) {
1551   _LIBUNWIND_ABORT("ARM float register support not yet implemented");
1552 }
1553
1554 inline bool Registers_arm::validVectorRegister(int) const {
1555   return false;
1556 }
1557
1558 inline v128 Registers_arm::getVectorRegister(int) const {
1559   _LIBUNWIND_ABORT("ARM vector support not implemented");
1560 }
1561
1562 inline void Registers_arm::setVectorRegister(int, v128) {
1563   _LIBUNWIND_ABORT("ARM vector support not implemented");
1564 }
1565
1566 } // namespace libunwind
1567
1568 #endif // __REGISTERS_HPP__