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_MIPS_O32,
35  REGISTERS_MIPS_NEWABI,
36  REGISTERS_SPARC,
37  REGISTERS_RISCV,
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_MIPS_O32)
2726/// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
2727/// process.
2728class _LIBUNWIND_HIDDEN Registers_mips_o32 {
2729public:
2730  Registers_mips_o32();
2731  Registers_mips_o32(const void *registers);
2732
2733  bool        validRegister(int num) const;
2734  uint32_t    getRegister(int num) const;
2735  void        setRegister(int num, uint32_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_MIPS; }
2745  static int  getArch() { return REGISTERS_MIPS_O32; }
2746
2747  uint32_t  getSP() const         { return _registers.__r[29]; }
2748  void      setSP(uint32_t value) { _registers.__r[29] = value; }
2749  uint32_t  getIP() const         { return _registers.__pc; }
2750  void      setIP(uint32_t value) { _registers.__pc = value; }
2751
2752private:
2753  struct mips_o32_thread_state_t {
2754    uint32_t __r[32];
2755    uint32_t __pc;
2756    uint32_t __hi;
2757    uint32_t __lo;
2758  };
2759
2760  mips_o32_thread_state_t _registers;
2761#ifdef __mips_hard_float
2762  /// O32 with 32-bit floating point registers only uses half of this
2763  /// space.  However, using the same layout for 32-bit vs 64-bit
2764  /// floating point registers results in a single context size for
2765  /// O32 with hard float.
2766  uint32_t _padding;
2767  double _floats[32];
2768#endif
2769};
2770
2771inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
2772  static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
2773                "mips_o32 registers do not fit into unw_context_t");
2774  memcpy(&_registers, static_cast<const uint8_t *>(registers),
2775         sizeof(_registers));
2776}
2777
2778inline Registers_mips_o32::Registers_mips_o32() {
2779  memset(&_registers, 0, sizeof(_registers));
2780}
2781
2782inline bool Registers_mips_o32::validRegister(int regNum) const {
2783  if (regNum == UNW_REG_IP)
2784    return true;
2785  if (regNum == UNW_REG_SP)
2786    return true;
2787  if (regNum < 0)
2788    return false;
2789  if (regNum <= UNW_MIPS_R31)
2790    return true;
2791#if __mips_isa_rev != 6
2792  if (regNum == UNW_MIPS_HI)
2793    return true;
2794  if (regNum == UNW_MIPS_LO)
2795    return true;
2796#endif
2797#if defined(__mips_hard_float) && __mips_fpr == 32
2798  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2799    return true;
2800#endif
2801  // FIXME: DSP accumulator registers, MSA registers
2802  return false;
2803}
2804
2805inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
2806  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
2807    return _registers.__r[regNum - UNW_MIPS_R0];
2808#if defined(__mips_hard_float) && __mips_fpr == 32
2809  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2810    uint32_t *p;
2811
2812    if (regNum % 2 == 0)
2813      p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2814    else
2815      p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2816    return *p;
2817  }
2818#endif
2819
2820  switch (regNum) {
2821  case UNW_REG_IP:
2822    return _registers.__pc;
2823  case UNW_REG_SP:
2824    return _registers.__r[29];
2825  case UNW_MIPS_HI:
2826    return _registers.__hi;
2827  case UNW_MIPS_LO:
2828    return _registers.__lo;
2829  }
2830  _LIBUNWIND_ABORT("unsupported mips_o32 register");
2831}
2832
2833inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
2834  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
2835    _registers.__r[regNum - UNW_MIPS_R0] = value;
2836    return;
2837  }
2838#if defined(__mips_hard_float) && __mips_fpr == 32
2839  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2840    uint32_t *p;
2841
2842    if (regNum % 2 == 0)
2843      p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2844    else
2845      p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2846    *p = value;
2847    return;
2848  }
2849#endif
2850
2851  switch (regNum) {
2852  case UNW_REG_IP:
2853    _registers.__pc = value;
2854    return;
2855  case UNW_REG_SP:
2856    _registers.__r[29] = value;
2857    return;
2858  case UNW_MIPS_HI:
2859    _registers.__hi = value;
2860    return;
2861  case UNW_MIPS_LO:
2862    _registers.__lo = value;
2863    return;
2864  }
2865  _LIBUNWIND_ABORT("unsupported mips_o32 register");
2866}
2867
2868inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
2869#if defined(__mips_hard_float) && __mips_fpr == 64
2870  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2871    return true;
2872#endif
2873  return false;
2874}
2875
2876inline double Registers_mips_o32::getFloatRegister(int regNum) const {
2877#if defined(__mips_hard_float) && __mips_fpr == 64
2878  assert(validFloatRegister(regNum));
2879  return _floats[regNum - UNW_MIPS_F0];
2880#else
2881  _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2882#endif
2883}
2884
2885inline void Registers_mips_o32::setFloatRegister(int regNum,
2886                                                 double value) {
2887#if defined(__mips_hard_float) && __mips_fpr == 64
2888  assert(validFloatRegister(regNum));
2889  _floats[regNum - UNW_MIPS_F0] = value;
2890#else
2891  _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2892#endif
2893}
2894
2895inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
2896  return false;
2897}
2898
2899inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
2900  _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2901}
2902
2903inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
2904  _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2905}
2906
2907inline const char *Registers_mips_o32::getRegisterName(int regNum) {
2908  switch (regNum) {
2909  case UNW_MIPS_R0:
2910    return "$0";
2911  case UNW_MIPS_R1:
2912    return "$1";
2913  case UNW_MIPS_R2:
2914    return "$2";
2915  case UNW_MIPS_R3:
2916    return "$3";
2917  case UNW_MIPS_R4:
2918    return "$4";
2919  case UNW_MIPS_R5:
2920    return "$5";
2921  case UNW_MIPS_R6:
2922    return "$6";
2923  case UNW_MIPS_R7:
2924    return "$7";
2925  case UNW_MIPS_R8:
2926    return "$8";
2927  case UNW_MIPS_R9:
2928    return "$9";
2929  case UNW_MIPS_R10:
2930    return "$10";
2931  case UNW_MIPS_R11:
2932    return "$11";
2933  case UNW_MIPS_R12:
2934    return "$12";
2935  case UNW_MIPS_R13:
2936    return "$13";
2937  case UNW_MIPS_R14:
2938    return "$14";
2939  case UNW_MIPS_R15:
2940    return "$15";
2941  case UNW_MIPS_R16:
2942    return "$16";
2943  case UNW_MIPS_R17:
2944    return "$17";
2945  case UNW_MIPS_R18:
2946    return "$18";
2947  case UNW_MIPS_R19:
2948    return "$19";
2949  case UNW_MIPS_R20:
2950    return "$20";
2951  case UNW_MIPS_R21:
2952    return "$21";
2953  case UNW_MIPS_R22:
2954    return "$22";
2955  case UNW_MIPS_R23:
2956    return "$23";
2957  case UNW_MIPS_R24:
2958    return "$24";
2959  case UNW_MIPS_R25:
2960    return "$25";
2961  case UNW_MIPS_R26:
2962    return "$26";
2963  case UNW_MIPS_R27:
2964    return "$27";
2965  case UNW_MIPS_R28:
2966    return "$28";
2967  case UNW_MIPS_R29:
2968    return "$29";
2969  case UNW_MIPS_R30:
2970    return "$30";
2971  case UNW_MIPS_R31:
2972    return "$31";
2973  case UNW_MIPS_F0:
2974    return "$f0";
2975  case UNW_MIPS_F1:
2976    return "$f1";
2977  case UNW_MIPS_F2:
2978    return "$f2";
2979  case UNW_MIPS_F3:
2980    return "$f3";
2981  case UNW_MIPS_F4:
2982    return "$f4";
2983  case UNW_MIPS_F5:
2984    return "$f5";
2985  case UNW_MIPS_F6:
2986    return "$f6";
2987  case UNW_MIPS_F7:
2988    return "$f7";
2989  case UNW_MIPS_F8:
2990    return "$f8";
2991  case UNW_MIPS_F9:
2992    return "$f9";
2993  case UNW_MIPS_F10:
2994    return "$f10";
2995  case UNW_MIPS_F11:
2996    return "$f11";
2997  case UNW_MIPS_F12:
2998    return "$f12";
2999  case UNW_MIPS_F13:
3000    return "$f13";
3001  case UNW_MIPS_F14:
3002    return "$f14";
3003  case UNW_MIPS_F15:
3004    return "$f15";
3005  case UNW_MIPS_F16:
3006    return "$f16";
3007  case UNW_MIPS_F17:
3008    return "$f17";
3009  case UNW_MIPS_F18:
3010    return "$f18";
3011  case UNW_MIPS_F19:
3012    return "$f19";
3013  case UNW_MIPS_F20:
3014    return "$f20";
3015  case UNW_MIPS_F21:
3016    return "$f21";
3017  case UNW_MIPS_F22:
3018    return "$f22";
3019  case UNW_MIPS_F23:
3020    return "$f23";
3021  case UNW_MIPS_F24:
3022    return "$f24";
3023  case UNW_MIPS_F25:
3024    return "$f25";
3025  case UNW_MIPS_F26:
3026    return "$f26";
3027  case UNW_MIPS_F27:
3028    return "$f27";
3029  case UNW_MIPS_F28:
3030    return "$f28";
3031  case UNW_MIPS_F29:
3032    return "$f29";
3033  case UNW_MIPS_F30:
3034    return "$f30";
3035  case UNW_MIPS_F31:
3036    return "$f31";
3037  case UNW_MIPS_HI:
3038    return "$hi";
3039  case UNW_MIPS_LO:
3040    return "$lo";
3041  default:
3042    return "unknown register";
3043  }
3044}
3045#endif // _LIBUNWIND_TARGET_MIPS_O32
3046
3047#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
3048/// Registers_mips_newabi holds the register state of a thread in a
3049/// MIPS process using NEWABI (the N32 or N64 ABIs).
3050class _LIBUNWIND_HIDDEN Registers_mips_newabi {
3051public:
3052  Registers_mips_newabi();
3053  Registers_mips_newabi(const void *registers);
3054
3055  bool        validRegister(int num) const;
3056  uint64_t    getRegister(int num) const;
3057  void        setRegister(int num, uint64_t value);
3058  bool        validFloatRegister(int num) const;
3059  double      getFloatRegister(int num) const;
3060  void        setFloatRegister(int num, double value);
3061  bool        validVectorRegister(int num) const;
3062  v128        getVectorRegister(int num) const;
3063  void        setVectorRegister(int num, v128 value);
3064  static const char *getRegisterName(int num);
3065  void        jumpto();
3066  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
3067  static int  getArch() { return REGISTERS_MIPS_NEWABI; }
3068
3069  uint64_t  getSP() const         { return _registers.__r[29]; }
3070  void      setSP(uint64_t value) { _registers.__r[29] = value; }
3071  uint64_t  getIP() const         { return _registers.__pc; }
3072  void      setIP(uint64_t value) { _registers.__pc = value; }
3073
3074private:
3075  struct mips_newabi_thread_state_t {
3076    uint64_t __r[32];
3077    uint64_t __pc;
3078    uint64_t __hi;
3079    uint64_t __lo;
3080  };
3081
3082  mips_newabi_thread_state_t _registers;
3083#ifdef __mips_hard_float
3084  double _floats[32];
3085#endif
3086};
3087
3088inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {
3089  static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),
3090                "mips_newabi registers do not fit into unw_context_t");
3091  memcpy(&_registers, static_cast<const uint8_t *>(registers),
3092         sizeof(_registers));
3093}
3094
3095inline Registers_mips_newabi::Registers_mips_newabi() {
3096  memset(&_registers, 0, sizeof(_registers));
3097}
3098
3099inline bool Registers_mips_newabi::validRegister(int regNum) const {
3100  if (regNum == UNW_REG_IP)
3101    return true;
3102  if (regNum == UNW_REG_SP)
3103    return true;
3104  if (regNum < 0)
3105    return false;
3106  if (regNum <= UNW_MIPS_R31)
3107    return true;
3108#if __mips_isa_rev != 6
3109  if (regNum == UNW_MIPS_HI)
3110    return true;
3111  if (regNum == UNW_MIPS_LO)
3112    return true;
3113#endif
3114  // FIXME: Hard float, DSP accumulator registers, MSA registers
3115  return false;
3116}
3117
3118inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
3119  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3120    return _registers.__r[regNum - UNW_MIPS_R0];
3121
3122  switch (regNum) {
3123  case UNW_REG_IP:
3124    return _registers.__pc;
3125  case UNW_REG_SP:
3126    return _registers.__r[29];
3127  case UNW_MIPS_HI:
3128    return _registers.__hi;
3129  case UNW_MIPS_LO:
3130    return _registers.__lo;
3131  }
3132  _LIBUNWIND_ABORT("unsupported mips_newabi register");
3133}
3134
3135inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
3136  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3137    _registers.__r[regNum - UNW_MIPS_R0] = value;
3138    return;
3139  }
3140
3141  switch (regNum) {
3142  case UNW_REG_IP:
3143    _registers.__pc = value;
3144    return;
3145  case UNW_REG_SP:
3146    _registers.__r[29] = value;
3147    return;
3148  case UNW_MIPS_HI:
3149    _registers.__hi = value;
3150    return;
3151  case UNW_MIPS_LO:
3152    _registers.__lo = value;
3153    return;
3154  }
3155  _LIBUNWIND_ABORT("unsupported mips_newabi register");
3156}
3157
3158inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {
3159#ifdef __mips_hard_float
3160  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3161    return true;
3162#endif
3163  return false;
3164}
3165
3166inline double Registers_mips_newabi::getFloatRegister(int regNum) const {
3167#ifdef __mips_hard_float
3168  assert(validFloatRegister(regNum));
3169  return _floats[regNum - UNW_MIPS_F0];
3170#else
3171  _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3172#endif
3173}
3174
3175inline void Registers_mips_newabi::setFloatRegister(int regNum,
3176                                                    double value) {
3177#ifdef __mips_hard_float
3178  assert(validFloatRegister(regNum));
3179  _floats[regNum - UNW_MIPS_F0] = value;
3180#else
3181  _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3182#endif
3183}
3184
3185inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {
3186  return false;
3187}
3188
3189inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {
3190  _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3191}
3192
3193inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {
3194  _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3195}
3196
3197inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
3198  switch (regNum) {
3199  case UNW_MIPS_R0:
3200    return "$0";
3201  case UNW_MIPS_R1:
3202    return "$1";
3203  case UNW_MIPS_R2:
3204    return "$2";
3205  case UNW_MIPS_R3:
3206    return "$3";
3207  case UNW_MIPS_R4:
3208    return "$4";
3209  case UNW_MIPS_R5:
3210    return "$5";
3211  case UNW_MIPS_R6:
3212    return "$6";
3213  case UNW_MIPS_R7:
3214    return "$7";
3215  case UNW_MIPS_R8:
3216    return "$8";
3217  case UNW_MIPS_R9:
3218    return "$9";
3219  case UNW_MIPS_R10:
3220    return "$10";
3221  case UNW_MIPS_R11:
3222    return "$11";
3223  case UNW_MIPS_R12:
3224    return "$12";
3225  case UNW_MIPS_R13:
3226    return "$13";
3227  case UNW_MIPS_R14:
3228    return "$14";
3229  case UNW_MIPS_R15:
3230    return "$15";
3231  case UNW_MIPS_R16:
3232    return "$16";
3233  case UNW_MIPS_R17:
3234    return "$17";
3235  case UNW_MIPS_R18:
3236    return "$18";
3237  case UNW_MIPS_R19:
3238    return "$19";
3239  case UNW_MIPS_R20:
3240    return "$20";
3241  case UNW_MIPS_R21:
3242    return "$21";
3243  case UNW_MIPS_R22:
3244    return "$22";
3245  case UNW_MIPS_R23:
3246    return "$23";
3247  case UNW_MIPS_R24:
3248    return "$24";
3249  case UNW_MIPS_R25:
3250    return "$25";
3251  case UNW_MIPS_R26:
3252    return "$26";
3253  case UNW_MIPS_R27:
3254    return "$27";
3255  case UNW_MIPS_R28:
3256    return "$28";
3257  case UNW_MIPS_R29:
3258    return "$29";
3259  case UNW_MIPS_R30:
3260    return "$30";
3261  case UNW_MIPS_R31:
3262    return "$31";
3263  case UNW_MIPS_F0:
3264    return "$f0";
3265  case UNW_MIPS_F1:
3266    return "$f1";
3267  case UNW_MIPS_F2:
3268    return "$f2";
3269  case UNW_MIPS_F3:
3270    return "$f3";
3271  case UNW_MIPS_F4:
3272    return "$f4";
3273  case UNW_MIPS_F5:
3274    return "$f5";
3275  case UNW_MIPS_F6:
3276    return "$f6";
3277  case UNW_MIPS_F7:
3278    return "$f7";
3279  case UNW_MIPS_F8:
3280    return "$f8";
3281  case UNW_MIPS_F9:
3282    return "$f9";
3283  case UNW_MIPS_F10:
3284    return "$f10";
3285  case UNW_MIPS_F11:
3286    return "$f11";
3287  case UNW_MIPS_F12:
3288    return "$f12";
3289  case UNW_MIPS_F13:
3290    return "$f13";
3291  case UNW_MIPS_F14:
3292    return "$f14";
3293  case UNW_MIPS_F15:
3294    return "$f15";
3295  case UNW_MIPS_F16:
3296    return "$f16";
3297  case UNW_MIPS_F17:
3298    return "$f17";
3299  case UNW_MIPS_F18:
3300    return "$f18";
3301  case UNW_MIPS_F19:
3302    return "$f19";
3303  case UNW_MIPS_F20:
3304    return "$f20";
3305  case UNW_MIPS_F21:
3306    return "$f21";
3307  case UNW_MIPS_F22:
3308    return "$f22";
3309  case UNW_MIPS_F23:
3310    return "$f23";
3311  case UNW_MIPS_F24:
3312    return "$f24";
3313  case UNW_MIPS_F25:
3314    return "$f25";
3315  case UNW_MIPS_F26:
3316    return "$f26";
3317  case UNW_MIPS_F27:
3318    return "$f27";
3319  case UNW_MIPS_F28:
3320    return "$f28";
3321  case UNW_MIPS_F29:
3322    return "$f29";
3323  case UNW_MIPS_F30:
3324    return "$f30";
3325  case UNW_MIPS_F31:
3326    return "$f31";
3327  case UNW_MIPS_HI:
3328    return "$hi";
3329  case UNW_MIPS_LO:
3330    return "$lo";
3331  default:
3332    return "unknown register";
3333  }
3334}
3335#endif // _LIBUNWIND_TARGET_MIPS_NEWABI
3336
3337#if defined(_LIBUNWIND_TARGET_SPARC)
3338/// Registers_sparc holds the register state of a thread in a 32-bit Sparc
3339/// process.
3340class _LIBUNWIND_HIDDEN Registers_sparc {
3341public:
3342  Registers_sparc();
3343  Registers_sparc(const void *registers);
3344
3345  bool        validRegister(int num) const;
3346  uint32_t    getRegister(int num) const;
3347  void        setRegister(int num, uint32_t value);
3348  bool        validFloatRegister(int num) const;
3349  double      getFloatRegister(int num) const;
3350  void        setFloatRegister(int num, double value);
3351  bool        validVectorRegister(int num) const;
3352  v128        getVectorRegister(int num) const;
3353  void        setVectorRegister(int num, v128 value);
3354  static const char *getRegisterName(int num);
3355  void        jumpto();
3356  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC; }
3357  static int  getArch() { return REGISTERS_SPARC; }
3358
3359  uint64_t  getSP() const         { return _registers.__regs[UNW_SPARC_O6]; }
3360  void      setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; }
3361  uint64_t  getIP() const         { return _registers.__regs[UNW_SPARC_O7]; }
3362  void      setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
3363
3364private:
3365  struct sparc_thread_state_t {
3366    unsigned int __regs[32];
3367  };
3368
3369  sparc_thread_state_t _registers;
3370};
3371
3372inline Registers_sparc::Registers_sparc(const void *registers) {
3373  static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit),
3374                "sparc registers do not fit into unw_context_t");
3375  memcpy(&_registers, static_cast<const uint8_t *>(registers),
3376         sizeof(_registers));
3377}
3378
3379inline Registers_sparc::Registers_sparc() {
3380  memset(&_registers, 0, sizeof(_registers));
3381}
3382
3383inline bool Registers_sparc::validRegister(int regNum) const {
3384  if (regNum == UNW_REG_IP)
3385    return true;
3386  if (regNum == UNW_REG_SP)
3387    return true;
3388  if (regNum < 0)
3389    return false;
3390  if (regNum <= UNW_SPARC_I7)
3391    return true;
3392  return false;
3393}
3394
3395inline uint32_t Registers_sparc::getRegister(int regNum) const {
3396  if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3397    return _registers.__regs[regNum];
3398  }
3399
3400  switch (regNum) {
3401  case UNW_REG_IP:
3402    return _registers.__regs[UNW_SPARC_O7];
3403  case UNW_REG_SP:
3404    return _registers.__regs[UNW_SPARC_O6];
3405  }
3406  _LIBUNWIND_ABORT("unsupported sparc register");
3407}
3408
3409inline void Registers_sparc::setRegister(int regNum, uint32_t value) {
3410  if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3411    _registers.__regs[regNum] = value;
3412    return;
3413  }
3414
3415  switch (regNum) {
3416  case UNW_REG_IP:
3417    _registers.__regs[UNW_SPARC_O7] = value;
3418    return;
3419  case UNW_REG_SP:
3420    _registers.__regs[UNW_SPARC_O6] = value;
3421    return;
3422  }
3423  _LIBUNWIND_ABORT("unsupported sparc register");
3424}
3425
3426inline bool Registers_sparc::validFloatRegister(int) const { return false; }
3427
3428inline double Registers_sparc::getFloatRegister(int) const {
3429  _LIBUNWIND_ABORT("no Sparc float registers");
3430}
3431
3432inline void Registers_sparc::setFloatRegister(int, double) {
3433  _LIBUNWIND_ABORT("no Sparc float registers");
3434}
3435
3436inline bool Registers_sparc::validVectorRegister(int) const { return false; }
3437
3438inline v128 Registers_sparc::getVectorRegister(int) const {
3439  _LIBUNWIND_ABORT("no Sparc vector registers");
3440}
3441
3442inline void Registers_sparc::setVectorRegister(int, v128) {
3443  _LIBUNWIND_ABORT("no Sparc vector registers");
3444}
3445
3446inline const char *Registers_sparc::getRegisterName(int regNum) {
3447  switch (regNum) {
3448  case UNW_REG_IP:
3449    return "pc";
3450  case UNW_SPARC_G0:
3451    return "g0";
3452  case UNW_SPARC_G1:
3453    return "g1";
3454  case UNW_SPARC_G2:
3455    return "g2";
3456  case UNW_SPARC_G3:
3457    return "g3";
3458  case UNW_SPARC_G4:
3459    return "g4";
3460  case UNW_SPARC_G5:
3461    return "g5";
3462  case UNW_SPARC_G6:
3463    return "g6";
3464  case UNW_SPARC_G7:
3465    return "g7";
3466  case UNW_SPARC_O0:
3467    return "o0";
3468  case UNW_SPARC_O1:
3469    return "o1";
3470  case UNW_SPARC_O2:
3471    return "o2";
3472  case UNW_SPARC_O3:
3473    return "o3";
3474  case UNW_SPARC_O4:
3475    return "o4";
3476  case UNW_SPARC_O5:
3477    return "o5";
3478  case UNW_REG_SP:
3479  case UNW_SPARC_O6:
3480    return "sp";
3481  case UNW_SPARC_O7:
3482    return "o7";
3483  case UNW_SPARC_L0:
3484    return "l0";
3485  case UNW_SPARC_L1:
3486    return "l1";
3487  case UNW_SPARC_L2:
3488    return "l2";
3489  case UNW_SPARC_L3:
3490    return "l3";
3491  case UNW_SPARC_L4:
3492    return "l4";
3493  case UNW_SPARC_L5:
3494    return "l5";
3495  case UNW_SPARC_L6:
3496    return "l6";
3497  case UNW_SPARC_L7:
3498    return "l7";
3499  case UNW_SPARC_I0:
3500    return "i0";
3501  case UNW_SPARC_I1:
3502    return "i1";
3503  case UNW_SPARC_I2:
3504    return "i2";
3505  case UNW_SPARC_I3:
3506    return "i3";
3507  case UNW_SPARC_I4:
3508    return "i4";
3509  case UNW_SPARC_I5:
3510    return "i5";
3511  case UNW_SPARC_I6:
3512    return "fp";
3513  case UNW_SPARC_I7:
3514    return "i7";
3515  default:
3516    return "unknown register";
3517  }
3518}
3519#endif // _LIBUNWIND_TARGET_SPARC
3520
3521#if defined(_LIBUNWIND_TARGET_RISCV)
3522/// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
3523/// process.
3524class _LIBUNWIND_HIDDEN Registers_riscv {
3525public:
3526  Registers_riscv();
3527  Registers_riscv(const void *registers);
3528
3529  bool        validRegister(int num) const;
3530  uint64_t    getRegister(int num) const;
3531  void        setRegister(int num, uint64_t value);
3532  bool        validFloatRegister(int num) const;
3533  double      getFloatRegister(int num) const;
3534  void        setFloatRegister(int num, double value);
3535  bool        validVectorRegister(int num) const;
3536  v128        getVectorRegister(int num) const;
3537  void        setVectorRegister(int num, v128 value);
3538  static const char *getRegisterName(int num);
3539  void        jumpto();
3540  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
3541  static int  getArch() { return REGISTERS_RISCV; }
3542
3543  uint64_t  getSP() const         { return _registers[2]; }
3544  void      setSP(uint64_t value) { _registers[2] = value; }
3545  uint64_t  getIP() const         { return _registers[1]; }
3546  void      setIP(uint64_t value) { _registers[1] = value; }
3547
3548private:
3549
3550  uint64_t _registers[32];
3551  double   _floats[32];
3552};
3553
3554inline Registers_riscv::Registers_riscv(const void *registers) {
3555  static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
3556                "riscv registers do not fit into unw_context_t");
3557  memcpy(&_registers, registers, sizeof(_registers));
3558  static_assert(sizeof(_registers) == 0x100,
3559                "expected float registers to be at offset 256");
3560  memcpy(_floats,
3561         static_cast<const uint8_t *>(registers) + sizeof(_registers),
3562         sizeof(_floats));
3563}
3564
3565inline Registers_riscv::Registers_riscv() {
3566  memset(&_registers, 0, sizeof(_registers));
3567  memset(&_floats, 0, sizeof(_floats));
3568}
3569
3570inline bool Registers_riscv::validRegister(int regNum) const {
3571  if (regNum == UNW_REG_IP)
3572    return true;
3573  if (regNum == UNW_REG_SP)
3574    return true;
3575  if (regNum < 0)
3576    return false;
3577  if (regNum > UNW_RISCV_F31)
3578    return false;
3579  return true;
3580}
3581
3582inline uint64_t Registers_riscv::getRegister(int regNum) const {
3583  if (regNum == UNW_REG_IP)
3584    return _registers[1];
3585  if (regNum == UNW_REG_SP)
3586    return _registers[2];
3587  if (regNum == UNW_RISCV_X0)
3588    return 0;
3589  if ((regNum > 0) && (regNum < 32))
3590    return _registers[regNum];
3591  _LIBUNWIND_ABORT("unsupported riscv register");
3592}
3593
3594inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
3595  if (regNum == UNW_REG_IP)
3596    _registers[1] = value;
3597  else if (regNum == UNW_REG_SP)
3598    _registers[2] = value;
3599  else if (regNum == UNW_RISCV_X0)
3600    /* x0 is hardwired to zero */
3601    return;
3602  else if ((regNum > 0) && (regNum < 32))
3603    _registers[regNum] = value;
3604  else
3605    _LIBUNWIND_ABORT("unsupported riscv register");
3606}
3607
3608inline const char *Registers_riscv::getRegisterName(int regNum) {
3609  switch (regNum) {
3610  case UNW_REG_IP:
3611    return "pc";
3612  case UNW_REG_SP:
3613    return "sp";
3614  case UNW_RISCV_X0:
3615    return "zero";
3616  case UNW_RISCV_X1:
3617    return "ra";
3618  case UNW_RISCV_X2:
3619    return "sp";
3620  case UNW_RISCV_X3:
3621    return "gp";
3622  case UNW_RISCV_X4:
3623    return "tp";
3624  case UNW_RISCV_X5:
3625    return "t0";
3626  case UNW_RISCV_X6:
3627    return "t1";
3628  case UNW_RISCV_X7:
3629    return "t2";
3630  case UNW_RISCV_X8:
3631    return "s0";
3632  case UNW_RISCV_X9:
3633    return "s1";
3634  case UNW_RISCV_X10:
3635    return "a0";
3636  case UNW_RISCV_X11:
3637    return "a1";
3638  case UNW_RISCV_X12:
3639    return "a2";
3640  case UNW_RISCV_X13:
3641    return "a3";
3642  case UNW_RISCV_X14:
3643    return "a4";
3644  case UNW_RISCV_X15:
3645    return "a5";
3646  case UNW_RISCV_X16:
3647    return "a6";
3648  case UNW_RISCV_X17:
3649    return "a7";
3650  case UNW_RISCV_X18:
3651    return "s2";
3652  case UNW_RISCV_X19:
3653    return "s3";
3654  case UNW_RISCV_X20:
3655    return "s4";
3656  case UNW_RISCV_X21:
3657    return "s5";
3658  case UNW_RISCV_X22:
3659    return "s6";
3660  case UNW_RISCV_X23:
3661    return "s7";
3662  case UNW_RISCV_X24:
3663    return "s8";
3664  case UNW_RISCV_X25:
3665    return "s9";
3666  case UNW_RISCV_X26:
3667    return "s10";
3668  case UNW_RISCV_X27:
3669    return "s11";
3670  case UNW_RISCV_X28:
3671    return "t3";
3672  case UNW_RISCV_X29:
3673    return "t4";
3674  case UNW_RISCV_X30:
3675    return "t5";
3676  case UNW_RISCV_X31:
3677    return "t6";
3678  case UNW_RISCV_F0:
3679    return "ft0";
3680  case UNW_RISCV_F1:
3681    return "ft1";
3682  case UNW_RISCV_F2:
3683    return "ft2";
3684  case UNW_RISCV_F3:
3685    return "ft3";
3686  case UNW_RISCV_F4:
3687    return "ft4";
3688  case UNW_RISCV_F5:
3689    return "ft5";
3690  case UNW_RISCV_F6:
3691    return "ft6";
3692  case UNW_RISCV_F7:
3693    return "ft7";
3694  case UNW_RISCV_F8:
3695    return "fs0";
3696  case UNW_RISCV_F9:
3697    return "fs1";
3698  case UNW_RISCV_F10:
3699    return "fa0";
3700  case UNW_RISCV_F11:
3701    return "fa1";
3702  case UNW_RISCV_F12:
3703    return "fa2";
3704  case UNW_RISCV_F13:
3705    return "fa3";
3706  case UNW_RISCV_F14:
3707    return "fa4";
3708  case UNW_RISCV_F15:
3709    return "fa5";
3710  case UNW_RISCV_F16:
3711    return "fa6";
3712  case UNW_RISCV_F17:
3713    return "fa7";
3714  case UNW_RISCV_F18:
3715    return "fs2";
3716  case UNW_RISCV_F19:
3717    return "fs3";
3718  case UNW_RISCV_F20:
3719    return "fs4";
3720  case UNW_RISCV_F21:
3721    return "fs5";
3722  case UNW_RISCV_F22:
3723    return "fs6";
3724  case UNW_RISCV_F23:
3725    return "fs7";
3726  case UNW_RISCV_F24:
3727    return "fs8";
3728  case UNW_RISCV_F25:
3729    return "fs9";
3730  case UNW_RISCV_F26:
3731    return "fs10";
3732  case UNW_RISCV_F27:
3733    return "fs11";
3734  case UNW_RISCV_F28:
3735    return "ft8";
3736  case UNW_RISCV_F29:
3737    return "ft9";
3738  case UNW_RISCV_F30:
3739    return "ft10";
3740  case UNW_RISCV_F31:
3741    return "ft11";
3742  default:
3743    return "unknown register";
3744  }
3745}
3746
3747inline bool Registers_riscv::validFloatRegister(int regNum) const {
3748  if (regNum < UNW_RISCV_F0)
3749    return false;
3750  if (regNum > UNW_RISCV_F31)
3751    return false;
3752  return true;
3753}
3754
3755inline double Registers_riscv::getFloatRegister(int regNum) const {
3756#if defined(__riscv_flen) && __riscv_flen == 64
3757  assert(validFloatRegister(regNum));
3758  return _floats[regNum - UNW_RISCV_F0];
3759#else
3760  _LIBUNWIND_ABORT("libunwind not built with float support");
3761#endif
3762}
3763
3764inline void Registers_riscv::setFloatRegister(int regNum, double value) {
3765#if defined(__riscv_flen) && __riscv_flen == 64
3766  assert(validFloatRegister(regNum));
3767  _floats[regNum - UNW_RISCV_F0] = value;
3768#else
3769  _LIBUNWIND_ABORT("libunwind not built with float support");
3770#endif
3771}
3772
3773inline bool Registers_riscv::validVectorRegister(int) const {
3774  return false;
3775}
3776
3777inline v128 Registers_riscv::getVectorRegister(int) const {
3778  _LIBUNWIND_ABORT("no riscv vector register support yet");
3779}
3780
3781inline void Registers_riscv::setVectorRegister(int, v128) {
3782  _LIBUNWIND_ABORT("no riscv vector register support yet");
3783}
3784#endif // _LIBUNWIND_TARGET_RISCV
3785} // namespace libunwind
3786
3787#endif // __REGISTERS_HPP__
3788