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  _registers = *((GPRs *)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  _registers = *((GPRs *)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  _registers = *((ppc_thread_state_t *)registers);
550  _floatRegisters = *((ppc_float_state_t *)((char *)registers + 160));
551  memcpy(_vectorRegisters, ((char *)registers + 424), sizeof(_vectorRegisters));
552}
553
554inline Registers_ppc::Registers_ppc() {
555  memset(&_registers, 0, sizeof(_registers));
556  memset(&_floatRegisters, 0, sizeof(_floatRegisters));
557  memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
558}
559
560inline bool Registers_ppc::validRegister(int regNum) const {
561  if (regNum == UNW_REG_IP)
562    return true;
563  if (regNum == UNW_REG_SP)
564    return true;
565  if (regNum == UNW_PPC_VRSAVE)
566    return true;
567  if (regNum < 0)
568    return false;
569  if (regNum <= UNW_PPC_R31)
570    return true;
571  if (regNum == UNW_PPC_MQ)
572    return true;
573  if (regNum == UNW_PPC_LR)
574    return true;
575  if (regNum == UNW_PPC_CTR)
576    return true;
577  if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
578    return true;
579  return false;
580}
581
582inline uint32_t Registers_ppc::getRegister(int regNum) const {
583  switch (regNum) {
584  case UNW_REG_IP:
585    return _registers.__srr0;
586  case UNW_REG_SP:
587    return _registers.__r1;
588  case UNW_PPC_R0:
589    return _registers.__r0;
590  case UNW_PPC_R1:
591    return _registers.__r1;
592  case UNW_PPC_R2:
593    return _registers.__r2;
594  case UNW_PPC_R3:
595    return _registers.__r3;
596  case UNW_PPC_R4:
597    return _registers.__r4;
598  case UNW_PPC_R5:
599    return _registers.__r5;
600  case UNW_PPC_R6:
601    return _registers.__r6;
602  case UNW_PPC_R7:
603    return _registers.__r7;
604  case UNW_PPC_R8:
605    return _registers.__r8;
606  case UNW_PPC_R9:
607    return _registers.__r9;
608  case UNW_PPC_R10:
609    return _registers.__r10;
610  case UNW_PPC_R11:
611    return _registers.__r11;
612  case UNW_PPC_R12:
613    return _registers.__r12;
614  case UNW_PPC_R13:
615    return _registers.__r13;
616  case UNW_PPC_R14:
617    return _registers.__r14;
618  case UNW_PPC_R15:
619    return _registers.__r15;
620  case UNW_PPC_R16:
621    return _registers.__r16;
622  case UNW_PPC_R17:
623    return _registers.__r17;
624  case UNW_PPC_R18:
625    return _registers.__r18;
626  case UNW_PPC_R19:
627    return _registers.__r19;
628  case UNW_PPC_R20:
629    return _registers.__r20;
630  case UNW_PPC_R21:
631    return _registers.__r21;
632  case UNW_PPC_R22:
633    return _registers.__r22;
634  case UNW_PPC_R23:
635    return _registers.__r23;
636  case UNW_PPC_R24:
637    return _registers.__r24;
638  case UNW_PPC_R25:
639    return _registers.__r25;
640  case UNW_PPC_R26:
641    return _registers.__r26;
642  case UNW_PPC_R27:
643    return _registers.__r27;
644  case UNW_PPC_R28:
645    return _registers.__r28;
646  case UNW_PPC_R29:
647    return _registers.__r29;
648  case UNW_PPC_R30:
649    return _registers.__r30;
650  case UNW_PPC_R31:
651    return _registers.__r31;
652  case UNW_PPC_LR:
653    return _registers.__lr;
654  case UNW_PPC_CR0:
655    return (_registers.__cr & 0xF0000000);
656  case UNW_PPC_CR1:
657    return (_registers.__cr & 0x0F000000);
658  case UNW_PPC_CR2:
659    return (_registers.__cr & 0x00F00000);
660  case UNW_PPC_CR3:
661    return (_registers.__cr & 0x000F0000);
662  case UNW_PPC_CR4:
663    return (_registers.__cr & 0x0000F000);
664  case UNW_PPC_CR5:
665    return (_registers.__cr & 0x00000F00);
666  case UNW_PPC_CR6:
667    return (_registers.__cr & 0x000000F0);
668  case UNW_PPC_CR7:
669    return (_registers.__cr & 0x0000000F);
670  case UNW_PPC_VRSAVE:
671    return _registers.__vrsave;
672  }
673  _LIBUNWIND_ABORT("unsupported ppc register");
674}
675
676inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
677  //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
678  switch (regNum) {
679  case UNW_REG_IP:
680    _registers.__srr0 = value;
681    return;
682  case UNW_REG_SP:
683    _registers.__r1 = value;
684    return;
685  case UNW_PPC_R0:
686    _registers.__r0 = value;
687    return;
688  case UNW_PPC_R1:
689    _registers.__r1 = value;
690    return;
691  case UNW_PPC_R2:
692    _registers.__r2 = value;
693    return;
694  case UNW_PPC_R3:
695    _registers.__r3 = value;
696    return;
697  case UNW_PPC_R4:
698    _registers.__r4 = value;
699    return;
700  case UNW_PPC_R5:
701    _registers.__r5 = value;
702    return;
703  case UNW_PPC_R6:
704    _registers.__r6 = value;
705    return;
706  case UNW_PPC_R7:
707    _registers.__r7 = value;
708    return;
709  case UNW_PPC_R8:
710    _registers.__r8 = value;
711    return;
712  case UNW_PPC_R9:
713    _registers.__r9 = value;
714    return;
715  case UNW_PPC_R10:
716    _registers.__r10 = value;
717    return;
718  case UNW_PPC_R11:
719    _registers.__r11 = value;
720    return;
721  case UNW_PPC_R12:
722    _registers.__r12 = value;
723    return;
724  case UNW_PPC_R13:
725    _registers.__r13 = value;
726    return;
727  case UNW_PPC_R14:
728    _registers.__r14 = value;
729    return;
730  case UNW_PPC_R15:
731    _registers.__r15 = value;
732    return;
733  case UNW_PPC_R16:
734    _registers.__r16 = value;
735    return;
736  case UNW_PPC_R17:
737    _registers.__r17 = value;
738    return;
739  case UNW_PPC_R18:
740    _registers.__r18 = value;
741    return;
742  case UNW_PPC_R19:
743    _registers.__r19 = value;
744    return;
745  case UNW_PPC_R20:
746    _registers.__r20 = value;
747    return;
748  case UNW_PPC_R21:
749    _registers.__r21 = value;
750    return;
751  case UNW_PPC_R22:
752    _registers.__r22 = value;
753    return;
754  case UNW_PPC_R23:
755    _registers.__r23 = value;
756    return;
757  case UNW_PPC_R24:
758    _registers.__r24 = value;
759    return;
760  case UNW_PPC_R25:
761    _registers.__r25 = value;
762    return;
763  case UNW_PPC_R26:
764    _registers.__r26 = value;
765    return;
766  case UNW_PPC_R27:
767    _registers.__r27 = value;
768    return;
769  case UNW_PPC_R28:
770    _registers.__r28 = value;
771    return;
772  case UNW_PPC_R29:
773    _registers.__r29 = value;
774    return;
775  case UNW_PPC_R30:
776    _registers.__r30 = value;
777    return;
778  case UNW_PPC_R31:
779    _registers.__r31 = value;
780    return;
781  case UNW_PPC_MQ:
782    _registers.__mq = value;
783    return;
784  case UNW_PPC_LR:
785    _registers.__lr = value;
786    return;
787  case UNW_PPC_CTR:
788    _registers.__ctr = value;
789    return;
790  case UNW_PPC_CR0:
791    _registers.__cr &= 0x0FFFFFFF;
792    _registers.__cr |= (value & 0xF0000000);
793    return;
794  case UNW_PPC_CR1:
795    _registers.__cr &= 0xF0FFFFFF;
796    _registers.__cr |= (value & 0x0F000000);
797    return;
798  case UNW_PPC_CR2:
799    _registers.__cr &= 0xFF0FFFFF;
800    _registers.__cr |= (value & 0x00F00000);
801    return;
802  case UNW_PPC_CR3:
803    _registers.__cr &= 0xFFF0FFFF;
804    _registers.__cr |= (value & 0x000F0000);
805    return;
806  case UNW_PPC_CR4:
807    _registers.__cr &= 0xFFFF0FFF;
808    _registers.__cr |= (value & 0x0000F000);
809    return;
810  case UNW_PPC_CR5:
811    _registers.__cr &= 0xFFFFF0FF;
812    _registers.__cr |= (value & 0x00000F00);
813    return;
814  case UNW_PPC_CR6:
815    _registers.__cr &= 0xFFFFFF0F;
816    _registers.__cr |= (value & 0x000000F0);
817    return;
818  case UNW_PPC_CR7:
819    _registers.__cr &= 0xFFFFFFF0;
820    _registers.__cr |= (value & 0x0000000F);
821    return;
822  case UNW_PPC_VRSAVE:
823    _registers.__vrsave = value;
824    return;
825    // not saved
826    return;
827  case UNW_PPC_XER:
828    _registers.__xer = value;
829    return;
830  case UNW_PPC_AP:
831  case UNW_PPC_VSCR:
832  case UNW_PPC_SPEFSCR:
833    // not saved
834    return;
835  }
836  _LIBUNWIND_ABORT("unsupported ppc register");
837}
838
839inline bool Registers_ppc::validFloatRegister(int regNum) const {
840  if (regNum < UNW_PPC_F0)
841    return false;
842  if (regNum > UNW_PPC_F31)
843    return false;
844  return true;
845}
846
847inline double Registers_ppc::getFloatRegister(int regNum) const {
848  assert(validFloatRegister(regNum));
849  return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
850}
851
852inline void Registers_ppc::setFloatRegister(int regNum, double value) {
853  assert(validFloatRegister(regNum));
854  _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
855}
856
857inline bool Registers_ppc::validVectorRegister(int regNum) const {
858  if (regNum < UNW_PPC_V0)
859    return false;
860  if (regNum > UNW_PPC_V31)
861    return false;
862  return true;
863}
864
865inline v128 Registers_ppc::getVectorRegister(int regNum) const {
866  assert(validVectorRegister(regNum));
867  v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
868  return result;
869}
870
871inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
872  assert(validVectorRegister(regNum));
873  _vectorRegisters[regNum - UNW_PPC_V0] = value;
874}
875
876inline const char *Registers_ppc::getRegisterName(int regNum) {
877  switch (regNum) {
878  case UNW_REG_IP:
879    return "ip";
880  case UNW_REG_SP:
881    return "sp";
882  case UNW_PPC_R0:
883    return "r0";
884  case UNW_PPC_R1:
885    return "r1";
886  case UNW_PPC_R2:
887    return "r2";
888  case UNW_PPC_R3:
889    return "r3";
890  case UNW_PPC_R4:
891    return "r4";
892  case UNW_PPC_R5:
893    return "r5";
894  case UNW_PPC_R6:
895    return "r6";
896  case UNW_PPC_R7:
897    return "r7";
898  case UNW_PPC_R8:
899    return "r8";
900  case UNW_PPC_R9:
901    return "r9";
902  case UNW_PPC_R10:
903    return "r10";
904  case UNW_PPC_R11:
905    return "r11";
906  case UNW_PPC_R12:
907    return "r12";
908  case UNW_PPC_R13:
909    return "r13";
910  case UNW_PPC_R14:
911    return "r14";
912  case UNW_PPC_R15:
913    return "r15";
914  case UNW_PPC_R16:
915    return "r16";
916  case UNW_PPC_R17:
917    return "r17";
918  case UNW_PPC_R18:
919    return "r18";
920  case UNW_PPC_R19:
921    return "r19";
922  case UNW_PPC_R20:
923    return "r20";
924  case UNW_PPC_R21:
925    return "r21";
926  case UNW_PPC_R22:
927    return "r22";
928  case UNW_PPC_R23:
929    return "r23";
930  case UNW_PPC_R24:
931    return "r24";
932  case UNW_PPC_R25:
933    return "r25";
934  case UNW_PPC_R26:
935    return "r26";
936  case UNW_PPC_R27:
937    return "r27";
938  case UNW_PPC_R28:
939    return "r28";
940  case UNW_PPC_R29:
941    return "r29";
942  case UNW_PPC_R30:
943    return "r30";
944  case UNW_PPC_R31:
945    return "r31";
946  case UNW_PPC_F0:
947    return "fp0";
948  case UNW_PPC_F1:
949    return "fp1";
950  case UNW_PPC_F2:
951    return "fp2";
952  case UNW_PPC_F3:
953    return "fp3";
954  case UNW_PPC_F4:
955    return "fp4";
956  case UNW_PPC_F5:
957    return "fp5";
958  case UNW_PPC_F6:
959    return "fp6";
960  case UNW_PPC_F7:
961    return "fp7";
962  case UNW_PPC_F8:
963    return "fp8";
964  case UNW_PPC_F9:
965    return "fp9";
966  case UNW_PPC_F10:
967    return "fp10";
968  case UNW_PPC_F11:
969    return "fp11";
970  case UNW_PPC_F12:
971    return "fp12";
972  case UNW_PPC_F13:
973    return "fp13";
974  case UNW_PPC_F14:
975    return "fp14";
976  case UNW_PPC_F15:
977    return "fp15";
978  case UNW_PPC_F16:
979    return "fp16";
980  case UNW_PPC_F17:
981    return "fp17";
982  case UNW_PPC_F18:
983    return "fp18";
984  case UNW_PPC_F19:
985    return "fp19";
986  case UNW_PPC_F20:
987    return "fp20";
988  case UNW_PPC_F21:
989    return "fp21";
990  case UNW_PPC_F22:
991    return "fp22";
992  case UNW_PPC_F23:
993    return "fp23";
994  case UNW_PPC_F24:
995    return "fp24";
996  case UNW_PPC_F25:
997    return "fp25";
998  case UNW_PPC_F26:
999    return "fp26";
1000  case UNW_PPC_F27:
1001    return "fp27";
1002  case UNW_PPC_F28:
1003    return "fp28";
1004  case UNW_PPC_F29:
1005    return "fp29";
1006  case UNW_PPC_F30:
1007    return "fp30";
1008  case UNW_PPC_F31:
1009    return "fp31";
1010  case UNW_PPC_LR:
1011    return "lr";
1012  default:
1013    return "unknown register";
1014  }
1015
1016}
1017
1018
1019/// Registers_arm64  holds the register state of a thread in a 64-bit arm
1020/// process.
1021class _LIBUNWIND_HIDDEN Registers_arm64 {
1022public:
1023  Registers_arm64();
1024  Registers_arm64(const void *registers);
1025
1026  bool        validRegister(int num) const;
1027  uint64_t    getRegister(int num) const;
1028  void        setRegister(int num, uint64_t value);
1029  bool        validFloatRegister(int num) const;
1030  double      getFloatRegister(int num) const;
1031  void        setFloatRegister(int num, double value);
1032  bool        validVectorRegister(int num) const;
1033  v128        getVectorRegister(int num) const;
1034  void        setVectorRegister(int num, v128 value);
1035  const char *getRegisterName(int num);
1036  void        jumpto();
1037  static int  lastDwarfRegNum() { return 95; }
1038
1039  uint64_t  getSP() const         { return _registers.__sp; }
1040  void      setSP(uint64_t value) { _registers.__sp = value; }
1041  uint64_t  getIP() const         { return _registers.__pc; }
1042  void      setIP(uint64_t value) { _registers.__pc = value; }
1043  uint64_t  getFP() const         { return _registers.__fp; }
1044  void      setFP(uint64_t value) { _registers.__fp = value; }
1045
1046private:
1047  struct GPRs {
1048    uint64_t __x[29]; // x0-x28
1049    uint64_t __fp;    // Frame pointer x29
1050    uint64_t __lr;    // Link register x30
1051    uint64_t __sp;    // Stack pointer x31
1052    uint64_t __pc;    // Program counter
1053    uint64_t padding; // 16-byte align
1054  };
1055
1056  GPRs    _registers;
1057  double  _vectorHalfRegisters[32];
1058  // Currently only the lower double in 128-bit vectore registers
1059  // is perserved during unwinding.  We could define new register
1060  // numbers (> 96) which mean whole vector registers, then this
1061  // struct would need to change to contain whole vector registers.
1062};
1063
1064inline Registers_arm64::Registers_arm64(const void *registers) {
1065  static_assert(sizeof(Registers_arm64) < sizeof(unw_context_t),
1066                    "arm64 registers do not fit into unw_context_t");
1067  memcpy(&_registers, registers, sizeof(_registers));
1068  memcpy(_vectorHalfRegisters, (((char *)registers) + 0x110),
1069         sizeof(_vectorHalfRegisters));
1070}
1071
1072inline Registers_arm64::Registers_arm64() {
1073  memset(&_registers, 0, sizeof(_registers));
1074  memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1075}
1076
1077inline bool Registers_arm64::validRegister(int regNum) const {
1078  if (regNum == UNW_REG_IP)
1079    return true;
1080  if (regNum == UNW_REG_SP)
1081    return true;
1082  if (regNum < 0)
1083    return false;
1084  if (regNum > 95)
1085    return false;
1086  if ((regNum > 31) && (regNum < 64))
1087    return false;
1088  return true;
1089}
1090
1091inline uint64_t Registers_arm64::getRegister(int regNum) const {
1092  if (regNum == UNW_REG_IP)
1093    return _registers.__pc;
1094  if (regNum == UNW_REG_SP)
1095    return _registers.__sp;
1096  if ((regNum >= 0) && (regNum < 32))
1097    return _registers.__x[regNum];
1098  _LIBUNWIND_ABORT("unsupported arm64 register");
1099}
1100
1101inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1102  if (regNum == UNW_REG_IP)
1103    _registers.__pc = value;
1104  else if (regNum == UNW_REG_SP)
1105    _registers.__sp = value;
1106  else if ((regNum >= 0) && (regNum < 32))
1107    _registers.__x[regNum] = value;
1108  else
1109    _LIBUNWIND_ABORT("unsupported arm64 register");
1110}
1111
1112inline const char *Registers_arm64::getRegisterName(int regNum) {
1113  switch (regNum) {
1114  case UNW_REG_IP:
1115    return "pc";
1116  case UNW_REG_SP:
1117    return "sp";
1118  case UNW_ARM64_X0:
1119    return "x0";
1120  case UNW_ARM64_X1:
1121    return "x1";
1122  case UNW_ARM64_X2:
1123    return "x2";
1124  case UNW_ARM64_X3:
1125    return "x3";
1126  case UNW_ARM64_X4:
1127    return "x4";
1128  case UNW_ARM64_X5:
1129    return "x5";
1130  case UNW_ARM64_X6:
1131    return "x6";
1132  case UNW_ARM64_X7:
1133    return "x7";
1134  case UNW_ARM64_X8:
1135    return "x8";
1136  case UNW_ARM64_X9:
1137    return "x9";
1138  case UNW_ARM64_X10:
1139    return "x10";
1140  case UNW_ARM64_X11:
1141    return "x11";
1142  case UNW_ARM64_X12:
1143    return "x12";
1144  case UNW_ARM64_X13:
1145    return "x13";
1146  case UNW_ARM64_X14:
1147    return "x14";
1148  case UNW_ARM64_X15:
1149    return "x15";
1150  case UNW_ARM64_X16:
1151    return "x16";
1152  case UNW_ARM64_X17:
1153    return "x17";
1154  case UNW_ARM64_X18:
1155    return "x18";
1156  case UNW_ARM64_X19:
1157    return "x19";
1158  case UNW_ARM64_X20:
1159    return "x20";
1160  case UNW_ARM64_X21:
1161    return "x21";
1162  case UNW_ARM64_X22:
1163    return "x22";
1164  case UNW_ARM64_X23:
1165    return "x23";
1166  case UNW_ARM64_X24:
1167    return "x24";
1168  case UNW_ARM64_X25:
1169    return "x25";
1170  case UNW_ARM64_X26:
1171    return "x26";
1172  case UNW_ARM64_X27:
1173    return "x27";
1174  case UNW_ARM64_X28:
1175    return "x28";
1176  case UNW_ARM64_X29:
1177    return "fp";
1178  case UNW_ARM64_X30:
1179    return "lr";
1180  case UNW_ARM64_X31:
1181    return "sp";
1182  case UNW_ARM64_D0:
1183    return "d0";
1184  case UNW_ARM64_D1:
1185    return "d1";
1186  case UNW_ARM64_D2:
1187    return "d2";
1188  case UNW_ARM64_D3:
1189    return "d3";
1190  case UNW_ARM64_D4:
1191    return "d4";
1192  case UNW_ARM64_D5:
1193    return "d5";
1194  case UNW_ARM64_D6:
1195    return "d6";
1196  case UNW_ARM64_D7:
1197    return "d7";
1198  case UNW_ARM64_D8:
1199    return "d8";
1200  case UNW_ARM64_D9:
1201    return "d9";
1202  case UNW_ARM64_D10:
1203    return "d10";
1204  case UNW_ARM64_D11:
1205    return "d11";
1206  case UNW_ARM64_D12:
1207    return "d12";
1208  case UNW_ARM64_D13:
1209    return "d13";
1210  case UNW_ARM64_D14:
1211    return "d14";
1212  case UNW_ARM64_D15:
1213    return "d15";
1214  case UNW_ARM64_D16:
1215    return "d16";
1216  case UNW_ARM64_D17:
1217    return "d17";
1218  case UNW_ARM64_D18:
1219    return "d18";
1220  case UNW_ARM64_D19:
1221    return "d19";
1222  case UNW_ARM64_D20:
1223    return "d20";
1224  case UNW_ARM64_D21:
1225    return "d21";
1226  case UNW_ARM64_D22:
1227    return "d22";
1228  case UNW_ARM64_D23:
1229    return "d23";
1230  case UNW_ARM64_D24:
1231    return "d24";
1232  case UNW_ARM64_D25:
1233    return "d25";
1234  case UNW_ARM64_D26:
1235    return "d26";
1236  case UNW_ARM64_D27:
1237    return "d27";
1238  case UNW_ARM64_D28:
1239    return "d28";
1240  case UNW_ARM64_D29:
1241    return "d29";
1242  case UNW_ARM64_D30:
1243    return "d30";
1244  case UNW_ARM64_D31:
1245    return "d31";
1246  default:
1247    return "unknown register";
1248  }
1249}
1250
1251inline bool Registers_arm64::validFloatRegister(int regNum) const {
1252  if (regNum < UNW_ARM64_D0)
1253    return false;
1254  if (regNum > UNW_ARM64_D31)
1255    return false;
1256  return true;
1257}
1258
1259inline double Registers_arm64::getFloatRegister(int regNum) const {
1260  assert(validFloatRegister(regNum));
1261  return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
1262}
1263
1264inline void Registers_arm64::setFloatRegister(int regNum, double value) {
1265  assert(validFloatRegister(regNum));
1266  _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
1267}
1268
1269inline bool Registers_arm64::validVectorRegister(int) const {
1270  return false;
1271}
1272
1273inline v128 Registers_arm64::getVectorRegister(int) const {
1274  _LIBUNWIND_ABORT("no arm64 vector register support yet");
1275}
1276
1277inline void Registers_arm64::setVectorRegister(int, v128) {
1278  _LIBUNWIND_ABORT("no arm64 vector register support yet");
1279}
1280
1281/// Registers_arm holds the register state of a thread in a 32-bit arm
1282/// process.
1283///
1284/// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
1285/// this uses more memory than required.
1286class _LIBUNWIND_HIDDEN Registers_arm {
1287public:
1288  Registers_arm();
1289  Registers_arm(const void *registers);
1290
1291  bool        validRegister(int num) const;
1292  uint32_t    getRegister(int num);
1293  void        setRegister(int num, uint32_t value);
1294  bool        validFloatRegister(int num) const;
1295  unw_fpreg_t getFloatRegister(int num);
1296  void        setFloatRegister(int num, unw_fpreg_t value);
1297  bool        validVectorRegister(int num) const;
1298  v128        getVectorRegister(int num) const;
1299  void        setVectorRegister(int num, v128 value);
1300  const char *getRegisterName(int num);
1301  void        jumpto() {
1302    restoreSavedFloatRegisters();
1303    restoreCoreAndJumpTo();
1304  }
1305
1306  uint32_t  getSP() const         { return _registers.__sp; }
1307  void      setSP(uint32_t value) { _registers.__sp = value; }
1308  uint32_t  getIP() const         { return _registers.__pc; }
1309  void      setIP(uint32_t value) { _registers.__pc = value; }
1310
1311  void saveVFPAsX() {
1312    assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
1313    _use_X_for_vfp_save = true;
1314  }
1315
1316  void restoreSavedFloatRegisters() {
1317    if (_saved_vfp_d0_d15) {
1318      if (_use_X_for_vfp_save)
1319        restoreVFPWithFLDMX(_vfp_d0_d15_pad);
1320      else
1321        restoreVFPWithFLDMD(_vfp_d0_d15_pad);
1322    }
1323    if (_saved_vfp_d16_d31)
1324      restoreVFPv3(_vfp_d16_d31);
1325    if (_saved_iwmmx)
1326      restoreiWMMX(_iwmmx);
1327    if (_saved_iwmmx_control)
1328      restoreiWMMXControl(_iwmmx_control);
1329  }
1330
1331private:
1332  struct GPRs {
1333    uint32_t __r[13]; // r0-r12
1334    uint32_t __sp;    // Stack pointer r13
1335    uint32_t __lr;    // Link register r14
1336    uint32_t __pc;    // Program counter r15
1337  };
1338
1339  static void saveVFPWithFSTMD(unw_fpreg_t*);
1340  static void saveVFPWithFSTMX(unw_fpreg_t*);
1341  static void saveVFPv3(unw_fpreg_t*);
1342  static void saveiWMMX(unw_fpreg_t*);
1343  static void saveiWMMXControl(uint32_t*);
1344  static void restoreVFPWithFLDMD(unw_fpreg_t*);
1345  static void restoreVFPWithFLDMX(unw_fpreg_t*);
1346  static void restoreVFPv3(unw_fpreg_t*);
1347  static void restoreiWMMX(unw_fpreg_t*);
1348  static void restoreiWMMXControl(uint32_t*);
1349  void restoreCoreAndJumpTo();
1350
1351  // ARM registers
1352  GPRs _registers;
1353
1354  // We save floating point registers lazily because we can't know ahead of
1355  // time which ones are used. See EHABI #4.7.
1356
1357  // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
1358  //
1359  // See EHABI #7.5 that explains how matching instruction sequences for load
1360  // and store need to be used to correctly restore the exact register bits.
1361  bool _use_X_for_vfp_save;
1362  // Whether VFP D0-D15 are saved.
1363  bool _saved_vfp_d0_d15;
1364  // Whether VFPv3 D16-D31 are saved.
1365  bool _saved_vfp_d16_d31;
1366  // Whether iWMMX data registers are saved.
1367  bool _saved_iwmmx;
1368  // Whether iWMMX control registers are saved.
1369  bool _saved_iwmmx_control;
1370  // VFP registers D0-D15, + padding if saved using FSTMX
1371  unw_fpreg_t _vfp_d0_d15_pad[17];
1372  // VFPv3 registers D16-D31, always saved using FSTMD
1373  unw_fpreg_t _vfp_d16_d31[16];
1374  // iWMMX registers
1375  unw_fpreg_t _iwmmx[16];
1376  // iWMMX control registers
1377  uint32_t _iwmmx_control[4];
1378};
1379
1380inline Registers_arm::Registers_arm(const void *registers)
1381  : _use_X_for_vfp_save(false),
1382    _saved_vfp_d0_d15(false),
1383    _saved_vfp_d16_d31(false),
1384    _saved_iwmmx(false),
1385    _saved_iwmmx_control(false) {
1386  static_assert(sizeof(Registers_arm) < sizeof(unw_context_t),
1387                    "arm registers do not fit into unw_context_t");
1388  // See unw_getcontext() note about data.
1389  memcpy(&_registers, registers, sizeof(_registers));
1390  memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
1391  memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
1392  memset(&_iwmmx, 0, sizeof(_iwmmx));
1393  memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
1394}
1395
1396inline Registers_arm::Registers_arm()
1397  : _use_X_for_vfp_save(false),
1398    _saved_vfp_d0_d15(false),
1399    _saved_vfp_d16_d31(false),
1400    _saved_iwmmx(false),
1401    _saved_iwmmx_control(false) {
1402  memset(&_registers, 0, 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 bool Registers_arm::validRegister(int regNum) const {
1410  // Returns true for all non-VFP registers supported by the EHABI
1411  // virtual register set (VRS).
1412  if (regNum == UNW_REG_IP)
1413    return true;
1414  if (regNum == UNW_REG_SP)
1415    return true;
1416  if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
1417    return true;
1418  if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
1419    return true;
1420  return false;
1421}
1422
1423inline uint32_t Registers_arm::getRegister(int regNum) {
1424  if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
1425    return _registers.__sp;
1426  if (regNum == UNW_ARM_LR)
1427    return _registers.__lr;
1428  if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
1429    return _registers.__pc;
1430  if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
1431    return _registers.__r[regNum];
1432  if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
1433    if (!_saved_iwmmx_control) {
1434      _saved_iwmmx_control = true;
1435      saveiWMMXControl(_iwmmx_control);
1436    }
1437    return _iwmmx_control[regNum - UNW_ARM_WC0];
1438  }
1439  _LIBUNWIND_ABORT("unsupported arm register");
1440}
1441
1442inline void Registers_arm::setRegister(int regNum, uint32_t value) {
1443  if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
1444    _registers.__sp = value;
1445  else if (regNum == UNW_ARM_LR)
1446    _registers.__lr = value;
1447  else if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
1448    _registers.__pc = value;
1449  else if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
1450    _registers.__r[regNum] = value;
1451  else if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
1452    if (!_saved_iwmmx_control) {
1453      _saved_iwmmx_control = true;
1454      saveiWMMXControl(_iwmmx_control);
1455    }
1456    _iwmmx_control[regNum - UNW_ARM_WC0] = value;
1457  } else
1458    _LIBUNWIND_ABORT("unsupported arm register");
1459}
1460
1461inline const char *Registers_arm::getRegisterName(int regNum) {
1462  switch (regNum) {
1463  case UNW_REG_IP:
1464  case UNW_ARM_IP: // UNW_ARM_R15 is alias
1465    return "pc";
1466  case UNW_ARM_LR: // UNW_ARM_R14 is alias
1467    return "lr";
1468  case UNW_REG_SP:
1469  case UNW_ARM_SP: // UNW_ARM_R13 is alias
1470    return "sp";
1471  case UNW_ARM_R0:
1472    return "r0";
1473  case UNW_ARM_R1:
1474    return "r1";
1475  case UNW_ARM_R2:
1476    return "r2";
1477  case UNW_ARM_R3:
1478    return "r3";
1479  case UNW_ARM_R4:
1480    return "r4";
1481  case UNW_ARM_R5:
1482    return "r5";
1483  case UNW_ARM_R6:
1484    return "r6";
1485  case UNW_ARM_R7:
1486    return "r7";
1487  case UNW_ARM_R8:
1488    return "r8";
1489  case UNW_ARM_R9:
1490    return "r9";
1491  case UNW_ARM_R10:
1492    return "r10";
1493  case UNW_ARM_R11:
1494    return "r11";
1495  case UNW_ARM_R12:
1496    return "r12";
1497  case UNW_ARM_S0:
1498    return "s0";
1499  case UNW_ARM_S1:
1500    return "s1";
1501  case UNW_ARM_S2:
1502    return "s2";
1503  case UNW_ARM_S3:
1504    return "s3";
1505  case UNW_ARM_S4:
1506    return "s4";
1507  case UNW_ARM_S5:
1508    return "s5";
1509  case UNW_ARM_S6:
1510    return "s6";
1511  case UNW_ARM_S7:
1512    return "s7";
1513  case UNW_ARM_S8:
1514    return "s8";
1515  case UNW_ARM_S9:
1516    return "s9";
1517  case UNW_ARM_S10:
1518    return "s10";
1519  case UNW_ARM_S11:
1520    return "s11";
1521  case UNW_ARM_S12:
1522    return "s12";
1523  case UNW_ARM_S13:
1524    return "s13";
1525  case UNW_ARM_S14:
1526    return "s14";
1527  case UNW_ARM_S15:
1528    return "s15";
1529  case UNW_ARM_S16:
1530    return "s16";
1531  case UNW_ARM_S17:
1532    return "s17";
1533  case UNW_ARM_S18:
1534    return "s18";
1535  case UNW_ARM_S19:
1536    return "s19";
1537  case UNW_ARM_S20:
1538    return "s20";
1539  case UNW_ARM_S21:
1540    return "s21";
1541  case UNW_ARM_S22:
1542    return "s22";
1543  case UNW_ARM_S23:
1544    return "s23";
1545  case UNW_ARM_S24:
1546    return "s24";
1547  case UNW_ARM_S25:
1548    return "s25";
1549  case UNW_ARM_S26:
1550    return "s26";
1551  case UNW_ARM_S27:
1552    return "s27";
1553  case UNW_ARM_S28:
1554    return "s28";
1555  case UNW_ARM_S29:
1556    return "s29";
1557  case UNW_ARM_S30:
1558    return "s30";
1559  case UNW_ARM_S31:
1560    return "s31";
1561  case UNW_ARM_D0:
1562    return "d0";
1563  case UNW_ARM_D1:
1564    return "d1";
1565  case UNW_ARM_D2:
1566    return "d2";
1567  case UNW_ARM_D3:
1568    return "d3";
1569  case UNW_ARM_D4:
1570    return "d4";
1571  case UNW_ARM_D5:
1572    return "d5";
1573  case UNW_ARM_D6:
1574    return "d6";
1575  case UNW_ARM_D7:
1576    return "d7";
1577  case UNW_ARM_D8:
1578    return "d8";
1579  case UNW_ARM_D9:
1580    return "d9";
1581  case UNW_ARM_D10:
1582    return "d10";
1583  case UNW_ARM_D11:
1584    return "d11";
1585  case UNW_ARM_D12:
1586    return "d12";
1587  case UNW_ARM_D13:
1588    return "d13";
1589  case UNW_ARM_D14:
1590    return "d14";
1591  case UNW_ARM_D15:
1592    return "d15";
1593  case UNW_ARM_D16:
1594    return "d16";
1595  case UNW_ARM_D17:
1596    return "d17";
1597  case UNW_ARM_D18:
1598    return "d18";
1599  case UNW_ARM_D19:
1600    return "d19";
1601  case UNW_ARM_D20:
1602    return "d20";
1603  case UNW_ARM_D21:
1604    return "d21";
1605  case UNW_ARM_D22:
1606    return "d22";
1607  case UNW_ARM_D23:
1608    return "d23";
1609  case UNW_ARM_D24:
1610    return "d24";
1611  case UNW_ARM_D25:
1612    return "d25";
1613  case UNW_ARM_D26:
1614    return "d26";
1615  case UNW_ARM_D27:
1616    return "d27";
1617  case UNW_ARM_D28:
1618    return "d28";
1619  case UNW_ARM_D29:
1620    return "d29";
1621  case UNW_ARM_D30:
1622    return "d30";
1623  case UNW_ARM_D31:
1624    return "d31";
1625  default:
1626    return "unknown register";
1627  }
1628}
1629
1630inline bool Registers_arm::validFloatRegister(int regNum) const {
1631  // NOTE: Consider the intel MMX registers floating points so the
1632  // unw_get_fpreg can be used to transmit the 64-bit data back.
1633  return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
1634      || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15));
1635}
1636
1637inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
1638  if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
1639    if (!_saved_vfp_d0_d15) {
1640      _saved_vfp_d0_d15 = true;
1641      if (_use_X_for_vfp_save)
1642        saveVFPWithFSTMX(_vfp_d0_d15_pad);
1643      else
1644        saveVFPWithFSTMD(_vfp_d0_d15_pad);
1645    }
1646    return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
1647  } else if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
1648    if (!_saved_vfp_d16_d31) {
1649      _saved_vfp_d16_d31 = true;
1650      saveVFPv3(_vfp_d16_d31);
1651    }
1652    return _vfp_d16_d31[regNum - UNW_ARM_D16];
1653  } else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
1654    if (!_saved_iwmmx) {
1655      _saved_iwmmx = true;
1656      saveiWMMX(_iwmmx);
1657    }
1658    return _iwmmx[regNum - UNW_ARM_WR0];
1659  } else {
1660    _LIBUNWIND_ABORT("Unknown ARM float register");
1661  }
1662}
1663
1664inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
1665  if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
1666    if (!_saved_vfp_d0_d15) {
1667      _saved_vfp_d0_d15 = true;
1668      if (_use_X_for_vfp_save)
1669        saveVFPWithFSTMX(_vfp_d0_d15_pad);
1670      else
1671        saveVFPWithFSTMD(_vfp_d0_d15_pad);
1672    }
1673    _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
1674  } else if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
1675    if (!_saved_vfp_d16_d31) {
1676      _saved_vfp_d16_d31 = true;
1677      saveVFPv3(_vfp_d16_d31);
1678    }
1679    _vfp_d16_d31[regNum - UNW_ARM_D0] = value;
1680  } else if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
1681    if (!_saved_iwmmx) {
1682      _saved_iwmmx = true;
1683      saveiWMMX(_iwmmx);
1684    }
1685    _iwmmx[regNum - UNW_ARM_WR0] = value;
1686  } else {
1687    _LIBUNWIND_ABORT("Unknown ARM float register");
1688  }
1689}
1690
1691inline bool Registers_arm::validVectorRegister(int) const {
1692  return false;
1693}
1694
1695inline v128 Registers_arm::getVectorRegister(int) const {
1696  _LIBUNWIND_ABORT("ARM vector support not implemented");
1697}
1698
1699inline void Registers_arm::setVectorRegister(int, v128) {
1700  _LIBUNWIND_ABORT("ARM vector support not implemented");
1701}
1702
1703} // namespace libunwind
1704
1705#endif // __REGISTERS_HPP__
1706