Registers.hpp revision 353358
1//===----------------------------- Registers.hpp --------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//
8//  Models register sets for supported processors.
9//
10//===----------------------------------------------------------------------===//
11
12#ifndef __REGISTERS_HPP__
13#define __REGISTERS_HPP__
14
15#include <stdint.h>
16#include <string.h>
17
18#include "libunwind.h"
19#include "config.h"
20
21namespace libunwind {
22
23// For emulating 128-bit registers
24struct v128 { uint32_t vec[4]; };
25
26enum {
27  REGISTERS_X86,
28  REGISTERS_X86_64,
29  REGISTERS_PPC,
30  REGISTERS_PPC64,
31  REGISTERS_ARM64,
32  REGISTERS_ARM,
33  REGISTERS_OR1K,
34  REGISTERS_RISCV,
35  REGISTERS_MIPS_O32,
36  REGISTERS_MIPS_NEWABI,
37  REGISTERS_SPARC,
38};
39
40#if defined(_LIBUNWIND_TARGET_I386)
41/// Registers_x86 holds the register state of a thread in a 32-bit intel
42/// process.
43class _LIBUNWIND_HIDDEN Registers_x86 {
44public:
45  Registers_x86();
46  Registers_x86(const void *registers);
47
48  bool        validRegister(int num) const;
49  uint32_t    getRegister(int num) const;
50  void        setRegister(int num, uint32_t value);
51  bool        validFloatRegister(int) const { return false; }
52  double      getFloatRegister(int num) const;
53  void        setFloatRegister(int num, double value);
54  bool        validVectorRegister(int) const { return false; }
55  v128        getVectorRegister(int num) const;
56  void        setVectorRegister(int num, v128 value);
57  static const char *getRegisterName(int num);
58  void        jumpto();
59  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
60  static int  getArch() { return REGISTERS_X86; }
61
62  uint32_t  getSP() const          { return _registers.__esp; }
63  void      setSP(uint32_t value)  { _registers.__esp = value; }
64  uint32_t  getIP() const          { return _registers.__eip; }
65  void      setIP(uint32_t value)  { _registers.__eip = value; }
66  uint32_t  getEBP() const         { return _registers.__ebp; }
67  void      setEBP(uint32_t value) { _registers.__ebp = value; }
68  uint32_t  getEBX() const         { return _registers.__ebx; }
69  void      setEBX(uint32_t value) { _registers.__ebx = value; }
70  uint32_t  getECX() const         { return _registers.__ecx; }
71  void      setECX(uint32_t value) { _registers.__ecx = value; }
72  uint32_t  getEDX() const         { return _registers.__edx; }
73  void      setEDX(uint32_t value) { _registers.__edx = value; }
74  uint32_t  getESI() const         { return _registers.__esi; }
75  void      setESI(uint32_t value) { _registers.__esi = value; }
76  uint32_t  getEDI() const         { return _registers.__edi; }
77  void      setEDI(uint32_t value) { _registers.__edi = value; }
78
79private:
80  struct GPRs {
81    unsigned int __eax;
82    unsigned int __ebx;
83    unsigned int __ecx;
84    unsigned int __edx;
85    unsigned int __edi;
86    unsigned int __esi;
87    unsigned int __ebp;
88    unsigned int __esp;
89    unsigned int __ss;
90    unsigned int __eflags;
91    unsigned int __eip;
92    unsigned int __cs;
93    unsigned int __ds;
94    unsigned int __es;
95    unsigned int __fs;
96    unsigned int __gs;
97  };
98
99  GPRs _registers;
100};
101
102inline Registers_x86::Registers_x86(const void *registers) {
103  static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
104                "x86 registers do not fit into unw_context_t");
105  memcpy(&_registers, registers, sizeof(_registers));
106}
107
108inline Registers_x86::Registers_x86() {
109  memset(&_registers, 0, sizeof(_registers));
110}
111
112inline bool Registers_x86::validRegister(int regNum) const {
113  if (regNum == UNW_REG_IP)
114    return true;
115  if (regNum == UNW_REG_SP)
116    return true;
117  if (regNum < 0)
118    return false;
119  if (regNum > 7)
120    return false;
121  return true;
122}
123
124inline uint32_t Registers_x86::getRegister(int regNum) const {
125  switch (regNum) {
126  case UNW_REG_IP:
127    return _registers.__eip;
128  case UNW_REG_SP:
129    return _registers.__esp;
130  case UNW_X86_EAX:
131    return _registers.__eax;
132  case UNW_X86_ECX:
133    return _registers.__ecx;
134  case UNW_X86_EDX:
135    return _registers.__edx;
136  case UNW_X86_EBX:
137    return _registers.__ebx;
138#if !defined(__APPLE__)
139  case UNW_X86_ESP:
140#else
141  case UNW_X86_EBP:
142#endif
143    return _registers.__ebp;
144#if !defined(__APPLE__)
145  case UNW_X86_EBP:
146#else
147  case UNW_X86_ESP:
148#endif
149    return _registers.__esp;
150  case UNW_X86_ESI:
151    return _registers.__esi;
152  case UNW_X86_EDI:
153    return _registers.__edi;
154  }
155  _LIBUNWIND_ABORT("unsupported x86 register");
156}
157
158inline void Registers_x86::setRegister(int regNum, uint32_t value) {
159  switch (regNum) {
160  case UNW_REG_IP:
161    _registers.__eip = value;
162    return;
163  case UNW_REG_SP:
164    _registers.__esp = value;
165    return;
166  case UNW_X86_EAX:
167    _registers.__eax = value;
168    return;
169  case UNW_X86_ECX:
170    _registers.__ecx = value;
171    return;
172  case UNW_X86_EDX:
173    _registers.__edx = value;
174    return;
175  case UNW_X86_EBX:
176    _registers.__ebx = value;
177    return;
178#if !defined(__APPLE__)
179  case UNW_X86_ESP:
180#else
181  case UNW_X86_EBP:
182#endif
183    _registers.__ebp = value;
184    return;
185#if !defined(__APPLE__)
186  case UNW_X86_EBP:
187#else
188  case UNW_X86_ESP:
189#endif
190    _registers.__esp = value;
191    return;
192  case UNW_X86_ESI:
193    _registers.__esi = value;
194    return;
195  case UNW_X86_EDI:
196    _registers.__edi = value;
197    return;
198  }
199  _LIBUNWIND_ABORT("unsupported x86 register");
200}
201
202inline const char *Registers_x86::getRegisterName(int regNum) {
203  switch (regNum) {
204  case UNW_REG_IP:
205    return "ip";
206  case UNW_REG_SP:
207    return "esp";
208  case UNW_X86_EAX:
209    return "eax";
210  case UNW_X86_ECX:
211    return "ecx";
212  case UNW_X86_EDX:
213    return "edx";
214  case UNW_X86_EBX:
215    return "ebx";
216  case UNW_X86_EBP:
217    return "ebp";
218  case UNW_X86_ESP:
219    return "esp";
220  case UNW_X86_ESI:
221    return "esi";
222  case UNW_X86_EDI:
223    return "edi";
224  default:
225    return "unknown register";
226  }
227}
228
229inline double Registers_x86::getFloatRegister(int) const {
230  _LIBUNWIND_ABORT("no x86 float registers");
231}
232
233inline void Registers_x86::setFloatRegister(int, double) {
234  _LIBUNWIND_ABORT("no x86 float registers");
235}
236
237inline v128 Registers_x86::getVectorRegister(int) const {
238  _LIBUNWIND_ABORT("no x86 vector registers");
239}
240
241inline void Registers_x86::setVectorRegister(int, v128) {
242  _LIBUNWIND_ABORT("no x86 vector registers");
243}
244#endif // _LIBUNWIND_TARGET_I386
245
246
247#if defined(_LIBUNWIND_TARGET_X86_64)
248/// Registers_x86_64  holds the register state of a thread in a 64-bit intel
249/// process.
250class _LIBUNWIND_HIDDEN Registers_x86_64 {
251public:
252  Registers_x86_64();
253  Registers_x86_64(const void *registers);
254
255  bool        validRegister(int num) const;
256  uint64_t    getRegister(int num) const;
257  void        setRegister(int num, uint64_t value);
258  bool        validFloatRegister(int) const { return false; }
259  double      getFloatRegister(int num) const;
260  void        setFloatRegister(int num, double value);
261  bool        validVectorRegister(int) const;
262  v128        getVectorRegister(int num) const;
263  void        setVectorRegister(int num, v128 value);
264  static const char *getRegisterName(int num);
265  void        jumpto();
266  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
267  static int  getArch() { return REGISTERS_X86_64; }
268
269  uint64_t  getSP() const          { return _registers.__rsp; }
270  void      setSP(uint64_t value)  { _registers.__rsp = value; }
271  uint64_t  getIP() const          { return _registers.__rip; }
272  void      setIP(uint64_t value)  { _registers.__rip = value; }
273  uint64_t  getRBP() const         { return _registers.__rbp; }
274  void      setRBP(uint64_t value) { _registers.__rbp = value; }
275  uint64_t  getRBX() const         { return _registers.__rbx; }
276  void      setRBX(uint64_t value) { _registers.__rbx = value; }
277  uint64_t  getR12() const         { return _registers.__r12; }
278  void      setR12(uint64_t value) { _registers.__r12 = value; }
279  uint64_t  getR13() const         { return _registers.__r13; }
280  void      setR13(uint64_t value) { _registers.__r13 = value; }
281  uint64_t  getR14() const         { return _registers.__r14; }
282  void      setR14(uint64_t value) { _registers.__r14 = value; }
283  uint64_t  getR15() const         { return _registers.__r15; }
284  void      setR15(uint64_t value) { _registers.__r15 = value; }
285
286private:
287  struct GPRs {
288    uint64_t __rax;
289    uint64_t __rbx;
290    uint64_t __rcx;
291    uint64_t __rdx;
292    uint64_t __rdi;
293    uint64_t __rsi;
294    uint64_t __rbp;
295    uint64_t __rsp;
296    uint64_t __r8;
297    uint64_t __r9;
298    uint64_t __r10;
299    uint64_t __r11;
300    uint64_t __r12;
301    uint64_t __r13;
302    uint64_t __r14;
303    uint64_t __r15;
304    uint64_t __rip;
305    uint64_t __rflags;
306    uint64_t __cs;
307    uint64_t __fs;
308    uint64_t __gs;
309#if defined(_WIN64)
310    uint64_t __padding; // 16-byte align
311#endif
312  };
313  GPRs _registers;
314#if defined(_WIN64)
315  v128 _xmm[16];
316#endif
317};
318
319inline Registers_x86_64::Registers_x86_64(const void *registers) {
320  static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
321                "x86_64 registers do not fit into unw_context_t");
322  memcpy(&_registers, registers, sizeof(_registers));
323}
324
325inline Registers_x86_64::Registers_x86_64() {
326  memset(&_registers, 0, sizeof(_registers));
327}
328
329inline bool Registers_x86_64::validRegister(int regNum) const {
330  if (regNum == UNW_REG_IP)
331    return true;
332  if (regNum == UNW_REG_SP)
333    return true;
334  if (regNum < 0)
335    return false;
336  if (regNum > 15)
337    return false;
338  return true;
339}
340
341inline uint64_t Registers_x86_64::getRegister(int regNum) const {
342  switch (regNum) {
343  case UNW_REG_IP:
344    return _registers.__rip;
345  case UNW_REG_SP:
346    return _registers.__rsp;
347  case UNW_X86_64_RAX:
348    return _registers.__rax;
349  case UNW_X86_64_RDX:
350    return _registers.__rdx;
351  case UNW_X86_64_RCX:
352    return _registers.__rcx;
353  case UNW_X86_64_RBX:
354    return _registers.__rbx;
355  case UNW_X86_64_RSI:
356    return _registers.__rsi;
357  case UNW_X86_64_RDI:
358    return _registers.__rdi;
359  case UNW_X86_64_RBP:
360    return _registers.__rbp;
361  case UNW_X86_64_RSP:
362    return _registers.__rsp;
363  case UNW_X86_64_R8:
364    return _registers.__r8;
365  case UNW_X86_64_R9:
366    return _registers.__r9;
367  case UNW_X86_64_R10:
368    return _registers.__r10;
369  case UNW_X86_64_R11:
370    return _registers.__r11;
371  case UNW_X86_64_R12:
372    return _registers.__r12;
373  case UNW_X86_64_R13:
374    return _registers.__r13;
375  case UNW_X86_64_R14:
376    return _registers.__r14;
377  case UNW_X86_64_R15:
378    return _registers.__r15;
379  }
380  _LIBUNWIND_ABORT("unsupported x86_64 register");
381}
382
383inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
384  switch (regNum) {
385  case UNW_REG_IP:
386    _registers.__rip = value;
387    return;
388  case UNW_REG_SP:
389    _registers.__rsp = value;
390    return;
391  case UNW_X86_64_RAX:
392    _registers.__rax = value;
393    return;
394  case UNW_X86_64_RDX:
395    _registers.__rdx = value;
396    return;
397  case UNW_X86_64_RCX:
398    _registers.__rcx = value;
399    return;
400  case UNW_X86_64_RBX:
401    _registers.__rbx = value;
402    return;
403  case UNW_X86_64_RSI:
404    _registers.__rsi = value;
405    return;
406  case UNW_X86_64_RDI:
407    _registers.__rdi = value;
408    return;
409  case UNW_X86_64_RBP:
410    _registers.__rbp = value;
411    return;
412  case UNW_X86_64_RSP:
413    _registers.__rsp = value;
414    return;
415  case UNW_X86_64_R8:
416    _registers.__r8 = value;
417    return;
418  case UNW_X86_64_R9:
419    _registers.__r9 = value;
420    return;
421  case UNW_X86_64_R10:
422    _registers.__r10 = value;
423    return;
424  case UNW_X86_64_R11:
425    _registers.__r11 = value;
426    return;
427  case UNW_X86_64_R12:
428    _registers.__r12 = value;
429    return;
430  case UNW_X86_64_R13:
431    _registers.__r13 = value;
432    return;
433  case UNW_X86_64_R14:
434    _registers.__r14 = value;
435    return;
436  case UNW_X86_64_R15:
437    _registers.__r15 = value;
438    return;
439  }
440  _LIBUNWIND_ABORT("unsupported x86_64 register");
441}
442
443inline const char *Registers_x86_64::getRegisterName(int regNum) {
444  switch (regNum) {
445  case UNW_REG_IP:
446    return "rip";
447  case UNW_REG_SP:
448    return "rsp";
449  case UNW_X86_64_RAX:
450    return "rax";
451  case UNW_X86_64_RDX:
452    return "rdx";
453  case UNW_X86_64_RCX:
454    return "rcx";
455  case UNW_X86_64_RBX:
456    return "rbx";
457  case UNW_X86_64_RSI:
458    return "rsi";
459  case UNW_X86_64_RDI:
460    return "rdi";
461  case UNW_X86_64_RBP:
462    return "rbp";
463  case UNW_X86_64_RSP:
464    return "rsp";
465  case UNW_X86_64_R8:
466    return "r8";
467  case UNW_X86_64_R9:
468    return "r9";
469  case UNW_X86_64_R10:
470    return "r10";
471  case UNW_X86_64_R11:
472    return "r11";
473  case UNW_X86_64_R12:
474    return "r12";
475  case UNW_X86_64_R13:
476    return "r13";
477  case UNW_X86_64_R14:
478    return "r14";
479  case UNW_X86_64_R15:
480    return "r15";
481  case UNW_X86_64_XMM0:
482    return "xmm0";
483  case UNW_X86_64_XMM1:
484    return "xmm1";
485  case UNW_X86_64_XMM2:
486    return "xmm2";
487  case UNW_X86_64_XMM3:
488    return "xmm3";
489  case UNW_X86_64_XMM4:
490    return "xmm4";
491  case UNW_X86_64_XMM5:
492    return "xmm5";
493  case UNW_X86_64_XMM6:
494    return "xmm6";
495  case UNW_X86_64_XMM7:
496    return "xmm7";
497  case UNW_X86_64_XMM8:
498    return "xmm8";
499  case UNW_X86_64_XMM9:
500    return "xmm9";
501  case UNW_X86_64_XMM10:
502    return "xmm10";
503  case UNW_X86_64_XMM11:
504    return "xmm11";
505  case UNW_X86_64_XMM12:
506    return "xmm12";
507  case UNW_X86_64_XMM13:
508    return "xmm13";
509  case UNW_X86_64_XMM14:
510    return "xmm14";
511  case UNW_X86_64_XMM15:
512    return "xmm15";
513  default:
514    return "unknown register";
515  }
516}
517
518inline double Registers_x86_64::getFloatRegister(int) const {
519  _LIBUNWIND_ABORT("no x86_64 float registers");
520}
521
522inline void Registers_x86_64::setFloatRegister(int, double) {
523  _LIBUNWIND_ABORT("no x86_64 float registers");
524}
525
526inline bool Registers_x86_64::validVectorRegister(int regNum) const {
527#if defined(_WIN64)
528  if (regNum < UNW_X86_64_XMM0)
529    return false;
530  if (regNum > UNW_X86_64_XMM15)
531    return false;
532  return true;
533#else
534  (void)regNum; // suppress unused parameter warning
535  return false;
536#endif
537}
538
539inline v128 Registers_x86_64::getVectorRegister(int regNum) const {
540#if defined(_WIN64)
541  assert(validVectorRegister(regNum));
542  return _xmm[regNum - UNW_X86_64_XMM0];
543#else
544  (void)regNum; // suppress unused parameter warning
545  _LIBUNWIND_ABORT("no x86_64 vector registers");
546#endif
547}
548
549inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {
550#if defined(_WIN64)
551  assert(validVectorRegister(regNum));
552  _xmm[regNum - UNW_X86_64_XMM0] = value;
553#else
554  (void)regNum; (void)value; // suppress unused parameter warnings
555  _LIBUNWIND_ABORT("no x86_64 vector registers");
556#endif
557}
558#endif // _LIBUNWIND_TARGET_X86_64
559
560
561#if defined(_LIBUNWIND_TARGET_PPC)
562/// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
563/// process.
564class _LIBUNWIND_HIDDEN Registers_ppc {
565public:
566  Registers_ppc();
567  Registers_ppc(const void *registers);
568
569  bool        validRegister(int num) const;
570  uint32_t    getRegister(int num) const;
571  void        setRegister(int num, uint32_t value);
572  bool        validFloatRegister(int num) const;
573  double      getFloatRegister(int num) const;
574  void        setFloatRegister(int num, double value);
575  bool        validVectorRegister(int num) const;
576  v128        getVectorRegister(int num) const;
577  void        setVectorRegister(int num, v128 value);
578  static const char *getRegisterName(int num);
579  void        jumpto();
580  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; }
581  static int  getArch() { return REGISTERS_PPC; }
582
583  uint64_t  getSP() const         { return _registers.__r1; }
584  void      setSP(uint32_t value) { _registers.__r1 = value; }
585  uint64_t  getIP() const         { return _registers.__srr0; }
586  void      setIP(uint32_t value) { _registers.__srr0 = value; }
587
588private:
589  struct ppc_thread_state_t {
590    unsigned int __srr0; /* Instruction address register (PC) */
591    unsigned int __srr1; /* Machine state register (supervisor) */
592    unsigned int __r0;
593    unsigned int __r1;
594    unsigned int __r2;
595    unsigned int __r3;
596    unsigned int __r4;
597    unsigned int __r5;
598    unsigned int __r6;
599    unsigned int __r7;
600    unsigned int __r8;
601    unsigned int __r9;
602    unsigned int __r10;
603    unsigned int __r11;
604    unsigned int __r12;
605    unsigned int __r13;
606    unsigned int __r14;
607    unsigned int __r15;
608    unsigned int __r16;
609    unsigned int __r17;
610    unsigned int __r18;
611    unsigned int __r19;
612    unsigned int __r20;
613    unsigned int __r21;
614    unsigned int __r22;
615    unsigned int __r23;
616    unsigned int __r24;
617    unsigned int __r25;
618    unsigned int __r26;
619    unsigned int __r27;
620    unsigned int __r28;
621    unsigned int __r29;
622    unsigned int __r30;
623    unsigned int __r31;
624    unsigned int __cr;     /* Condition register */
625    unsigned int __xer;    /* User's integer exception register */
626    unsigned int __lr;     /* Link register */
627    unsigned int __ctr;    /* Count register */
628    unsigned int __mq;     /* MQ register (601 only) */
629    unsigned int __vrsave; /* Vector Save Register */
630  };
631
632  struct ppc_float_state_t {
633    double __fpregs[32];
634
635    unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
636    unsigned int __fpscr;     /* floating point status register */
637  };
638
639  ppc_thread_state_t _registers;
640  ppc_float_state_t  _floatRegisters;
641  v128               _vectorRegisters[32]; // offset 424
642};
643
644inline Registers_ppc::Registers_ppc(const void *registers) {
645  static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
646                "ppc registers do not fit into unw_context_t");
647  memcpy(&_registers, static_cast<const uint8_t *>(registers),
648         sizeof(_registers));
649  static_assert(sizeof(ppc_thread_state_t) == 160,
650                "expected float register offset to be 160");
651  memcpy(&_floatRegisters,
652         static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
653         sizeof(_floatRegisters));
654  static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
655                "expected vector register offset to be 424 bytes");
656  memcpy(_vectorRegisters,
657         static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
658             sizeof(ppc_float_state_t),
659         sizeof(_vectorRegisters));
660}
661
662inline Registers_ppc::Registers_ppc() {
663  memset(&_registers, 0, sizeof(_registers));
664  memset(&_floatRegisters, 0, sizeof(_floatRegisters));
665  memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
666}
667
668inline bool Registers_ppc::validRegister(int regNum) const {
669  if (regNum == UNW_REG_IP)
670    return true;
671  if (regNum == UNW_REG_SP)
672    return true;
673  if (regNum == UNW_PPC_VRSAVE)
674    return true;
675  if (regNum < 0)
676    return false;
677  if (regNum <= UNW_PPC_R31)
678    return true;
679  if (regNum == UNW_PPC_MQ)
680    return true;
681  if (regNum == UNW_PPC_LR)
682    return true;
683  if (regNum == UNW_PPC_CTR)
684    return true;
685  if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
686    return true;
687  return false;
688}
689
690inline uint32_t Registers_ppc::getRegister(int regNum) const {
691  switch (regNum) {
692  case UNW_REG_IP:
693    return _registers.__srr0;
694  case UNW_REG_SP:
695    return _registers.__r1;
696  case UNW_PPC_R0:
697    return _registers.__r0;
698  case UNW_PPC_R1:
699    return _registers.__r1;
700  case UNW_PPC_R2:
701    return _registers.__r2;
702  case UNW_PPC_R3:
703    return _registers.__r3;
704  case UNW_PPC_R4:
705    return _registers.__r4;
706  case UNW_PPC_R5:
707    return _registers.__r5;
708  case UNW_PPC_R6:
709    return _registers.__r6;
710  case UNW_PPC_R7:
711    return _registers.__r7;
712  case UNW_PPC_R8:
713    return _registers.__r8;
714  case UNW_PPC_R9:
715    return _registers.__r9;
716  case UNW_PPC_R10:
717    return _registers.__r10;
718  case UNW_PPC_R11:
719    return _registers.__r11;
720  case UNW_PPC_R12:
721    return _registers.__r12;
722  case UNW_PPC_R13:
723    return _registers.__r13;
724  case UNW_PPC_R14:
725    return _registers.__r14;
726  case UNW_PPC_R15:
727    return _registers.__r15;
728  case UNW_PPC_R16:
729    return _registers.__r16;
730  case UNW_PPC_R17:
731    return _registers.__r17;
732  case UNW_PPC_R18:
733    return _registers.__r18;
734  case UNW_PPC_R19:
735    return _registers.__r19;
736  case UNW_PPC_R20:
737    return _registers.__r20;
738  case UNW_PPC_R21:
739    return _registers.__r21;
740  case UNW_PPC_R22:
741    return _registers.__r22;
742  case UNW_PPC_R23:
743    return _registers.__r23;
744  case UNW_PPC_R24:
745    return _registers.__r24;
746  case UNW_PPC_R25:
747    return _registers.__r25;
748  case UNW_PPC_R26:
749    return _registers.__r26;
750  case UNW_PPC_R27:
751    return _registers.__r27;
752  case UNW_PPC_R28:
753    return _registers.__r28;
754  case UNW_PPC_R29:
755    return _registers.__r29;
756  case UNW_PPC_R30:
757    return _registers.__r30;
758  case UNW_PPC_R31:
759    return _registers.__r31;
760  case UNW_PPC_LR:
761    return _registers.__lr;
762  case UNW_PPC_CR0:
763    return (_registers.__cr & 0xF0000000);
764  case UNW_PPC_CR1:
765    return (_registers.__cr & 0x0F000000);
766  case UNW_PPC_CR2:
767    return (_registers.__cr & 0x00F00000);
768  case UNW_PPC_CR3:
769    return (_registers.__cr & 0x000F0000);
770  case UNW_PPC_CR4:
771    return (_registers.__cr & 0x0000F000);
772  case UNW_PPC_CR5:
773    return (_registers.__cr & 0x00000F00);
774  case UNW_PPC_CR6:
775    return (_registers.__cr & 0x000000F0);
776  case UNW_PPC_CR7:
777    return (_registers.__cr & 0x0000000F);
778  case UNW_PPC_VRSAVE:
779    return _registers.__vrsave;
780  }
781  _LIBUNWIND_ABORT("unsupported ppc register");
782}
783
784inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
785  //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
786  switch (regNum) {
787  case UNW_REG_IP:
788    _registers.__srr0 = value;
789    return;
790  case UNW_REG_SP:
791    _registers.__r1 = value;
792    return;
793  case UNW_PPC_R0:
794    _registers.__r0 = value;
795    return;
796  case UNW_PPC_R1:
797    _registers.__r1 = value;
798    return;
799  case UNW_PPC_R2:
800    _registers.__r2 = value;
801    return;
802  case UNW_PPC_R3:
803    _registers.__r3 = value;
804    return;
805  case UNW_PPC_R4:
806    _registers.__r4 = value;
807    return;
808  case UNW_PPC_R5:
809    _registers.__r5 = value;
810    return;
811  case UNW_PPC_R6:
812    _registers.__r6 = value;
813    return;
814  case UNW_PPC_R7:
815    _registers.__r7 = value;
816    return;
817  case UNW_PPC_R8:
818    _registers.__r8 = value;
819    return;
820  case UNW_PPC_R9:
821    _registers.__r9 = value;
822    return;
823  case UNW_PPC_R10:
824    _registers.__r10 = value;
825    return;
826  case UNW_PPC_R11:
827    _registers.__r11 = value;
828    return;
829  case UNW_PPC_R12:
830    _registers.__r12 = value;
831    return;
832  case UNW_PPC_R13:
833    _registers.__r13 = value;
834    return;
835  case UNW_PPC_R14:
836    _registers.__r14 = value;
837    return;
838  case UNW_PPC_R15:
839    _registers.__r15 = value;
840    return;
841  case UNW_PPC_R16:
842    _registers.__r16 = value;
843    return;
844  case UNW_PPC_R17:
845    _registers.__r17 = value;
846    return;
847  case UNW_PPC_R18:
848    _registers.__r18 = value;
849    return;
850  case UNW_PPC_R19:
851    _registers.__r19 = value;
852    return;
853  case UNW_PPC_R20:
854    _registers.__r20 = value;
855    return;
856  case UNW_PPC_R21:
857    _registers.__r21 = value;
858    return;
859  case UNW_PPC_R22:
860    _registers.__r22 = value;
861    return;
862  case UNW_PPC_R23:
863    _registers.__r23 = value;
864    return;
865  case UNW_PPC_R24:
866    _registers.__r24 = value;
867    return;
868  case UNW_PPC_R25:
869    _registers.__r25 = value;
870    return;
871  case UNW_PPC_R26:
872    _registers.__r26 = value;
873    return;
874  case UNW_PPC_R27:
875    _registers.__r27 = value;
876    return;
877  case UNW_PPC_R28:
878    _registers.__r28 = value;
879    return;
880  case UNW_PPC_R29:
881    _registers.__r29 = value;
882    return;
883  case UNW_PPC_R30:
884    _registers.__r30 = value;
885    return;
886  case UNW_PPC_R31:
887    _registers.__r31 = value;
888    return;
889  case UNW_PPC_MQ:
890    _registers.__mq = value;
891    return;
892  case UNW_PPC_LR:
893    _registers.__lr = value;
894    return;
895  case UNW_PPC_CTR:
896    _registers.__ctr = value;
897    return;
898  case UNW_PPC_CR0:
899    _registers.__cr &= 0x0FFFFFFF;
900    _registers.__cr |= (value & 0xF0000000);
901    return;
902  case UNW_PPC_CR1:
903    _registers.__cr &= 0xF0FFFFFF;
904    _registers.__cr |= (value & 0x0F000000);
905    return;
906  case UNW_PPC_CR2:
907    _registers.__cr &= 0xFF0FFFFF;
908    _registers.__cr |= (value & 0x00F00000);
909    return;
910  case UNW_PPC_CR3:
911    _registers.__cr &= 0xFFF0FFFF;
912    _registers.__cr |= (value & 0x000F0000);
913    return;
914  case UNW_PPC_CR4:
915    _registers.__cr &= 0xFFFF0FFF;
916    _registers.__cr |= (value & 0x0000F000);
917    return;
918  case UNW_PPC_CR5:
919    _registers.__cr &= 0xFFFFF0FF;
920    _registers.__cr |= (value & 0x00000F00);
921    return;
922  case UNW_PPC_CR6:
923    _registers.__cr &= 0xFFFFFF0F;
924    _registers.__cr |= (value & 0x000000F0);
925    return;
926  case UNW_PPC_CR7:
927    _registers.__cr &= 0xFFFFFFF0;
928    _registers.__cr |= (value & 0x0000000F);
929    return;
930  case UNW_PPC_VRSAVE:
931    _registers.__vrsave = value;
932    return;
933    // not saved
934    return;
935  case UNW_PPC_XER:
936    _registers.__xer = value;
937    return;
938  case UNW_PPC_AP:
939  case UNW_PPC_VSCR:
940  case UNW_PPC_SPEFSCR:
941    // not saved
942    return;
943  }
944  _LIBUNWIND_ABORT("unsupported ppc register");
945}
946
947inline bool Registers_ppc::validFloatRegister(int regNum) const {
948  if (regNum < UNW_PPC_F0)
949    return false;
950  if (regNum > UNW_PPC_F31)
951    return false;
952  return true;
953}
954
955inline double Registers_ppc::getFloatRegister(int regNum) const {
956  assert(validFloatRegister(regNum));
957  return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
958}
959
960inline void Registers_ppc::setFloatRegister(int regNum, double value) {
961  assert(validFloatRegister(regNum));
962  _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
963}
964
965inline bool Registers_ppc::validVectorRegister(int regNum) const {
966  if (regNum < UNW_PPC_V0)
967    return false;
968  if (regNum > UNW_PPC_V31)
969    return false;
970  return true;
971}
972
973inline v128 Registers_ppc::getVectorRegister(int regNum) const {
974  assert(validVectorRegister(regNum));
975  v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
976  return result;
977}
978
979inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
980  assert(validVectorRegister(regNum));
981  _vectorRegisters[regNum - UNW_PPC_V0] = value;
982}
983
984inline const char *Registers_ppc::getRegisterName(int regNum) {
985  switch (regNum) {
986  case UNW_REG_IP:
987    return "ip";
988  case UNW_REG_SP:
989    return "sp";
990  case UNW_PPC_R0:
991    return "r0";
992  case UNW_PPC_R1:
993    return "r1";
994  case UNW_PPC_R2:
995    return "r2";
996  case UNW_PPC_R3:
997    return "r3";
998  case UNW_PPC_R4:
999    return "r4";
1000  case UNW_PPC_R5:
1001    return "r5";
1002  case UNW_PPC_R6:
1003    return "r6";
1004  case UNW_PPC_R7:
1005    return "r7";
1006  case UNW_PPC_R8:
1007    return "r8";
1008  case UNW_PPC_R9:
1009    return "r9";
1010  case UNW_PPC_R10:
1011    return "r10";
1012  case UNW_PPC_R11:
1013    return "r11";
1014  case UNW_PPC_R12:
1015    return "r12";
1016  case UNW_PPC_R13:
1017    return "r13";
1018  case UNW_PPC_R14:
1019    return "r14";
1020  case UNW_PPC_R15:
1021    return "r15";
1022  case UNW_PPC_R16:
1023    return "r16";
1024  case UNW_PPC_R17:
1025    return "r17";
1026  case UNW_PPC_R18:
1027    return "r18";
1028  case UNW_PPC_R19:
1029    return "r19";
1030  case UNW_PPC_R20:
1031    return "r20";
1032  case UNW_PPC_R21:
1033    return "r21";
1034  case UNW_PPC_R22:
1035    return "r22";
1036  case UNW_PPC_R23:
1037    return "r23";
1038  case UNW_PPC_R24:
1039    return "r24";
1040  case UNW_PPC_R25:
1041    return "r25";
1042  case UNW_PPC_R26:
1043    return "r26";
1044  case UNW_PPC_R27:
1045    return "r27";
1046  case UNW_PPC_R28:
1047    return "r28";
1048  case UNW_PPC_R29:
1049    return "r29";
1050  case UNW_PPC_R30:
1051    return "r30";
1052  case UNW_PPC_R31:
1053    return "r31";
1054  case UNW_PPC_F0:
1055    return "fp0";
1056  case UNW_PPC_F1:
1057    return "fp1";
1058  case UNW_PPC_F2:
1059    return "fp2";
1060  case UNW_PPC_F3:
1061    return "fp3";
1062  case UNW_PPC_F4:
1063    return "fp4";
1064  case UNW_PPC_F5:
1065    return "fp5";
1066  case UNW_PPC_F6:
1067    return "fp6";
1068  case UNW_PPC_F7:
1069    return "fp7";
1070  case UNW_PPC_F8:
1071    return "fp8";
1072  case UNW_PPC_F9:
1073    return "fp9";
1074  case UNW_PPC_F10:
1075    return "fp10";
1076  case UNW_PPC_F11:
1077    return "fp11";
1078  case UNW_PPC_F12:
1079    return "fp12";
1080  case UNW_PPC_F13:
1081    return "fp13";
1082  case UNW_PPC_F14:
1083    return "fp14";
1084  case UNW_PPC_F15:
1085    return "fp15";
1086  case UNW_PPC_F16:
1087    return "fp16";
1088  case UNW_PPC_F17:
1089    return "fp17";
1090  case UNW_PPC_F18:
1091    return "fp18";
1092  case UNW_PPC_F19:
1093    return "fp19";
1094  case UNW_PPC_F20:
1095    return "fp20";
1096  case UNW_PPC_F21:
1097    return "fp21";
1098  case UNW_PPC_F22:
1099    return "fp22";
1100  case UNW_PPC_F23:
1101    return "fp23";
1102  case UNW_PPC_F24:
1103    return "fp24";
1104  case UNW_PPC_F25:
1105    return "fp25";
1106  case UNW_PPC_F26:
1107    return "fp26";
1108  case UNW_PPC_F27:
1109    return "fp27";
1110  case UNW_PPC_F28:
1111    return "fp28";
1112  case UNW_PPC_F29:
1113    return "fp29";
1114  case UNW_PPC_F30:
1115    return "fp30";
1116  case UNW_PPC_F31:
1117    return "fp31";
1118  case UNW_PPC_LR:
1119    return "lr";
1120  default:
1121    return "unknown register";
1122  }
1123
1124}
1125#endif // _LIBUNWIND_TARGET_PPC
1126
1127#if defined(_LIBUNWIND_TARGET_PPC64)
1128/// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC
1129/// process.
1130class _LIBUNWIND_HIDDEN Registers_ppc64 {
1131public:
1132  Registers_ppc64();
1133  Registers_ppc64(const void *registers);
1134
1135  bool        validRegister(int num) const;
1136  uint64_t    getRegister(int num) const;
1137  void        setRegister(int num, uint64_t value);
1138  bool        validFloatRegister(int num) const;
1139  double      getFloatRegister(int num) const;
1140  void        setFloatRegister(int num, double value);
1141  bool        validVectorRegister(int num) const;
1142  v128        getVectorRegister(int num) const;
1143  void        setVectorRegister(int num, v128 value);
1144  static const char *getRegisterName(int num);
1145  void        jumpto();
1146  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64; }
1147  static int  getArch() { return REGISTERS_PPC64; }
1148
1149  uint64_t  getSP() const         { return _registers.__r1; }
1150  void      setSP(uint64_t value) { _registers.__r1 = value; }
1151  uint64_t  getIP() const         { return _registers.__srr0; }
1152  void      setIP(uint64_t value) { _registers.__srr0 = value; }
1153
1154private:
1155  struct ppc64_thread_state_t {
1156    uint64_t __srr0;    // Instruction address register (PC)
1157    uint64_t __srr1;    // Machine state register (supervisor)
1158    uint64_t __r0;
1159    uint64_t __r1;
1160    uint64_t __r2;
1161    uint64_t __r3;
1162    uint64_t __r4;
1163    uint64_t __r5;
1164    uint64_t __r6;
1165    uint64_t __r7;
1166    uint64_t __r8;
1167    uint64_t __r9;
1168    uint64_t __r10;
1169    uint64_t __r11;
1170    uint64_t __r12;
1171    uint64_t __r13;
1172    uint64_t __r14;
1173    uint64_t __r15;
1174    uint64_t __r16;
1175    uint64_t __r17;
1176    uint64_t __r18;
1177    uint64_t __r19;
1178    uint64_t __r20;
1179    uint64_t __r21;
1180    uint64_t __r22;
1181    uint64_t __r23;
1182    uint64_t __r24;
1183    uint64_t __r25;
1184    uint64_t __r26;
1185    uint64_t __r27;
1186    uint64_t __r28;
1187    uint64_t __r29;
1188    uint64_t __r30;
1189    uint64_t __r31;
1190    uint64_t __cr;      // Condition register
1191    uint64_t __xer;     // User's integer exception register
1192    uint64_t __lr;      // Link register
1193    uint64_t __ctr;     // Count register
1194    uint64_t __vrsave;  // Vector Save Register
1195  };
1196
1197  union ppc64_vsr_t {
1198    struct asfloat_s {
1199      double f;
1200      uint64_t v2;
1201    } asfloat;
1202    v128 v;
1203  };
1204
1205  ppc64_thread_state_t _registers;
1206  ppc64_vsr_t          _vectorScalarRegisters[64];
1207
1208  static int getVectorRegNum(int num);
1209};
1210
1211inline Registers_ppc64::Registers_ppc64(const void *registers) {
1212  static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit),
1213                "ppc64 registers do not fit into unw_context_t");
1214  memcpy(&_registers, static_cast<const uint8_t *>(registers),
1215         sizeof(_registers));
1216  static_assert(sizeof(_registers) == 312,
1217                "expected vector scalar register offset to be 312");
1218  memcpy(&_vectorScalarRegisters,
1219         static_cast<const uint8_t *>(registers) + sizeof(_registers),
1220         sizeof(_vectorScalarRegisters));
1221  static_assert(sizeof(_registers) +
1222                sizeof(_vectorScalarRegisters) == 1336,
1223                "expected vector register offset to be 1336 bytes");
1224}
1225
1226inline Registers_ppc64::Registers_ppc64() {
1227  memset(&_registers, 0, sizeof(_registers));
1228  memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters));
1229}
1230
1231inline bool Registers_ppc64::validRegister(int regNum) const {
1232  switch (regNum) {
1233  case UNW_REG_IP:
1234  case UNW_REG_SP:
1235  case UNW_PPC64_XER:
1236  case UNW_PPC64_LR:
1237  case UNW_PPC64_CTR:
1238  case UNW_PPC64_VRSAVE:
1239      return true;
1240  }
1241
1242  if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31)
1243    return true;
1244  if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7)
1245    return true;
1246
1247  return false;
1248}
1249
1250inline uint64_t Registers_ppc64::getRegister(int regNum) const {
1251  switch (regNum) {
1252  case UNW_REG_IP:
1253    return _registers.__srr0;
1254  case UNW_PPC64_R0:
1255    return _registers.__r0;
1256  case UNW_PPC64_R1:
1257  case UNW_REG_SP:
1258    return _registers.__r1;
1259  case UNW_PPC64_R2:
1260    return _registers.__r2;
1261  case UNW_PPC64_R3:
1262    return _registers.__r3;
1263  case UNW_PPC64_R4:
1264    return _registers.__r4;
1265  case UNW_PPC64_R5:
1266    return _registers.__r5;
1267  case UNW_PPC64_R6:
1268    return _registers.__r6;
1269  case UNW_PPC64_R7:
1270    return _registers.__r7;
1271  case UNW_PPC64_R8:
1272    return _registers.__r8;
1273  case UNW_PPC64_R9:
1274    return _registers.__r9;
1275  case UNW_PPC64_R10:
1276    return _registers.__r10;
1277  case UNW_PPC64_R11:
1278    return _registers.__r11;
1279  case UNW_PPC64_R12:
1280    return _registers.__r12;
1281  case UNW_PPC64_R13:
1282    return _registers.__r13;
1283  case UNW_PPC64_R14:
1284    return _registers.__r14;
1285  case UNW_PPC64_R15:
1286    return _registers.__r15;
1287  case UNW_PPC64_R16:
1288    return _registers.__r16;
1289  case UNW_PPC64_R17:
1290    return _registers.__r17;
1291  case UNW_PPC64_R18:
1292    return _registers.__r18;
1293  case UNW_PPC64_R19:
1294    return _registers.__r19;
1295  case UNW_PPC64_R20:
1296    return _registers.__r20;
1297  case UNW_PPC64_R21:
1298    return _registers.__r21;
1299  case UNW_PPC64_R22:
1300    return _registers.__r22;
1301  case UNW_PPC64_R23:
1302    return _registers.__r23;
1303  case UNW_PPC64_R24:
1304    return _registers.__r24;
1305  case UNW_PPC64_R25:
1306    return _registers.__r25;
1307  case UNW_PPC64_R26:
1308    return _registers.__r26;
1309  case UNW_PPC64_R27:
1310    return _registers.__r27;
1311  case UNW_PPC64_R28:
1312    return _registers.__r28;
1313  case UNW_PPC64_R29:
1314    return _registers.__r29;
1315  case UNW_PPC64_R30:
1316    return _registers.__r30;
1317  case UNW_PPC64_R31:
1318    return _registers.__r31;
1319  case UNW_PPC64_CR0:
1320    return (_registers.__cr & 0xF0000000);
1321  case UNW_PPC64_CR1:
1322    return (_registers.__cr & 0x0F000000);
1323  case UNW_PPC64_CR2:
1324    return (_registers.__cr & 0x00F00000);
1325  case UNW_PPC64_CR3:
1326    return (_registers.__cr & 0x000F0000);
1327  case UNW_PPC64_CR4:
1328    return (_registers.__cr & 0x0000F000);
1329  case UNW_PPC64_CR5:
1330    return (_registers.__cr & 0x00000F00);
1331  case UNW_PPC64_CR6:
1332    return (_registers.__cr & 0x000000F0);
1333  case UNW_PPC64_CR7:
1334    return (_registers.__cr & 0x0000000F);
1335  case UNW_PPC64_XER:
1336    return _registers.__xer;
1337  case UNW_PPC64_LR:
1338    return _registers.__lr;
1339  case UNW_PPC64_CTR:
1340    return _registers.__ctr;
1341  case UNW_PPC64_VRSAVE:
1342    return _registers.__vrsave;
1343  }
1344  _LIBUNWIND_ABORT("unsupported ppc64 register");
1345}
1346
1347inline void Registers_ppc64::setRegister(int regNum, uint64_t value) {
1348  switch (regNum) {
1349  case UNW_REG_IP:
1350    _registers.__srr0 = value;
1351    return;
1352  case UNW_PPC64_R0:
1353    _registers.__r0 = value;
1354    return;
1355  case UNW_PPC64_R1:
1356  case UNW_REG_SP:
1357    _registers.__r1 = value;
1358    return;
1359  case UNW_PPC64_R2:
1360    _registers.__r2 = value;
1361    return;
1362  case UNW_PPC64_R3:
1363    _registers.__r3 = value;
1364    return;
1365  case UNW_PPC64_R4:
1366    _registers.__r4 = value;
1367    return;
1368  case UNW_PPC64_R5:
1369    _registers.__r5 = value;
1370    return;
1371  case UNW_PPC64_R6:
1372    _registers.__r6 = value;
1373    return;
1374  case UNW_PPC64_R7:
1375    _registers.__r7 = value;
1376    return;
1377  case UNW_PPC64_R8:
1378    _registers.__r8 = value;
1379    return;
1380  case UNW_PPC64_R9:
1381    _registers.__r9 = value;
1382    return;
1383  case UNW_PPC64_R10:
1384    _registers.__r10 = value;
1385    return;
1386  case UNW_PPC64_R11:
1387    _registers.__r11 = value;
1388    return;
1389  case UNW_PPC64_R12:
1390    _registers.__r12 = value;
1391    return;
1392  case UNW_PPC64_R13:
1393    _registers.__r13 = value;
1394    return;
1395  case UNW_PPC64_R14:
1396    _registers.__r14 = value;
1397    return;
1398  case UNW_PPC64_R15:
1399    _registers.__r15 = value;
1400    return;
1401  case UNW_PPC64_R16:
1402    _registers.__r16 = value;
1403    return;
1404  case UNW_PPC64_R17:
1405    _registers.__r17 = value;
1406    return;
1407  case UNW_PPC64_R18:
1408    _registers.__r18 = value;
1409    return;
1410  case UNW_PPC64_R19:
1411    _registers.__r19 = value;
1412    return;
1413  case UNW_PPC64_R20:
1414    _registers.__r20 = value;
1415    return;
1416  case UNW_PPC64_R21:
1417    _registers.__r21 = value;
1418    return;
1419  case UNW_PPC64_R22:
1420    _registers.__r22 = value;
1421    return;
1422  case UNW_PPC64_R23:
1423    _registers.__r23 = value;
1424    return;
1425  case UNW_PPC64_R24:
1426    _registers.__r24 = value;
1427    return;
1428  case UNW_PPC64_R25:
1429    _registers.__r25 = value;
1430    return;
1431  case UNW_PPC64_R26:
1432    _registers.__r26 = value;
1433    return;
1434  case UNW_PPC64_R27:
1435    _registers.__r27 = value;
1436    return;
1437  case UNW_PPC64_R28:
1438    _registers.__r28 = value;
1439    return;
1440  case UNW_PPC64_R29:
1441    _registers.__r29 = value;
1442    return;
1443  case UNW_PPC64_R30:
1444    _registers.__r30 = value;
1445    return;
1446  case UNW_PPC64_R31:
1447    _registers.__r31 = value;
1448    return;
1449  case UNW_PPC64_CR0:
1450    _registers.__cr &= 0x0FFFFFFF;
1451    _registers.__cr |= (value & 0xF0000000);
1452    return;
1453  case UNW_PPC64_CR1:
1454    _registers.__cr &= 0xF0FFFFFF;
1455    _registers.__cr |= (value & 0x0F000000);
1456    return;
1457  case UNW_PPC64_CR2:
1458    _registers.__cr &= 0xFF0FFFFF;
1459    _registers.__cr |= (value & 0x00F00000);
1460    return;
1461  case UNW_PPC64_CR3:
1462    _registers.__cr &= 0xFFF0FFFF;
1463    _registers.__cr |= (value & 0x000F0000);
1464    return;
1465  case UNW_PPC64_CR4:
1466    _registers.__cr &= 0xFFFF0FFF;
1467    _registers.__cr |= (value & 0x0000F000);
1468    return;
1469  case UNW_PPC64_CR5:
1470    _registers.__cr &= 0xFFFFF0FF;
1471    _registers.__cr |= (value & 0x00000F00);
1472    return;
1473  case UNW_PPC64_CR6:
1474    _registers.__cr &= 0xFFFFFF0F;
1475    _registers.__cr |= (value & 0x000000F0);
1476    return;
1477  case UNW_PPC64_CR7:
1478    _registers.__cr &= 0xFFFFFFF0;
1479    _registers.__cr |= (value & 0x0000000F);
1480    return;
1481  case UNW_PPC64_XER:
1482    _registers.__xer = value;
1483    return;
1484  case UNW_PPC64_LR:
1485    _registers.__lr = value;
1486    return;
1487  case UNW_PPC64_CTR:
1488    _registers.__ctr = value;
1489    return;
1490  case UNW_PPC64_VRSAVE:
1491    _registers.__vrsave = value;
1492    return;
1493  }
1494  _LIBUNWIND_ABORT("unsupported ppc64 register");
1495}
1496
1497inline bool Registers_ppc64::validFloatRegister(int regNum) const {
1498  return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31;
1499}
1500
1501inline double Registers_ppc64::getFloatRegister(int regNum) const {
1502  assert(validFloatRegister(regNum));
1503  return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f;
1504}
1505
1506inline void Registers_ppc64::setFloatRegister(int regNum, double value) {
1507  assert(validFloatRegister(regNum));
1508  _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value;
1509}
1510
1511inline bool Registers_ppc64::validVectorRegister(int regNum) const {
1512#ifdef PPC64_HAS_VMX
1513  if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)
1514    return true;
1515  if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)
1516    return true;
1517#else
1518  if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)
1519    return true;
1520#endif
1521  return false;
1522}
1523
1524inline int Registers_ppc64::getVectorRegNum(int num)
1525{
1526  if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31)
1527    return num - UNW_PPC64_VS0;
1528  else
1529    return num - UNW_PPC64_VS32 + 32;
1530}
1531
1532inline v128 Registers_ppc64::getVectorRegister(int regNum) const {
1533  assert(validVectorRegister(regNum));
1534  return _vectorScalarRegisters[getVectorRegNum(regNum)].v;
1535}
1536
1537inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) {
1538  assert(validVectorRegister(regNum));
1539  _vectorScalarRegisters[getVectorRegNum(regNum)].v = value;
1540}
1541
1542inline const char *Registers_ppc64::getRegisterName(int regNum) {
1543  switch (regNum) {
1544  case UNW_REG_IP:
1545    return "ip";
1546  case UNW_REG_SP:
1547    return "sp";
1548  case UNW_PPC64_R0:
1549    return "r0";
1550  case UNW_PPC64_R1:
1551    return "r1";
1552  case UNW_PPC64_R2:
1553    return "r2";
1554  case UNW_PPC64_R3:
1555    return "r3";
1556  case UNW_PPC64_R4:
1557    return "r4";
1558  case UNW_PPC64_R5:
1559    return "r5";
1560  case UNW_PPC64_R6:
1561    return "r6";
1562  case UNW_PPC64_R7:
1563    return "r7";
1564  case UNW_PPC64_R8:
1565    return "r8";
1566  case UNW_PPC64_R9:
1567    return "r9";
1568  case UNW_PPC64_R10:
1569    return "r10";
1570  case UNW_PPC64_R11:
1571    return "r11";
1572  case UNW_PPC64_R12:
1573    return "r12";
1574  case UNW_PPC64_R13:
1575    return "r13";
1576  case UNW_PPC64_R14:
1577    return "r14";
1578  case UNW_PPC64_R15:
1579    return "r15";
1580  case UNW_PPC64_R16:
1581    return "r16";
1582  case UNW_PPC64_R17:
1583    return "r17";
1584  case UNW_PPC64_R18:
1585    return "r18";
1586  case UNW_PPC64_R19:
1587    return "r19";
1588  case UNW_PPC64_R20:
1589    return "r20";
1590  case UNW_PPC64_R21:
1591    return "r21";
1592  case UNW_PPC64_R22:
1593    return "r22";
1594  case UNW_PPC64_R23:
1595    return "r23";
1596  case UNW_PPC64_R24:
1597    return "r24";
1598  case UNW_PPC64_R25:
1599    return "r25";
1600  case UNW_PPC64_R26:
1601    return "r26";
1602  case UNW_PPC64_R27:
1603    return "r27";
1604  case UNW_PPC64_R28:
1605    return "r28";
1606  case UNW_PPC64_R29:
1607    return "r29";
1608  case UNW_PPC64_R30:
1609    return "r30";
1610  case UNW_PPC64_R31:
1611    return "r31";
1612  case UNW_PPC64_CR0:
1613    return "cr0";
1614  case UNW_PPC64_CR1:
1615    return "cr1";
1616  case UNW_PPC64_CR2:
1617    return "cr2";
1618  case UNW_PPC64_CR3:
1619    return "cr3";
1620  case UNW_PPC64_CR4:
1621    return "cr4";
1622  case UNW_PPC64_CR5:
1623    return "cr5";
1624  case UNW_PPC64_CR6:
1625    return "cr6";
1626  case UNW_PPC64_CR7:
1627    return "cr7";
1628  case UNW_PPC64_XER:
1629    return "xer";
1630  case UNW_PPC64_LR:
1631    return "lr";
1632  case UNW_PPC64_CTR:
1633    return "ctr";
1634  case UNW_PPC64_VRSAVE:
1635    return "vrsave";
1636  case UNW_PPC64_F0:
1637    return "fp0";
1638  case UNW_PPC64_F1:
1639    return "fp1";
1640  case UNW_PPC64_F2:
1641    return "fp2";
1642  case UNW_PPC64_F3:
1643    return "fp3";
1644  case UNW_PPC64_F4:
1645    return "fp4";
1646  case UNW_PPC64_F5:
1647    return "fp5";
1648  case UNW_PPC64_F6:
1649    return "fp6";
1650  case UNW_PPC64_F7:
1651    return "fp7";
1652  case UNW_PPC64_F8:
1653    return "fp8";
1654  case UNW_PPC64_F9:
1655    return "fp9";
1656  case UNW_PPC64_F10:
1657    return "fp10";
1658  case UNW_PPC64_F11:
1659    return "fp11";
1660  case UNW_PPC64_F12:
1661    return "fp12";
1662  case UNW_PPC64_F13:
1663    return "fp13";
1664  case UNW_PPC64_F14:
1665    return "fp14";
1666  case UNW_PPC64_F15:
1667    return "fp15";
1668  case UNW_PPC64_F16:
1669    return "fp16";
1670  case UNW_PPC64_F17:
1671    return "fp17";
1672  case UNW_PPC64_F18:
1673    return "fp18";
1674  case UNW_PPC64_F19:
1675    return "fp19";
1676  case UNW_PPC64_F20:
1677    return "fp20";
1678  case UNW_PPC64_F21:
1679    return "fp21";
1680  case UNW_PPC64_F22:
1681    return "fp22";
1682  case UNW_PPC64_F23:
1683    return "fp23";
1684  case UNW_PPC64_F24:
1685    return "fp24";
1686  case UNW_PPC64_F25:
1687    return "fp25";
1688  case UNW_PPC64_F26:
1689    return "fp26";
1690  case UNW_PPC64_F27:
1691    return "fp27";
1692  case UNW_PPC64_F28:
1693    return "fp28";
1694  case UNW_PPC64_F29:
1695    return "fp29";
1696  case UNW_PPC64_F30:
1697    return "fp30";
1698  case UNW_PPC64_F31:
1699    return "fp31";
1700  case UNW_PPC64_V0:
1701    return "v0";
1702  case UNW_PPC64_V1:
1703    return "v1";
1704  case UNW_PPC64_V2:
1705    return "v2";
1706  case UNW_PPC64_V3:
1707    return "v3";
1708  case UNW_PPC64_V4:
1709    return "v4";
1710  case UNW_PPC64_V5:
1711    return "v5";
1712  case UNW_PPC64_V6:
1713    return "v6";
1714  case UNW_PPC64_V7:
1715    return "v7";
1716  case UNW_PPC64_V8:
1717    return "v8";
1718  case UNW_PPC64_V9:
1719    return "v9";
1720  case UNW_PPC64_V10:
1721    return "v10";
1722  case UNW_PPC64_V11:
1723    return "v11";
1724  case UNW_PPC64_V12:
1725    return "v12";
1726  case UNW_PPC64_V13:
1727    return "v13";
1728  case UNW_PPC64_V14:
1729    return "v14";
1730  case UNW_PPC64_V15:
1731    return "v15";
1732  case UNW_PPC64_V16:
1733    return "v16";
1734  case UNW_PPC64_V17:
1735    return "v17";
1736  case UNW_PPC64_V18:
1737    return "v18";
1738  case UNW_PPC64_V19:
1739    return "v19";
1740  case UNW_PPC64_V20:
1741    return "v20";
1742  case UNW_PPC64_V21:
1743    return "v21";
1744  case UNW_PPC64_V22:
1745    return "v22";
1746  case UNW_PPC64_V23:
1747    return "v23";
1748  case UNW_PPC64_V24:
1749    return "v24";
1750  case UNW_PPC64_V25:
1751    return "v25";
1752  case UNW_PPC64_V26:
1753    return "v26";
1754  case UNW_PPC64_V27:
1755    return "v27";
1756  case UNW_PPC64_V28:
1757    return "v28";
1758  case UNW_PPC64_V29:
1759    return "v29";
1760  case UNW_PPC64_V30:
1761    return "v30";
1762  case UNW_PPC64_V31:
1763    return "v31";
1764  }
1765  return "unknown register";
1766}
1767#endif // _LIBUNWIND_TARGET_PPC64
1768
1769
1770#if defined(_LIBUNWIND_TARGET_AARCH64)
1771/// Registers_arm64  holds the register state of a thread in a 64-bit arm
1772/// process.
1773class _LIBUNWIND_HIDDEN Registers_arm64 {
1774public:
1775  Registers_arm64();
1776  Registers_arm64(const void *registers);
1777
1778  bool        validRegister(int num) const;
1779  uint64_t    getRegister(int num) const;
1780  void        setRegister(int num, uint64_t value);
1781  bool        validFloatRegister(int num) const;
1782  double      getFloatRegister(int num) const;
1783  void        setFloatRegister(int num, double value);
1784  bool        validVectorRegister(int num) const;
1785  v128        getVectorRegister(int num) const;
1786  void        setVectorRegister(int num, v128 value);
1787  static const char *getRegisterName(int num);
1788  void        jumpto();
1789  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
1790  static int  getArch() { return REGISTERS_ARM64; }
1791
1792  uint64_t  getSP() const         { return _registers.__sp; }
1793  void      setSP(uint64_t value) { _registers.__sp = value; }
1794  uint64_t  getIP() const         { return _registers.__pc; }
1795  void      setIP(uint64_t value) { _registers.__pc = value; }
1796  uint64_t  getFP() const         { return _registers.__fp; }
1797  void      setFP(uint64_t value) { _registers.__fp = value; }
1798
1799private:
1800  struct GPRs {
1801    uint64_t __x[29]; // x0-x28
1802    uint64_t __fp;    // Frame pointer x29
1803    uint64_t __lr;    // Link register x30
1804    uint64_t __sp;    // Stack pointer x31
1805    uint64_t __pc;    // Program counter
1806    uint64_t __ra_sign_state; // RA sign state register
1807  };
1808
1809  GPRs    _registers;
1810  double  _vectorHalfRegisters[32];
1811  // Currently only the lower double in 128-bit vectore registers
1812  // is perserved during unwinding.  We could define new register
1813  // numbers (> 96) which mean whole vector registers, then this
1814  // struct would need to change to contain whole vector registers.
1815};
1816
1817inline Registers_arm64::Registers_arm64(const void *registers) {
1818  static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
1819                "arm64 registers do not fit into unw_context_t");
1820  memcpy(&_registers, registers, sizeof(_registers));
1821  static_assert(sizeof(GPRs) == 0x110,
1822                "expected VFP registers to be at offset 272");
1823  memcpy(_vectorHalfRegisters,
1824         static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1825         sizeof(_vectorHalfRegisters));
1826}
1827
1828inline Registers_arm64::Registers_arm64() {
1829  memset(&_registers, 0, sizeof(_registers));
1830  memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1831}
1832
1833inline bool Registers_arm64::validRegister(int regNum) const {
1834  if (regNum == UNW_REG_IP)
1835    return true;
1836  if (regNum == UNW_REG_SP)
1837    return true;
1838  if (regNum < 0)
1839    return false;
1840  if (regNum > 95)
1841    return false;
1842  if (regNum == UNW_ARM64_RA_SIGN_STATE)
1843    return true;
1844  if ((regNum > 31) && (regNum < 64))
1845    return false;
1846  return true;
1847}
1848
1849inline uint64_t Registers_arm64::getRegister(int regNum) const {
1850  if (regNum == UNW_REG_IP)
1851    return _registers.__pc;
1852  if (regNum == UNW_REG_SP)
1853    return _registers.__sp;
1854  if (regNum == UNW_ARM64_RA_SIGN_STATE)
1855    return _registers.__ra_sign_state;
1856  if ((regNum >= 0) && (regNum < 32))
1857    return _registers.__x[regNum];
1858  _LIBUNWIND_ABORT("unsupported arm64 register");
1859}
1860
1861inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1862  if (regNum == UNW_REG_IP)
1863    _registers.__pc = value;
1864  else if (regNum == UNW_REG_SP)
1865    _registers.__sp = value;
1866  else if (regNum == UNW_ARM64_RA_SIGN_STATE)
1867    _registers.__ra_sign_state = value;
1868  else if ((regNum >= 0) && (regNum < 32))
1869    _registers.__x[regNum] = value;
1870  else
1871    _LIBUNWIND_ABORT("unsupported arm64 register");
1872}
1873
1874inline const char *Registers_arm64::getRegisterName(int regNum) {
1875  switch (regNum) {
1876  case UNW_REG_IP:
1877    return "pc";
1878  case UNW_REG_SP:
1879    return "sp";
1880  case UNW_ARM64_X0:
1881    return "x0";
1882  case UNW_ARM64_X1:
1883    return "x1";
1884  case UNW_ARM64_X2:
1885    return "x2";
1886  case UNW_ARM64_X3:
1887    return "x3";
1888  case UNW_ARM64_X4:
1889    return "x4";
1890  case UNW_ARM64_X5:
1891    return "x5";
1892  case UNW_ARM64_X6:
1893    return "x6";
1894  case UNW_ARM64_X7:
1895    return "x7";
1896  case UNW_ARM64_X8:
1897    return "x8";
1898  case UNW_ARM64_X9:
1899    return "x9";
1900  case UNW_ARM64_X10:
1901    return "x10";
1902  case UNW_ARM64_X11:
1903    return "x11";
1904  case UNW_ARM64_X12:
1905    return "x12";
1906  case UNW_ARM64_X13:
1907    return "x13";
1908  case UNW_ARM64_X14:
1909    return "x14";
1910  case UNW_ARM64_X15:
1911    return "x15";
1912  case UNW_ARM64_X16:
1913    return "x16";
1914  case UNW_ARM64_X17:
1915    return "x17";
1916  case UNW_ARM64_X18:
1917    return "x18";
1918  case UNW_ARM64_X19:
1919    return "x19";
1920  case UNW_ARM64_X20:
1921    return "x20";
1922  case UNW_ARM64_X21:
1923    return "x21";
1924  case UNW_ARM64_X22:
1925    return "x22";
1926  case UNW_ARM64_X23:
1927    return "x23";
1928  case UNW_ARM64_X24:
1929    return "x24";
1930  case UNW_ARM64_X25:
1931    return "x25";
1932  case UNW_ARM64_X26:
1933    return "x26";
1934  case UNW_ARM64_X27:
1935    return "x27";
1936  case UNW_ARM64_X28:
1937    return "x28";
1938  case UNW_ARM64_X29:
1939    return "fp";
1940  case UNW_ARM64_X30:
1941    return "lr";
1942  case UNW_ARM64_X31:
1943    return "sp";
1944  case UNW_ARM64_D0:
1945    return "d0";
1946  case UNW_ARM64_D1:
1947    return "d1";
1948  case UNW_ARM64_D2:
1949    return "d2";
1950  case UNW_ARM64_D3:
1951    return "d3";
1952  case UNW_ARM64_D4:
1953    return "d4";
1954  case UNW_ARM64_D5:
1955    return "d5";
1956  case UNW_ARM64_D6:
1957    return "d6";
1958  case UNW_ARM64_D7:
1959    return "d7";
1960  case UNW_ARM64_D8:
1961    return "d8";
1962  case UNW_ARM64_D9:
1963    return "d9";
1964  case UNW_ARM64_D10:
1965    return "d10";
1966  case UNW_ARM64_D11:
1967    return "d11";
1968  case UNW_ARM64_D12:
1969    return "d12";
1970  case UNW_ARM64_D13:
1971    return "d13";
1972  case UNW_ARM64_D14:
1973    return "d14";
1974  case UNW_ARM64_D15:
1975    return "d15";
1976  case UNW_ARM64_D16:
1977    return "d16";
1978  case UNW_ARM64_D17:
1979    return "d17";
1980  case UNW_ARM64_D18:
1981    return "d18";
1982  case UNW_ARM64_D19:
1983    return "d19";
1984  case UNW_ARM64_D20:
1985    return "d20";
1986  case UNW_ARM64_D21:
1987    return "d21";
1988  case UNW_ARM64_D22:
1989    return "d22";
1990  case UNW_ARM64_D23:
1991    return "d23";
1992  case UNW_ARM64_D24:
1993    return "d24";
1994  case UNW_ARM64_D25:
1995    return "d25";
1996  case UNW_ARM64_D26:
1997    return "d26";
1998  case UNW_ARM64_D27:
1999    return "d27";
2000  case UNW_ARM64_D28:
2001    return "d28";
2002  case UNW_ARM64_D29:
2003    return "d29";
2004  case UNW_ARM64_D30:
2005    return "d30";
2006  case UNW_ARM64_D31:
2007    return "d31";
2008  default:
2009    return "unknown register";
2010  }
2011}
2012
2013inline bool Registers_arm64::validFloatRegister(int regNum) const {
2014  if (regNum < UNW_ARM64_D0)
2015    return false;
2016  if (regNum > UNW_ARM64_D31)
2017    return false;
2018  return true;
2019}
2020
2021inline double Registers_arm64::getFloatRegister(int regNum) const {
2022  assert(validFloatRegister(regNum));
2023  return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
2024}
2025
2026inline void Registers_arm64::setFloatRegister(int regNum, double value) {
2027  assert(validFloatRegister(regNum));
2028  _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
2029}
2030
2031inline bool Registers_arm64::validVectorRegister(int) const {
2032  return false;
2033}
2034
2035inline v128 Registers_arm64::getVectorRegister(int) const {
2036  _LIBUNWIND_ABORT("no arm64 vector register support yet");
2037}
2038
2039inline void Registers_arm64::setVectorRegister(int, v128) {
2040  _LIBUNWIND_ABORT("no arm64 vector register support yet");
2041}
2042#endif // _LIBUNWIND_TARGET_AARCH64
2043
2044#if defined(_LIBUNWIND_TARGET_ARM)
2045/// Registers_arm holds the register state of a thread in a 32-bit arm
2046/// process.
2047///
2048/// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
2049/// this uses more memory than required.
2050class _LIBUNWIND_HIDDEN Registers_arm {
2051public:
2052  Registers_arm();
2053  Registers_arm(const void *registers);
2054
2055  bool        validRegister(int num) const;
2056  uint32_t    getRegister(int num) const;
2057  void        setRegister(int num, uint32_t value);
2058  bool        validFloatRegister(int num) const;
2059  unw_fpreg_t getFloatRegister(int num);
2060  void        setFloatRegister(int num, unw_fpreg_t value);
2061  bool        validVectorRegister(int num) const;
2062  v128        getVectorRegister(int num) const;
2063  void        setVectorRegister(int num, v128 value);
2064  static const char *getRegisterName(int num);
2065  void        jumpto() {
2066    restoreSavedFloatRegisters();
2067    restoreCoreAndJumpTo();
2068  }
2069  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; }
2070  static int  getArch() { return REGISTERS_ARM; }
2071
2072  uint32_t  getSP() const         { return _registers.__sp; }
2073  void      setSP(uint32_t value) { _registers.__sp = value; }
2074  uint32_t  getIP() const         { return _registers.__pc; }
2075  void      setIP(uint32_t value) { _registers.__pc = value; }
2076
2077  void saveVFPAsX() {
2078    assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
2079    _use_X_for_vfp_save = true;
2080  }
2081
2082  void restoreSavedFloatRegisters() {
2083    if (_saved_vfp_d0_d15) {
2084      if (_use_X_for_vfp_save)
2085        restoreVFPWithFLDMX(_vfp_d0_d15_pad);
2086      else
2087        restoreVFPWithFLDMD(_vfp_d0_d15_pad);
2088    }
2089    if (_saved_vfp_d16_d31)
2090      restoreVFPv3(_vfp_d16_d31);
2091#if defined(__ARM_WMMX)
2092    if (_saved_iwmmx)
2093      restoreiWMMX(_iwmmx);
2094    if (_saved_iwmmx_control)
2095      restoreiWMMXControl(_iwmmx_control);
2096#endif
2097  }
2098
2099private:
2100  struct GPRs {
2101    uint32_t __r[13]; // r0-r12
2102    uint32_t __sp;    // Stack pointer r13
2103    uint32_t __lr;    // Link register r14
2104    uint32_t __pc;    // Program counter r15
2105  };
2106
2107  static void saveVFPWithFSTMD(void*);
2108  static void saveVFPWithFSTMX(void*);
2109  static void saveVFPv3(void*);
2110  static void restoreVFPWithFLDMD(void*);
2111  static void restoreVFPWithFLDMX(void*);
2112  static void restoreVFPv3(void*);
2113#if defined(__ARM_WMMX)
2114  static void saveiWMMX(void*);
2115  static void saveiWMMXControl(uint32_t*);
2116  static void restoreiWMMX(void*);
2117  static void restoreiWMMXControl(uint32_t*);
2118#endif
2119  void restoreCoreAndJumpTo();
2120
2121  // ARM registers
2122  GPRs _registers;
2123
2124  // We save floating point registers lazily because we can't know ahead of
2125  // time which ones are used. See EHABI #4.7.
2126
2127  // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
2128  //
2129  // See EHABI #7.5 that explains how matching instruction sequences for load
2130  // and store need to be used to correctly restore the exact register bits.
2131  bool _use_X_for_vfp_save;
2132  // Whether VFP D0-D15 are saved.
2133  bool _saved_vfp_d0_d15;
2134  // Whether VFPv3 D16-D31 are saved.
2135  bool _saved_vfp_d16_d31;
2136  // VFP registers D0-D15, + padding if saved using FSTMX
2137  unw_fpreg_t _vfp_d0_d15_pad[17];
2138  // VFPv3 registers D16-D31, always saved using FSTMD
2139  unw_fpreg_t _vfp_d16_d31[16];
2140#if defined(__ARM_WMMX)
2141  // Whether iWMMX data registers are saved.
2142  bool _saved_iwmmx;
2143  // Whether iWMMX control registers are saved.
2144  mutable bool _saved_iwmmx_control;
2145  // iWMMX registers
2146  unw_fpreg_t _iwmmx[16];
2147  // iWMMX control registers
2148  mutable uint32_t _iwmmx_control[4];
2149#endif
2150};
2151
2152inline Registers_arm::Registers_arm(const void *registers)
2153  : _use_X_for_vfp_save(false),
2154    _saved_vfp_d0_d15(false),
2155    _saved_vfp_d16_d31(false) {
2156  static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
2157                "arm registers do not fit into unw_context_t");
2158  // See __unw_getcontext() note about data.
2159  memcpy(&_registers, registers, sizeof(_registers));
2160  memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2161  memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2162#if defined(__ARM_WMMX)
2163  _saved_iwmmx = false;
2164  _saved_iwmmx_control = false;
2165  memset(&_iwmmx, 0, sizeof(_iwmmx));
2166  memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2167#endif
2168}
2169
2170inline Registers_arm::Registers_arm()
2171  : _use_X_for_vfp_save(false),
2172    _saved_vfp_d0_d15(false),
2173    _saved_vfp_d16_d31(false) {
2174  memset(&_registers, 0, sizeof(_registers));
2175  memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2176  memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2177#if defined(__ARM_WMMX)
2178  _saved_iwmmx = false;
2179  _saved_iwmmx_control = false;
2180  memset(&_iwmmx, 0, sizeof(_iwmmx));
2181  memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2182#endif
2183}
2184
2185inline bool Registers_arm::validRegister(int regNum) const {
2186  // Returns true for all non-VFP registers supported by the EHABI
2187  // virtual register set (VRS).
2188  if (regNum == UNW_REG_IP)
2189    return true;
2190
2191  if (regNum == UNW_REG_SP)
2192    return true;
2193
2194  if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
2195    return true;
2196
2197#if defined(__ARM_WMMX)
2198  if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
2199    return true;
2200#endif
2201
2202  return false;
2203}
2204
2205inline uint32_t Registers_arm::getRegister(int regNum) const {
2206  if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
2207    return _registers.__sp;
2208
2209  if (regNum == UNW_ARM_LR)
2210    return _registers.__lr;
2211
2212  if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
2213    return _registers.__pc;
2214
2215  if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
2216    return _registers.__r[regNum];
2217
2218#if defined(__ARM_WMMX)
2219  if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2220    if (!_saved_iwmmx_control) {
2221      _saved_iwmmx_control = true;
2222      saveiWMMXControl(_iwmmx_control);
2223    }
2224    return _iwmmx_control[regNum - UNW_ARM_WC0];
2225  }
2226#endif
2227
2228  _LIBUNWIND_ABORT("unsupported arm register");
2229}
2230
2231inline void Registers_arm::setRegister(int regNum, uint32_t value) {
2232  if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
2233    _registers.__sp = value;
2234    return;
2235  }
2236
2237  if (regNum == UNW_ARM_LR) {
2238    _registers.__lr = value;
2239    return;
2240  }
2241
2242  if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
2243    _registers.__pc = value;
2244    return;
2245  }
2246
2247  if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
2248    _registers.__r[regNum] = value;
2249    return;
2250  }
2251
2252#if defined(__ARM_WMMX)
2253  if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2254    if (!_saved_iwmmx_control) {
2255      _saved_iwmmx_control = true;
2256      saveiWMMXControl(_iwmmx_control);
2257    }
2258    _iwmmx_control[regNum - UNW_ARM_WC0] = value;
2259    return;
2260  }
2261#endif
2262
2263  _LIBUNWIND_ABORT("unsupported arm register");
2264}
2265
2266inline const char *Registers_arm::getRegisterName(int regNum) {
2267  switch (regNum) {
2268  case UNW_REG_IP:
2269  case UNW_ARM_IP: // UNW_ARM_R15 is alias
2270    return "pc";
2271  case UNW_ARM_LR: // UNW_ARM_R14 is alias
2272    return "lr";
2273  case UNW_REG_SP:
2274  case UNW_ARM_SP: // UNW_ARM_R13 is alias
2275    return "sp";
2276  case UNW_ARM_R0:
2277    return "r0";
2278  case UNW_ARM_R1:
2279    return "r1";
2280  case UNW_ARM_R2:
2281    return "r2";
2282  case UNW_ARM_R3:
2283    return "r3";
2284  case UNW_ARM_R4:
2285    return "r4";
2286  case UNW_ARM_R5:
2287    return "r5";
2288  case UNW_ARM_R6:
2289    return "r6";
2290  case UNW_ARM_R7:
2291    return "r7";
2292  case UNW_ARM_R8:
2293    return "r8";
2294  case UNW_ARM_R9:
2295    return "r9";
2296  case UNW_ARM_R10:
2297    return "r10";
2298  case UNW_ARM_R11:
2299    return "r11";
2300  case UNW_ARM_R12:
2301    return "r12";
2302  case UNW_ARM_S0:
2303    return "s0";
2304  case UNW_ARM_S1:
2305    return "s1";
2306  case UNW_ARM_S2:
2307    return "s2";
2308  case UNW_ARM_S3:
2309    return "s3";
2310  case UNW_ARM_S4:
2311    return "s4";
2312  case UNW_ARM_S5:
2313    return "s5";
2314  case UNW_ARM_S6:
2315    return "s6";
2316  case UNW_ARM_S7:
2317    return "s7";
2318  case UNW_ARM_S8:
2319    return "s8";
2320  case UNW_ARM_S9:
2321    return "s9";
2322  case UNW_ARM_S10:
2323    return "s10";
2324  case UNW_ARM_S11:
2325    return "s11";
2326  case UNW_ARM_S12:
2327    return "s12";
2328  case UNW_ARM_S13:
2329    return "s13";
2330  case UNW_ARM_S14:
2331    return "s14";
2332  case UNW_ARM_S15:
2333    return "s15";
2334  case UNW_ARM_S16:
2335    return "s16";
2336  case UNW_ARM_S17:
2337    return "s17";
2338  case UNW_ARM_S18:
2339    return "s18";
2340  case UNW_ARM_S19:
2341    return "s19";
2342  case UNW_ARM_S20:
2343    return "s20";
2344  case UNW_ARM_S21:
2345    return "s21";
2346  case UNW_ARM_S22:
2347    return "s22";
2348  case UNW_ARM_S23:
2349    return "s23";
2350  case UNW_ARM_S24:
2351    return "s24";
2352  case UNW_ARM_S25:
2353    return "s25";
2354  case UNW_ARM_S26:
2355    return "s26";
2356  case UNW_ARM_S27:
2357    return "s27";
2358  case UNW_ARM_S28:
2359    return "s28";
2360  case UNW_ARM_S29:
2361    return "s29";
2362  case UNW_ARM_S30:
2363    return "s30";
2364  case UNW_ARM_S31:
2365    return "s31";
2366  case UNW_ARM_D0:
2367    return "d0";
2368  case UNW_ARM_D1:
2369    return "d1";
2370  case UNW_ARM_D2:
2371    return "d2";
2372  case UNW_ARM_D3:
2373    return "d3";
2374  case UNW_ARM_D4:
2375    return "d4";
2376  case UNW_ARM_D5:
2377    return "d5";
2378  case UNW_ARM_D6:
2379    return "d6";
2380  case UNW_ARM_D7:
2381    return "d7";
2382  case UNW_ARM_D8:
2383    return "d8";
2384  case UNW_ARM_D9:
2385    return "d9";
2386  case UNW_ARM_D10:
2387    return "d10";
2388  case UNW_ARM_D11:
2389    return "d11";
2390  case UNW_ARM_D12:
2391    return "d12";
2392  case UNW_ARM_D13:
2393    return "d13";
2394  case UNW_ARM_D14:
2395    return "d14";
2396  case UNW_ARM_D15:
2397    return "d15";
2398  case UNW_ARM_D16:
2399    return "d16";
2400  case UNW_ARM_D17:
2401    return "d17";
2402  case UNW_ARM_D18:
2403    return "d18";
2404  case UNW_ARM_D19:
2405    return "d19";
2406  case UNW_ARM_D20:
2407    return "d20";
2408  case UNW_ARM_D21:
2409    return "d21";
2410  case UNW_ARM_D22:
2411    return "d22";
2412  case UNW_ARM_D23:
2413    return "d23";
2414  case UNW_ARM_D24:
2415    return "d24";
2416  case UNW_ARM_D25:
2417    return "d25";
2418  case UNW_ARM_D26:
2419    return "d26";
2420  case UNW_ARM_D27:
2421    return "d27";
2422  case UNW_ARM_D28:
2423    return "d28";
2424  case UNW_ARM_D29:
2425    return "d29";
2426  case UNW_ARM_D30:
2427    return "d30";
2428  case UNW_ARM_D31:
2429    return "d31";
2430  default:
2431    return "unknown register";
2432  }
2433}
2434
2435inline bool Registers_arm::validFloatRegister(int regNum) const {
2436  // NOTE: Consider the intel MMX registers floating points so the
2437  // __unw_get_fpreg can be used to transmit the 64-bit data back.
2438  return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
2439#if defined(__ARM_WMMX)
2440      || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
2441#endif
2442      ;
2443}
2444
2445inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
2446  if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2447    if (!_saved_vfp_d0_d15) {
2448      _saved_vfp_d0_d15 = true;
2449      if (_use_X_for_vfp_save)
2450        saveVFPWithFSTMX(_vfp_d0_d15_pad);
2451      else
2452        saveVFPWithFSTMD(_vfp_d0_d15_pad);
2453    }
2454    return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
2455  }
2456
2457  if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2458    if (!_saved_vfp_d16_d31) {
2459      _saved_vfp_d16_d31 = true;
2460      saveVFPv3(_vfp_d16_d31);
2461    }
2462    return _vfp_d16_d31[regNum - UNW_ARM_D16];
2463  }
2464
2465#if defined(__ARM_WMMX)
2466  if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2467    if (!_saved_iwmmx) {
2468      _saved_iwmmx = true;
2469      saveiWMMX(_iwmmx);
2470    }
2471    return _iwmmx[regNum - UNW_ARM_WR0];
2472  }
2473#endif
2474
2475  _LIBUNWIND_ABORT("Unknown ARM float register");
2476}
2477
2478inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
2479  if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2480    if (!_saved_vfp_d0_d15) {
2481      _saved_vfp_d0_d15 = true;
2482      if (_use_X_for_vfp_save)
2483        saveVFPWithFSTMX(_vfp_d0_d15_pad);
2484      else
2485        saveVFPWithFSTMD(_vfp_d0_d15_pad);
2486    }
2487    _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
2488    return;
2489  }
2490
2491  if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2492    if (!_saved_vfp_d16_d31) {
2493      _saved_vfp_d16_d31 = true;
2494      saveVFPv3(_vfp_d16_d31);
2495    }
2496    _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
2497    return;
2498  }
2499
2500#if defined(__ARM_WMMX)
2501  if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2502    if (!_saved_iwmmx) {
2503      _saved_iwmmx = true;
2504      saveiWMMX(_iwmmx);
2505    }
2506    _iwmmx[regNum - UNW_ARM_WR0] = value;
2507    return;
2508  }
2509#endif
2510
2511  _LIBUNWIND_ABORT("Unknown ARM float register");
2512}
2513
2514inline bool Registers_arm::validVectorRegister(int) const {
2515  return false;
2516}
2517
2518inline v128 Registers_arm::getVectorRegister(int) const {
2519  _LIBUNWIND_ABORT("ARM vector support not implemented");
2520}
2521
2522inline void Registers_arm::setVectorRegister(int, v128) {
2523  _LIBUNWIND_ABORT("ARM vector support not implemented");
2524}
2525#endif // _LIBUNWIND_TARGET_ARM
2526
2527
2528#if defined(_LIBUNWIND_TARGET_OR1K)
2529/// Registers_or1k holds the register state of a thread in an OpenRISC1000
2530/// process.
2531class _LIBUNWIND_HIDDEN Registers_or1k {
2532public:
2533  Registers_or1k();
2534  Registers_or1k(const void *registers);
2535
2536  bool        validRegister(int num) const;
2537  uint32_t    getRegister(int num) const;
2538  void        setRegister(int num, uint32_t value);
2539  bool        validFloatRegister(int num) const;
2540  double      getFloatRegister(int num) const;
2541  void        setFloatRegister(int num, double value);
2542  bool        validVectorRegister(int num) const;
2543  v128        getVectorRegister(int num) const;
2544  void        setVectorRegister(int num, v128 value);
2545  static const char *getRegisterName(int num);
2546  void        jumpto();
2547  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; }
2548  static int  getArch() { return REGISTERS_OR1K; }
2549
2550  uint64_t  getSP() const         { return _registers.__r[1]; }
2551  void      setSP(uint32_t value) { _registers.__r[1] = value; }
2552  uint64_t  getIP() const         { return _registers.__pc; }
2553  void      setIP(uint32_t value) { _registers.__pc = value; }
2554
2555private:
2556  struct or1k_thread_state_t {
2557    unsigned int __r[32]; // r0-r31
2558    unsigned int __pc;    // Program counter
2559    unsigned int __epcr;  // Program counter at exception
2560  };
2561
2562  or1k_thread_state_t _registers;
2563};
2564
2565inline Registers_or1k::Registers_or1k(const void *registers) {
2566  static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
2567                "or1k registers do not fit into unw_context_t");
2568  memcpy(&_registers, static_cast<const uint8_t *>(registers),
2569         sizeof(_registers));
2570}
2571
2572inline Registers_or1k::Registers_or1k() {
2573  memset(&_registers, 0, sizeof(_registers));
2574}
2575
2576inline bool Registers_or1k::validRegister(int regNum) const {
2577  if (regNum == UNW_REG_IP)
2578    return true;
2579  if (regNum == UNW_REG_SP)
2580    return true;
2581  if (regNum < 0)
2582    return false;
2583  if (regNum <= UNW_OR1K_R31)
2584    return true;
2585  if (regNum == UNW_OR1K_EPCR)
2586    return true;
2587  return false;
2588}
2589
2590inline uint32_t Registers_or1k::getRegister(int regNum) const {
2591  if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
2592    return _registers.__r[regNum - UNW_OR1K_R0];
2593
2594  switch (regNum) {
2595  case UNW_REG_IP:
2596    return _registers.__pc;
2597  case UNW_REG_SP:
2598    return _registers.__r[1];
2599  case UNW_OR1K_EPCR:
2600    return _registers.__epcr;
2601  }
2602  _LIBUNWIND_ABORT("unsupported or1k register");
2603}
2604
2605inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
2606  if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
2607    _registers.__r[regNum - UNW_OR1K_R0] = value;
2608    return;
2609  }
2610
2611  switch (regNum) {
2612  case UNW_REG_IP:
2613    _registers.__pc = value;
2614    return;
2615  case UNW_REG_SP:
2616    _registers.__r[1] = value;
2617    return;
2618  case UNW_OR1K_EPCR:
2619    _registers.__epcr = value;
2620    return;
2621  }
2622  _LIBUNWIND_ABORT("unsupported or1k register");
2623}
2624
2625inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
2626  return false;
2627}
2628
2629inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
2630  _LIBUNWIND_ABORT("or1k float support not implemented");
2631}
2632
2633inline void Registers_or1k::setFloatRegister(int /* regNum */,
2634                                             double /* value */) {
2635  _LIBUNWIND_ABORT("or1k float support not implemented");
2636}
2637
2638inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
2639  return false;
2640}
2641
2642inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
2643  _LIBUNWIND_ABORT("or1k vector support not implemented");
2644}
2645
2646inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
2647  _LIBUNWIND_ABORT("or1k vector support not implemented");
2648}
2649
2650inline const char *Registers_or1k::getRegisterName(int regNum) {
2651  switch (regNum) {
2652  case UNW_OR1K_R0:
2653    return "r0";
2654  case UNW_OR1K_R1:
2655    return "r1";
2656  case UNW_OR1K_R2:
2657    return "r2";
2658  case UNW_OR1K_R3:
2659    return "r3";
2660  case UNW_OR1K_R4:
2661    return "r4";
2662  case UNW_OR1K_R5:
2663    return "r5";
2664  case UNW_OR1K_R6:
2665    return "r6";
2666  case UNW_OR1K_R7:
2667    return "r7";
2668  case UNW_OR1K_R8:
2669    return "r8";
2670  case UNW_OR1K_R9:
2671    return "r9";
2672  case UNW_OR1K_R10:
2673    return "r10";
2674  case UNW_OR1K_R11:
2675    return "r11";
2676  case UNW_OR1K_R12:
2677    return "r12";
2678  case UNW_OR1K_R13:
2679    return "r13";
2680  case UNW_OR1K_R14:
2681    return "r14";
2682  case UNW_OR1K_R15:
2683    return "r15";
2684  case UNW_OR1K_R16:
2685    return "r16";
2686  case UNW_OR1K_R17:
2687    return "r17";
2688  case UNW_OR1K_R18:
2689    return "r18";
2690  case UNW_OR1K_R19:
2691    return "r19";
2692  case UNW_OR1K_R20:
2693    return "r20";
2694  case UNW_OR1K_R21:
2695    return "r21";
2696  case UNW_OR1K_R22:
2697    return "r22";
2698  case UNW_OR1K_R23:
2699    return "r23";
2700  case UNW_OR1K_R24:
2701    return "r24";
2702  case UNW_OR1K_R25:
2703    return "r25";
2704  case UNW_OR1K_R26:
2705    return "r26";
2706  case UNW_OR1K_R27:
2707    return "r27";
2708  case UNW_OR1K_R28:
2709    return "r28";
2710  case UNW_OR1K_R29:
2711    return "r29";
2712  case UNW_OR1K_R30:
2713    return "r30";
2714  case UNW_OR1K_R31:
2715    return "r31";
2716  case UNW_OR1K_EPCR:
2717    return "EPCR";
2718  default:
2719    return "unknown register";
2720  }
2721
2722}
2723#endif // _LIBUNWIND_TARGET_OR1K
2724
2725#if defined(_LIBUNWIND_TARGET_RISCV)
2726/// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
2727/// process.
2728class _LIBUNWIND_HIDDEN Registers_riscv {
2729public:
2730  Registers_riscv();
2731  Registers_riscv(const void *registers);
2732
2733  bool        validRegister(int num) const;
2734  uint64_t    getRegister(int num) const;
2735  void        setRegister(int num, uint64_t value);
2736  bool        validFloatRegister(int num) const;
2737  double      getFloatRegister(int num) const;
2738  void        setFloatRegister(int num, double value);
2739  bool        validVectorRegister(int num) const;
2740  v128        getVectorRegister(int num) const;
2741  void        setVectorRegister(int num, v128 value);
2742  static const char *getRegisterName(int num);
2743  void        jumpto();
2744  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
2745  static int  getArch() { return REGISTERS_RISCV; }
2746
2747  uint64_t  getSP() const         { return _registers.__x[2]; }
2748  void      setSP(uint64_t value) { _registers.__x[2] = value; }
2749  uint64_t  getIP() const         { return _registers.__x[1]; }
2750  void      setIP(uint64_t value) { _registers.__x[1] = value; }
2751
2752private:
2753  struct GPRs {
2754    uint64_t __x[32]; // x0-x31
2755  };
2756
2757  GPRs    _registers;
2758  double  _vectorHalfRegisters[32];
2759  // Currently only the lower double in 128-bit vectore registers
2760  // is perserved during unwinding.  We could define new register
2761  // numbers (> 96) which mean whole vector registers, then this
2762  // struct would need to change to contain whole vector registers.
2763};
2764
2765inline Registers_riscv::Registers_riscv(const void *registers) {
2766  static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
2767                "riscv registers do not fit into unw_context_t");
2768  memcpy(&_registers, registers, sizeof(_registers));
2769  static_assert(sizeof(GPRs) == 0x100,
2770                "expected VFP registers to be at offset 256");
2771  memcpy(_vectorHalfRegisters,
2772         static_cast<const uint8_t *>(registers) + sizeof(GPRs),
2773         sizeof(_vectorHalfRegisters));
2774}
2775
2776inline Registers_riscv::Registers_riscv() {
2777  memset(&_registers, 0, sizeof(_registers));
2778  memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
2779}
2780
2781inline bool Registers_riscv::validRegister(int regNum) const {
2782  if (regNum == UNW_REG_IP)
2783    return true;
2784  if (regNum == UNW_REG_SP)
2785    return true;
2786  if (regNum < 0)
2787    return false;
2788  if (regNum > 95)
2789    return false;
2790  if ((regNum > 31) && (regNum < 64))
2791    return false;
2792  return true;
2793}
2794
2795inline uint64_t Registers_riscv::getRegister(int regNum) const {
2796  if (regNum == UNW_REG_IP)
2797    return _registers.__x[1];
2798  if (regNum == UNW_REG_SP)
2799    return _registers.__x[2];
2800  if ((regNum >= 0) && (regNum < 32))
2801    return _registers.__x[regNum];
2802  _LIBUNWIND_ABORT("unsupported riscv register");
2803}
2804
2805inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
2806  if (regNum == UNW_REG_IP)
2807    _registers.__x[1] = value;
2808  else if (regNum == UNW_REG_SP)
2809    _registers.__x[2] = value;
2810  else if ((regNum >= 0) && (regNum < 32))
2811    _registers.__x[regNum] = value;
2812  else
2813    _LIBUNWIND_ABORT("unsupported riscv register");
2814}
2815
2816inline const char *Registers_riscv::getRegisterName(int regNum) {
2817  switch (regNum) {
2818  case UNW_REG_IP:
2819    return "ra";
2820  case UNW_REG_SP:
2821    return "sp";
2822  case UNW_RISCV_X0:
2823    return "x0";
2824  case UNW_RISCV_X1:
2825    return "ra";
2826  case UNW_RISCV_X2:
2827    return "sp";
2828  case UNW_RISCV_X3:
2829    return "x3";
2830  case UNW_RISCV_X4:
2831    return "x4";
2832  case UNW_RISCV_X5:
2833    return "x5";
2834  case UNW_RISCV_X6:
2835    return "x6";
2836  case UNW_RISCV_X7:
2837    return "x7";
2838  case UNW_RISCV_X8:
2839    return "x8";
2840  case UNW_RISCV_X9:
2841    return "x9";
2842  case UNW_RISCV_X10:
2843    return "x10";
2844  case UNW_RISCV_X11:
2845    return "x11";
2846  case UNW_RISCV_X12:
2847    return "x12";
2848  case UNW_RISCV_X13:
2849    return "x13";
2850  case UNW_RISCV_X14:
2851    return "x14";
2852  case UNW_RISCV_X15:
2853    return "x15";
2854  case UNW_RISCV_X16:
2855    return "x16";
2856  case UNW_RISCV_X17:
2857    return "x17";
2858  case UNW_RISCV_X18:
2859    return "x18";
2860  case UNW_RISCV_X19:
2861    return "x19";
2862  case UNW_RISCV_X20:
2863    return "x20";
2864  case UNW_RISCV_X21:
2865    return "x21";
2866  case UNW_RISCV_X22:
2867    return "x22";
2868  case UNW_RISCV_X23:
2869    return "x23";
2870  case UNW_RISCV_X24:
2871    return "x24";
2872  case UNW_RISCV_X25:
2873    return "x25";
2874  case UNW_RISCV_X26:
2875    return "x26";
2876  case UNW_RISCV_X27:
2877    return "x27";
2878  case UNW_RISCV_X28:
2879    return "x28";
2880  case UNW_RISCV_X29:
2881    return "x29";
2882  case UNW_RISCV_X30:
2883    return "x30";
2884  case UNW_RISCV_X31:
2885    return "x31";
2886  case UNW_RISCV_D0:
2887    return "d0";
2888  case UNW_RISCV_D1:
2889    return "d1";
2890  case UNW_RISCV_D2:
2891    return "d2";
2892  case UNW_RISCV_D3:
2893    return "d3";
2894  case UNW_RISCV_D4:
2895    return "d4";
2896  case UNW_RISCV_D5:
2897    return "d5";
2898  case UNW_RISCV_D6:
2899    return "d6";
2900  case UNW_RISCV_D7:
2901    return "d7";
2902  case UNW_RISCV_D8:
2903    return "d8";
2904  case UNW_RISCV_D9:
2905    return "d9";
2906  case UNW_RISCV_D10:
2907    return "d10";
2908  case UNW_RISCV_D11:
2909    return "d11";
2910  case UNW_RISCV_D12:
2911    return "d12";
2912  case UNW_RISCV_D13:
2913    return "d13";
2914  case UNW_RISCV_D14:
2915    return "d14";
2916  case UNW_RISCV_D15:
2917    return "d15";
2918  case UNW_RISCV_D16:
2919    return "d16";
2920  case UNW_RISCV_D17:
2921    return "d17";
2922  case UNW_RISCV_D18:
2923    return "d18";
2924  case UNW_RISCV_D19:
2925    return "d19";
2926  case UNW_RISCV_D20:
2927    return "d20";
2928  case UNW_RISCV_D21:
2929    return "d21";
2930  case UNW_RISCV_D22:
2931    return "d22";
2932  case UNW_RISCV_D23:
2933    return "d23";
2934  case UNW_RISCV_D24:
2935    return "d24";
2936  case UNW_RISCV_D25:
2937    return "d25";
2938  case UNW_RISCV_D26:
2939    return "d26";
2940  case UNW_RISCV_D27:
2941    return "d27";
2942  case UNW_RISCV_D28:
2943    return "d28";
2944  case UNW_RISCV_D29:
2945    return "d29";
2946  case UNW_RISCV_D30:
2947    return "d30";
2948  case UNW_RISCV_D31:
2949    return "d31";
2950  default:
2951    return "unknown register";
2952  }
2953}
2954
2955inline bool Registers_riscv::validFloatRegister(int regNum) const {
2956  if (regNum < UNW_RISCV_D0)
2957    return false;
2958  if (regNum > UNW_RISCV_D31)
2959    return false;
2960  return true;
2961}
2962
2963inline double Registers_riscv::getFloatRegister(int regNum) const {
2964  assert(validFloatRegister(regNum));
2965  return _vectorHalfRegisters[regNum - UNW_RISCV_D0];
2966}
2967
2968inline void Registers_riscv::setFloatRegister(int regNum, double value) {
2969  assert(validFloatRegister(regNum));
2970  _vectorHalfRegisters[regNum - UNW_RISCV_D0] = value;
2971}
2972
2973inline bool Registers_riscv::validVectorRegister(int) const {
2974  return false;
2975}
2976
2977inline v128 Registers_riscv::getVectorRegister(int) const {
2978  _LIBUNWIND_ABORT("no riscv vector register support yet");
2979}
2980
2981inline void Registers_riscv::setVectorRegister(int, v128) {
2982  _LIBUNWIND_ABORT("no riscv vector register support yet");
2983}
2984#endif // _LIBUNWIND_TARGET_RISCV
2985
2986#if defined(_LIBUNWIND_TARGET_MIPS_O32)
2987/// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
2988/// process.
2989class _LIBUNWIND_HIDDEN Registers_mips_o32 {
2990public:
2991  Registers_mips_o32();
2992  Registers_mips_o32(const void *registers);
2993
2994  bool        validRegister(int num) const;
2995  uint32_t    getRegister(int num) const;
2996  void        setRegister(int num, uint32_t value);
2997  bool        validFloatRegister(int num) const;
2998  double      getFloatRegister(int num) const;
2999  void        setFloatRegister(int num, double value);
3000  bool        validVectorRegister(int num) const;
3001  v128        getVectorRegister(int num) const;
3002  void        setVectorRegister(int num, v128 value);
3003  static const char *getRegisterName(int num);
3004  void        jumpto();
3005  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
3006  static int  getArch() { return REGISTERS_MIPS_O32; }
3007
3008  uint32_t  getSP() const         { return _registers.__r[29]; }
3009  void      setSP(uint32_t value) { _registers.__r[29] = value; }
3010  uint32_t  getIP() const         { return _registers.__pc; }
3011  void      setIP(uint32_t value) { _registers.__pc = value; }
3012
3013private:
3014  struct mips_o32_thread_state_t {
3015    uint32_t __r[32];
3016    uint32_t __pc;
3017    uint32_t __hi;
3018    uint32_t __lo;
3019  };
3020
3021  mips_o32_thread_state_t _registers;
3022#ifdef __mips_hard_float
3023  /// O32 with 32-bit floating point registers only uses half of this
3024  /// space.  However, using the same layout for 32-bit vs 64-bit
3025  /// floating point registers results in a single context size for
3026  /// O32 with hard float.
3027  uint32_t _padding;
3028  double _floats[32];
3029#endif
3030};
3031
3032inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
3033  static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
3034                "mips_o32 registers do not fit into unw_context_t");
3035  memcpy(&_registers, static_cast<const uint8_t *>(registers),
3036         sizeof(_registers));
3037}
3038
3039inline Registers_mips_o32::Registers_mips_o32() {
3040  memset(&_registers, 0, sizeof(_registers));
3041}
3042
3043inline bool Registers_mips_o32::validRegister(int regNum) const {
3044  if (regNum == UNW_REG_IP)
3045    return true;
3046  if (regNum == UNW_REG_SP)
3047    return true;
3048  if (regNum < 0)
3049    return false;
3050  if (regNum <= UNW_MIPS_R31)
3051    return true;
3052#if __mips_isa_rev != 6
3053  if (regNum == UNW_MIPS_HI)
3054    return true;
3055  if (regNum == UNW_MIPS_LO)
3056    return true;
3057#endif
3058#if defined(__mips_hard_float) && __mips_fpr == 32
3059  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3060    return true;
3061#endif
3062  // FIXME: DSP accumulator registers, MSA registers
3063  return false;
3064}
3065
3066inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
3067  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3068    return _registers.__r[regNum - UNW_MIPS_R0];
3069#if defined(__mips_hard_float) && __mips_fpr == 32
3070  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
3071    uint32_t *p;
3072
3073    if (regNum % 2 == 0)
3074      p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
3075    else
3076      p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
3077    return *p;
3078  }
3079#endif
3080
3081  switch (regNum) {
3082  case UNW_REG_IP:
3083    return _registers.__pc;
3084  case UNW_REG_SP:
3085    return _registers.__r[29];
3086  case UNW_MIPS_HI:
3087    return _registers.__hi;
3088  case UNW_MIPS_LO:
3089    return _registers.__lo;
3090  }
3091  _LIBUNWIND_ABORT("unsupported mips_o32 register");
3092}
3093
3094inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
3095  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3096    _registers.__r[regNum - UNW_MIPS_R0] = value;
3097    return;
3098  }
3099#if defined(__mips_hard_float) && __mips_fpr == 32
3100  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
3101    uint32_t *p;
3102
3103    if (regNum % 2 == 0)
3104      p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
3105    else
3106      p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
3107    *p = value;
3108    return;
3109  }
3110#endif
3111
3112  switch (regNum) {
3113  case UNW_REG_IP:
3114    _registers.__pc = value;
3115    return;
3116  case UNW_REG_SP:
3117    _registers.__r[29] = value;
3118    return;
3119  case UNW_MIPS_HI:
3120    _registers.__hi = value;
3121    return;
3122  case UNW_MIPS_LO:
3123    _registers.__lo = value;
3124    return;
3125  }
3126  _LIBUNWIND_ABORT("unsupported mips_o32 register");
3127}
3128
3129inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
3130#if defined(__mips_hard_float) && __mips_fpr == 64
3131  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3132    return true;
3133#endif
3134  return false;
3135}
3136
3137inline double Registers_mips_o32::getFloatRegister(int regNum) const {
3138#if defined(__mips_hard_float) && __mips_fpr == 64
3139  assert(validFloatRegister(regNum));
3140  return _floats[regNum - UNW_MIPS_F0];
3141#else
3142  _LIBUNWIND_ABORT("mips_o32 float support not implemented");
3143#endif
3144}
3145
3146inline void Registers_mips_o32::setFloatRegister(int regNum,
3147                                                 double value) {
3148#if defined(__mips_hard_float) && __mips_fpr == 64
3149  assert(validFloatRegister(regNum));
3150  _floats[regNum - UNW_MIPS_F0] = value;
3151#else
3152  _LIBUNWIND_ABORT("mips_o32 float support not implemented");
3153#endif
3154}
3155
3156inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
3157  return false;
3158}
3159
3160inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
3161  _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
3162}
3163
3164inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
3165  _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
3166}
3167
3168inline const char *Registers_mips_o32::getRegisterName(int regNum) {
3169  switch (regNum) {
3170  case UNW_MIPS_R0:
3171    return "$0";
3172  case UNW_MIPS_R1:
3173    return "$1";
3174  case UNW_MIPS_R2:
3175    return "$2";
3176  case UNW_MIPS_R3:
3177    return "$3";
3178  case UNW_MIPS_R4:
3179    return "$4";
3180  case UNW_MIPS_R5:
3181    return "$5";
3182  case UNW_MIPS_R6:
3183    return "$6";
3184  case UNW_MIPS_R7:
3185    return "$7";
3186  case UNW_MIPS_R8:
3187    return "$8";
3188  case UNW_MIPS_R9:
3189    return "$9";
3190  case UNW_MIPS_R10:
3191    return "$10";
3192  case UNW_MIPS_R11:
3193    return "$11";
3194  case UNW_MIPS_R12:
3195    return "$12";
3196  case UNW_MIPS_R13:
3197    return "$13";
3198  case UNW_MIPS_R14:
3199    return "$14";
3200  case UNW_MIPS_R15:
3201    return "$15";
3202  case UNW_MIPS_R16:
3203    return "$16";
3204  case UNW_MIPS_R17:
3205    return "$17";
3206  case UNW_MIPS_R18:
3207    return "$18";
3208  case UNW_MIPS_R19:
3209    return "$19";
3210  case UNW_MIPS_R20:
3211    return "$20";
3212  case UNW_MIPS_R21:
3213    return "$21";
3214  case UNW_MIPS_R22:
3215    return "$22";
3216  case UNW_MIPS_R23:
3217    return "$23";
3218  case UNW_MIPS_R24:
3219    return "$24";
3220  case UNW_MIPS_R25:
3221    return "$25";
3222  case UNW_MIPS_R26:
3223    return "$26";
3224  case UNW_MIPS_R27:
3225    return "$27";
3226  case UNW_MIPS_R28:
3227    return "$28";
3228  case UNW_MIPS_R29:
3229    return "$29";
3230  case UNW_MIPS_R30:
3231    return "$30";
3232  case UNW_MIPS_R31:
3233    return "$31";
3234  case UNW_MIPS_F0:
3235    return "$f0";
3236  case UNW_MIPS_F1:
3237    return "$f1";
3238  case UNW_MIPS_F2:
3239    return "$f2";
3240  case UNW_MIPS_F3:
3241    return "$f3";
3242  case UNW_MIPS_F4:
3243    return "$f4";
3244  case UNW_MIPS_F5:
3245    return "$f5";
3246  case UNW_MIPS_F6:
3247    return "$f6";
3248  case UNW_MIPS_F7:
3249    return "$f7";
3250  case UNW_MIPS_F8:
3251    return "$f8";
3252  case UNW_MIPS_F9:
3253    return "$f9";
3254  case UNW_MIPS_F10:
3255    return "$f10";
3256  case UNW_MIPS_F11:
3257    return "$f11";
3258  case UNW_MIPS_F12:
3259    return "$f12";
3260  case UNW_MIPS_F13:
3261    return "$f13";
3262  case UNW_MIPS_F14:
3263    return "$f14";
3264  case UNW_MIPS_F15:
3265    return "$f15";
3266  case UNW_MIPS_F16:
3267    return "$f16";
3268  case UNW_MIPS_F17:
3269    return "$f17";
3270  case UNW_MIPS_F18:
3271    return "$f18";
3272  case UNW_MIPS_F19:
3273    return "$f19";
3274  case UNW_MIPS_F20:
3275    return "$f20";
3276  case UNW_MIPS_F21:
3277    return "$f21";
3278  case UNW_MIPS_F22:
3279    return "$f22";
3280  case UNW_MIPS_F23:
3281    return "$f23";
3282  case UNW_MIPS_F24:
3283    return "$f24";
3284  case UNW_MIPS_F25:
3285    return "$f25";
3286  case UNW_MIPS_F26:
3287    return "$f26";
3288  case UNW_MIPS_F27:
3289    return "$f27";
3290  case UNW_MIPS_F28:
3291    return "$f28";
3292  case UNW_MIPS_F29:
3293    return "$f29";
3294  case UNW_MIPS_F30:
3295    return "$f30";
3296  case UNW_MIPS_F31:
3297    return "$f31";
3298  case UNW_MIPS_HI:
3299    return "$hi";
3300  case UNW_MIPS_LO:
3301    return "$lo";
3302  default:
3303    return "unknown register";
3304  }
3305}
3306#endif // _LIBUNWIND_TARGET_MIPS_O32
3307
3308#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
3309/// Registers_mips_newabi holds the register state of a thread in a
3310/// MIPS process using NEWABI (the N32 or N64 ABIs).
3311class _LIBUNWIND_HIDDEN Registers_mips_newabi {
3312public:
3313  Registers_mips_newabi();
3314  Registers_mips_newabi(const void *registers);
3315
3316  bool        validRegister(int num) const;
3317  uint64_t    getRegister(int num) const;
3318  void        setRegister(int num, uint64_t value);
3319  bool        validFloatRegister(int num) const;
3320  double      getFloatRegister(int num) const;
3321  void        setFloatRegister(int num, double value);
3322  bool        validVectorRegister(int num) const;
3323  v128        getVectorRegister(int num) const;
3324  void        setVectorRegister(int num, v128 value);
3325  static const char *getRegisterName(int num);
3326  void        jumpto();
3327  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
3328  static int  getArch() { return REGISTERS_MIPS_NEWABI; }
3329
3330  uint64_t  getSP() const         { return _registers.__r[29]; }
3331  void      setSP(uint64_t value) { _registers.__r[29] = value; }
3332  uint64_t  getIP() const         { return _registers.__pc; }
3333  void      setIP(uint64_t value) { _registers.__pc = value; }
3334
3335private:
3336  struct mips_newabi_thread_state_t {
3337    uint64_t __r[32];
3338    uint64_t __pc;
3339    uint64_t __hi;
3340    uint64_t __lo;
3341  };
3342
3343  mips_newabi_thread_state_t _registers;
3344#ifdef __mips_hard_float
3345  double _floats[32];
3346#endif
3347};
3348
3349inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {
3350  static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),
3351                "mips_newabi registers do not fit into unw_context_t");
3352  memcpy(&_registers, static_cast<const uint8_t *>(registers),
3353         sizeof(_registers));
3354}
3355
3356inline Registers_mips_newabi::Registers_mips_newabi() {
3357  memset(&_registers, 0, sizeof(_registers));
3358}
3359
3360inline bool Registers_mips_newabi::validRegister(int regNum) const {
3361  if (regNum == UNW_REG_IP)
3362    return true;
3363  if (regNum == UNW_REG_SP)
3364    return true;
3365  if (regNum < 0)
3366    return false;
3367  if (regNum <= UNW_MIPS_R31)
3368    return true;
3369#if __mips_isa_rev != 6
3370  if (regNum == UNW_MIPS_HI)
3371    return true;
3372  if (regNum == UNW_MIPS_LO)
3373    return true;
3374#endif
3375  // FIXME: Hard float, DSP accumulator registers, MSA registers
3376  return false;
3377}
3378
3379inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
3380  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3381    return _registers.__r[regNum - UNW_MIPS_R0];
3382
3383  switch (regNum) {
3384  case UNW_REG_IP:
3385    return _registers.__pc;
3386  case UNW_REG_SP:
3387    return _registers.__r[29];
3388  case UNW_MIPS_HI:
3389    return _registers.__hi;
3390  case UNW_MIPS_LO:
3391    return _registers.__lo;
3392  }
3393  _LIBUNWIND_ABORT("unsupported mips_newabi register");
3394}
3395
3396inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
3397  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3398    _registers.__r[regNum - UNW_MIPS_R0] = value;
3399    return;
3400  }
3401
3402  switch (regNum) {
3403  case UNW_REG_IP:
3404    _registers.__pc = value;
3405    return;
3406  case UNW_REG_SP:
3407    _registers.__r[29] = value;
3408    return;
3409  case UNW_MIPS_HI:
3410    _registers.__hi = value;
3411    return;
3412  case UNW_MIPS_LO:
3413    _registers.__lo = value;
3414    return;
3415  }
3416  _LIBUNWIND_ABORT("unsupported mips_newabi register");
3417}
3418
3419inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {
3420#ifdef __mips_hard_float
3421  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3422    return true;
3423#endif
3424  return false;
3425}
3426
3427inline double Registers_mips_newabi::getFloatRegister(int regNum) const {
3428#ifdef __mips_hard_float
3429  assert(validFloatRegister(regNum));
3430  return _floats[regNum - UNW_MIPS_F0];
3431#else
3432  _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3433#endif
3434}
3435
3436inline void Registers_mips_newabi::setFloatRegister(int regNum,
3437                                                    double value) {
3438#ifdef __mips_hard_float
3439  assert(validFloatRegister(regNum));
3440  _floats[regNum - UNW_MIPS_F0] = value;
3441#else
3442  _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3443#endif
3444}
3445
3446inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {
3447  return false;
3448}
3449
3450inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {
3451  _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3452}
3453
3454inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {
3455  _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3456}
3457
3458inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
3459  switch (regNum) {
3460  case UNW_MIPS_R0:
3461    return "$0";
3462  case UNW_MIPS_R1:
3463    return "$1";
3464  case UNW_MIPS_R2:
3465    return "$2";
3466  case UNW_MIPS_R3:
3467    return "$3";
3468  case UNW_MIPS_R4:
3469    return "$4";
3470  case UNW_MIPS_R5:
3471    return "$5";
3472  case UNW_MIPS_R6:
3473    return "$6";
3474  case UNW_MIPS_R7:
3475    return "$7";
3476  case UNW_MIPS_R8:
3477    return "$8";
3478  case UNW_MIPS_R9:
3479    return "$9";
3480  case UNW_MIPS_R10:
3481    return "$10";
3482  case UNW_MIPS_R11:
3483    return "$11";
3484  case UNW_MIPS_R12:
3485    return "$12";
3486  case UNW_MIPS_R13:
3487    return "$13";
3488  case UNW_MIPS_R14:
3489    return "$14";
3490  case UNW_MIPS_R15:
3491    return "$15";
3492  case UNW_MIPS_R16:
3493    return "$16";
3494  case UNW_MIPS_R17:
3495    return "$17";
3496  case UNW_MIPS_R18:
3497    return "$18";
3498  case UNW_MIPS_R19:
3499    return "$19";
3500  case UNW_MIPS_R20:
3501    return "$20";
3502  case UNW_MIPS_R21:
3503    return "$21";
3504  case UNW_MIPS_R22:
3505    return "$22";
3506  case UNW_MIPS_R23:
3507    return "$23";
3508  case UNW_MIPS_R24:
3509    return "$24";
3510  case UNW_MIPS_R25:
3511    return "$25";
3512  case UNW_MIPS_R26:
3513    return "$26";
3514  case UNW_MIPS_R27:
3515    return "$27";
3516  case UNW_MIPS_R28:
3517    return "$28";
3518  case UNW_MIPS_R29:
3519    return "$29";
3520  case UNW_MIPS_R30:
3521    return "$30";
3522  case UNW_MIPS_R31:
3523    return "$31";
3524  case UNW_MIPS_F0:
3525    return "$f0";
3526  case UNW_MIPS_F1:
3527    return "$f1";
3528  case UNW_MIPS_F2:
3529    return "$f2";
3530  case UNW_MIPS_F3:
3531    return "$f3";
3532  case UNW_MIPS_F4:
3533    return "$f4";
3534  case UNW_MIPS_F5:
3535    return "$f5";
3536  case UNW_MIPS_F6:
3537    return "$f6";
3538  case UNW_MIPS_F7:
3539    return "$f7";
3540  case UNW_MIPS_F8:
3541    return "$f8";
3542  case UNW_MIPS_F9:
3543    return "$f9";
3544  case UNW_MIPS_F10:
3545    return "$f10";
3546  case UNW_MIPS_F11:
3547    return "$f11";
3548  case UNW_MIPS_F12:
3549    return "$f12";
3550  case UNW_MIPS_F13:
3551    return "$f13";
3552  case UNW_MIPS_F14:
3553    return "$f14";
3554  case UNW_MIPS_F15:
3555    return "$f15";
3556  case UNW_MIPS_F16:
3557    return "$f16";
3558  case UNW_MIPS_F17:
3559    return "$f17";
3560  case UNW_MIPS_F18:
3561    return "$f18";
3562  case UNW_MIPS_F19:
3563    return "$f19";
3564  case UNW_MIPS_F20:
3565    return "$f20";
3566  case UNW_MIPS_F21:
3567    return "$f21";
3568  case UNW_MIPS_F22:
3569    return "$f22";
3570  case UNW_MIPS_F23:
3571    return "$f23";
3572  case UNW_MIPS_F24:
3573    return "$f24";
3574  case UNW_MIPS_F25:
3575    return "$f25";
3576  case UNW_MIPS_F26:
3577    return "$f26";
3578  case UNW_MIPS_F27:
3579    return "$f27";
3580  case UNW_MIPS_F28:
3581    return "$f28";
3582  case UNW_MIPS_F29:
3583    return "$f29";
3584  case UNW_MIPS_F30:
3585    return "$f30";
3586  case UNW_MIPS_F31:
3587    return "$f31";
3588  case UNW_MIPS_HI:
3589    return "$hi";
3590  case UNW_MIPS_LO:
3591    return "$lo";
3592  default:
3593    return "unknown register";
3594  }
3595}
3596#endif // _LIBUNWIND_TARGET_MIPS_NEWABI
3597
3598#if defined(_LIBUNWIND_TARGET_SPARC)
3599/// Registers_sparc holds the register state of a thread in a 32-bit Sparc
3600/// process.
3601class _LIBUNWIND_HIDDEN Registers_sparc {
3602public:
3603  Registers_sparc();
3604  Registers_sparc(const void *registers);
3605
3606  bool        validRegister(int num) const;
3607  uint32_t    getRegister(int num) const;
3608  void        setRegister(int num, uint32_t value);
3609  bool        validFloatRegister(int num) const;
3610  double      getFloatRegister(int num) const;
3611  void        setFloatRegister(int num, double value);
3612  bool        validVectorRegister(int num) const;
3613  v128        getVectorRegister(int num) const;
3614  void        setVectorRegister(int num, v128 value);
3615  static const char *getRegisterName(int num);
3616  void        jumpto();
3617  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC; }
3618  static int  getArch() { return REGISTERS_SPARC; }
3619
3620  uint64_t  getSP() const         { return _registers.__regs[UNW_SPARC_O6]; }
3621  void      setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; }
3622  uint64_t  getIP() const         { return _registers.__regs[UNW_SPARC_O7]; }
3623  void      setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
3624
3625private:
3626  struct sparc_thread_state_t {
3627    unsigned int __regs[32];
3628  };
3629
3630  sparc_thread_state_t _registers;
3631};
3632
3633inline Registers_sparc::Registers_sparc(const void *registers) {
3634  static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit),
3635                "sparc registers do not fit into unw_context_t");
3636  memcpy(&_registers, static_cast<const uint8_t *>(registers),
3637         sizeof(_registers));
3638}
3639
3640inline Registers_sparc::Registers_sparc() {
3641  memset(&_registers, 0, sizeof(_registers));
3642}
3643
3644inline bool Registers_sparc::validRegister(int regNum) const {
3645  if (regNum == UNW_REG_IP)
3646    return true;
3647  if (regNum == UNW_REG_SP)
3648    return true;
3649  if (regNum < 0)
3650    return false;
3651  if (regNum <= UNW_SPARC_I7)
3652    return true;
3653  return false;
3654}
3655
3656inline uint32_t Registers_sparc::getRegister(int regNum) const {
3657  if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3658    return _registers.__regs[regNum];
3659  }
3660
3661  switch (regNum) {
3662  case UNW_REG_IP:
3663    return _registers.__regs[UNW_SPARC_O7];
3664  case UNW_REG_SP:
3665    return _registers.__regs[UNW_SPARC_O6];
3666  }
3667  _LIBUNWIND_ABORT("unsupported sparc register");
3668}
3669
3670inline void Registers_sparc::setRegister(int regNum, uint32_t value) {
3671  if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3672    _registers.__regs[regNum] = value;
3673    return;
3674  }
3675
3676  switch (regNum) {
3677  case UNW_REG_IP:
3678    _registers.__regs[UNW_SPARC_O7] = value;
3679    return;
3680  case UNW_REG_SP:
3681    _registers.__regs[UNW_SPARC_O6] = value;
3682    return;
3683  }
3684  _LIBUNWIND_ABORT("unsupported sparc register");
3685}
3686
3687inline bool Registers_sparc::validFloatRegister(int) const { return false; }
3688
3689inline double Registers_sparc::getFloatRegister(int) const {
3690  _LIBUNWIND_ABORT("no Sparc float registers");
3691}
3692
3693inline void Registers_sparc::setFloatRegister(int, double) {
3694  _LIBUNWIND_ABORT("no Sparc float registers");
3695}
3696
3697inline bool Registers_sparc::validVectorRegister(int) const { return false; }
3698
3699inline v128 Registers_sparc::getVectorRegister(int) const {
3700  _LIBUNWIND_ABORT("no Sparc vector registers");
3701}
3702
3703inline void Registers_sparc::setVectorRegister(int, v128) {
3704  _LIBUNWIND_ABORT("no Sparc vector registers");
3705}
3706
3707inline const char *Registers_sparc::getRegisterName(int regNum) {
3708  switch (regNum) {
3709  case UNW_REG_IP:
3710    return "pc";
3711  case UNW_SPARC_G0:
3712    return "g0";
3713  case UNW_SPARC_G1:
3714    return "g1";
3715  case UNW_SPARC_G2:
3716    return "g2";
3717  case UNW_SPARC_G3:
3718    return "g3";
3719  case UNW_SPARC_G4:
3720    return "g4";
3721  case UNW_SPARC_G5:
3722    return "g5";
3723  case UNW_SPARC_G6:
3724    return "g6";
3725  case UNW_SPARC_G7:
3726    return "g7";
3727  case UNW_SPARC_O0:
3728    return "o0";
3729  case UNW_SPARC_O1:
3730    return "o1";
3731  case UNW_SPARC_O2:
3732    return "o2";
3733  case UNW_SPARC_O3:
3734    return "o3";
3735  case UNW_SPARC_O4:
3736    return "o4";
3737  case UNW_SPARC_O5:
3738    return "o5";
3739  case UNW_REG_SP:
3740  case UNW_SPARC_O6:
3741    return "sp";
3742  case UNW_SPARC_O7:
3743    return "o7";
3744  case UNW_SPARC_L0:
3745    return "l0";
3746  case UNW_SPARC_L1:
3747    return "l1";
3748  case UNW_SPARC_L2:
3749    return "l2";
3750  case UNW_SPARC_L3:
3751    return "l3";
3752  case UNW_SPARC_L4:
3753    return "l4";
3754  case UNW_SPARC_L5:
3755    return "l5";
3756  case UNW_SPARC_L6:
3757    return "l6";
3758  case UNW_SPARC_L7:
3759    return "l7";
3760  case UNW_SPARC_I0:
3761    return "i0";
3762  case UNW_SPARC_I1:
3763    return "i1";
3764  case UNW_SPARC_I2:
3765    return "i2";
3766  case UNW_SPARC_I3:
3767    return "i3";
3768  case UNW_SPARC_I4:
3769    return "i4";
3770  case UNW_SPARC_I5:
3771    return "i5";
3772  case UNW_SPARC_I6:
3773    return "fp";
3774  case UNW_SPARC_I7:
3775    return "i7";
3776  default:
3777    return "unknown register";
3778  }
3779}
3780#endif // _LIBUNWIND_TARGET_SPARC
3781
3782} // namespace libunwind
3783
3784#endif // __REGISTERS_HPP__
3785