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