master
   1//===----------------------------------------------------------------------===//
   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 "config.h"
  19#include "libunwind.h"
  20#include "shadow_stack_unwind.h"
  21
  22namespace libunwind {
  23
  24// For emulating 128-bit registers
  25struct v128 { uint32_t vec[4]; };
  26
  27enum {
  28  REGISTERS_X86,
  29  REGISTERS_X86_64,
  30  REGISTERS_PPC,
  31  REGISTERS_PPC64,
  32  REGISTERS_ARM64,
  33  REGISTERS_ARM,
  34  REGISTERS_OR1K,
  35  REGISTERS_MIPS_O32,
  36  REGISTERS_MIPS_NEWABI,
  37  REGISTERS_SPARC,
  38  REGISTERS_SPARC64,
  39  REGISTERS_HEXAGON,
  40  REGISTERS_RISCV,
  41  REGISTERS_VE,
  42  REGISTERS_S390X,
  43  REGISTERS_LOONGARCH,
  44};
  45
  46#if defined(_LIBUNWIND_TARGET_I386)
  47class _LIBUNWIND_HIDDEN Registers_x86;
  48extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);
  49
  50#if defined(_LIBUNWIND_USE_CET)
  51extern "C" void *__libunwind_shstk_get_jump_target() {
  52  return reinterpret_cast<void *>(&__libunwind_Registers_x86_jumpto);
  53}
  54#endif
  55
  56/// Registers_x86 holds the register state of a thread in a 32-bit intel
  57/// process.
  58class _LIBUNWIND_HIDDEN Registers_x86 {
  59public:
  60  Registers_x86();
  61  Registers_x86(const void *registers);
  62
  63  bool        validRegister(int num) const;
  64  uint32_t    getRegister(int num) const;
  65  void        setRegister(int num, uint32_t value);
  66  bool        validFloatRegister(int) const { return false; }
  67  double      getFloatRegister(int num) const;
  68  void        setFloatRegister(int num, double value);
  69  bool        validVectorRegister(int) const { return false; }
  70  v128        getVectorRegister(int num) const;
  71  void        setVectorRegister(int num, v128 value);
  72  static const char *getRegisterName(int num);
  73  void        jumpto() { __libunwind_Registers_x86_jumpto(this); }
  74  static constexpr int lastDwarfRegNum() {
  75    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86;
  76  }
  77  static int  getArch() { return REGISTERS_X86; }
  78
  79  uint32_t  getSP() const          { return _registers.__esp; }
  80  void      setSP(uint32_t value)  { _registers.__esp = value; }
  81  uint32_t  getIP() const          { return _registers.__eip; }
  82  void      setIP(uint32_t value)  { _registers.__eip = value; }
  83  uint32_t  getEBP() const         { return _registers.__ebp; }
  84  void      setEBP(uint32_t value) { _registers.__ebp = value; }
  85  uint32_t  getEBX() const         { return _registers.__ebx; }
  86  void      setEBX(uint32_t value) { _registers.__ebx = value; }
  87  uint32_t  getECX() const         { return _registers.__ecx; }
  88  void      setECX(uint32_t value) { _registers.__ecx = value; }
  89  uint32_t  getEDX() const         { return _registers.__edx; }
  90  void      setEDX(uint32_t value) { _registers.__edx = value; }
  91  uint32_t  getESI() const         { return _registers.__esi; }
  92  void      setESI(uint32_t value) { _registers.__esi = value; }
  93  uint32_t  getEDI() const         { return _registers.__edi; }
  94  void      setEDI(uint32_t value) { _registers.__edi = value; }
  95
  96private:
  97  struct GPRs {
  98    unsigned int __eax;
  99    unsigned int __ebx;
 100    unsigned int __ecx;
 101    unsigned int __edx;
 102    unsigned int __edi;
 103    unsigned int __esi;
 104    unsigned int __ebp;
 105    unsigned int __esp;
 106    unsigned int __ss;
 107    unsigned int __eflags;
 108    unsigned int __eip;
 109    unsigned int __cs;
 110    unsigned int __ds;
 111    unsigned int __es;
 112    unsigned int __fs;
 113    unsigned int __gs;
 114  };
 115
 116  GPRs _registers;
 117};
 118
 119inline Registers_x86::Registers_x86(const void *registers) {
 120  static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
 121                "x86 registers do not fit into unw_context_t");
 122  memcpy(&_registers, registers, sizeof(_registers));
 123}
 124
 125inline Registers_x86::Registers_x86() {
 126  memset(&_registers, 0, sizeof(_registers));
 127}
 128
 129inline bool Registers_x86::validRegister(int regNum) const {
 130  if (regNum == UNW_REG_IP)
 131    return true;
 132  if (regNum == UNW_REG_SP)
 133    return true;
 134  if (regNum < 0)
 135    return false;
 136  if (regNum > 7)
 137    return false;
 138  return true;
 139}
 140
 141inline uint32_t Registers_x86::getRegister(int regNum) const {
 142  switch (regNum) {
 143  case UNW_REG_IP:
 144    return _registers.__eip;
 145  case UNW_REG_SP:
 146    return _registers.__esp;
 147  case UNW_X86_EAX:
 148    return _registers.__eax;
 149  case UNW_X86_ECX:
 150    return _registers.__ecx;
 151  case UNW_X86_EDX:
 152    return _registers.__edx;
 153  case UNW_X86_EBX:
 154    return _registers.__ebx;
 155#if !defined(__APPLE__)
 156  case UNW_X86_ESP:
 157#else
 158  case UNW_X86_EBP:
 159#endif
 160    return _registers.__ebp;
 161#if !defined(__APPLE__)
 162  case UNW_X86_EBP:
 163#else
 164  case UNW_X86_ESP:
 165#endif
 166    return _registers.__esp;
 167  case UNW_X86_ESI:
 168    return _registers.__esi;
 169  case UNW_X86_EDI:
 170    return _registers.__edi;
 171  }
 172  _LIBUNWIND_ABORT("unsupported x86 register");
 173}
 174
 175inline void Registers_x86::setRegister(int regNum, uint32_t value) {
 176  switch (regNum) {
 177  case UNW_REG_IP:
 178    _registers.__eip = value;
 179    return;
 180  case UNW_REG_SP:
 181    _registers.__esp = value;
 182    return;
 183  case UNW_X86_EAX:
 184    _registers.__eax = value;
 185    return;
 186  case UNW_X86_ECX:
 187    _registers.__ecx = value;
 188    return;
 189  case UNW_X86_EDX:
 190    _registers.__edx = value;
 191    return;
 192  case UNW_X86_EBX:
 193    _registers.__ebx = value;
 194    return;
 195#if !defined(__APPLE__)
 196  case UNW_X86_ESP:
 197#else
 198  case UNW_X86_EBP:
 199#endif
 200    _registers.__ebp = value;
 201    return;
 202#if !defined(__APPLE__)
 203  case UNW_X86_EBP:
 204#else
 205  case UNW_X86_ESP:
 206#endif
 207    _registers.__esp = value;
 208    return;
 209  case UNW_X86_ESI:
 210    _registers.__esi = value;
 211    return;
 212  case UNW_X86_EDI:
 213    _registers.__edi = value;
 214    return;
 215  }
 216  _LIBUNWIND_ABORT("unsupported x86 register");
 217}
 218
 219inline const char *Registers_x86::getRegisterName(int regNum) {
 220  switch (regNum) {
 221  case UNW_REG_IP:
 222    return "ip";
 223  case UNW_REG_SP:
 224    return "esp";
 225  case UNW_X86_EAX:
 226    return "eax";
 227  case UNW_X86_ECX:
 228    return "ecx";
 229  case UNW_X86_EDX:
 230    return "edx";
 231  case UNW_X86_EBX:
 232    return "ebx";
 233  case UNW_X86_EBP:
 234    return "ebp";
 235  case UNW_X86_ESP:
 236    return "esp";
 237  case UNW_X86_ESI:
 238    return "esi";
 239  case UNW_X86_EDI:
 240    return "edi";
 241  default:
 242    return "unknown register";
 243  }
 244}
 245
 246inline double Registers_x86::getFloatRegister(int) const {
 247  _LIBUNWIND_ABORT("no x86 float registers");
 248}
 249
 250inline void Registers_x86::setFloatRegister(int, double) {
 251  _LIBUNWIND_ABORT("no x86 float registers");
 252}
 253
 254inline v128 Registers_x86::getVectorRegister(int) const {
 255  _LIBUNWIND_ABORT("no x86 vector registers");
 256}
 257
 258inline void Registers_x86::setVectorRegister(int, v128) {
 259  _LIBUNWIND_ABORT("no x86 vector registers");
 260}
 261#endif // _LIBUNWIND_TARGET_I386
 262
 263
 264#if defined(_LIBUNWIND_TARGET_X86_64)
 265/// Registers_x86_64  holds the register state of a thread in a 64-bit intel
 266/// process.
 267class _LIBUNWIND_HIDDEN Registers_x86_64;
 268extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);
 269
 270#if defined(_LIBUNWIND_USE_CET)
 271extern "C" void *__libunwind_shstk_get_jump_target() {
 272  return reinterpret_cast<void *>(&__libunwind_Registers_x86_64_jumpto);
 273}
 274#endif
 275
 276class _LIBUNWIND_HIDDEN Registers_x86_64 {
 277public:
 278  Registers_x86_64();
 279  Registers_x86_64(const void *registers);
 280
 281  bool        validRegister(int num) const;
 282  uint64_t    getRegister(int num) const;
 283  void        setRegister(int num, uint64_t value);
 284  bool        validFloatRegister(int) const { return false; }
 285  double      getFloatRegister(int num) const;
 286  void        setFloatRegister(int num, double value);
 287  bool        validVectorRegister(int) const;
 288  v128        getVectorRegister(int num) const;
 289  void        setVectorRegister(int num, v128 value);
 290  static const char *getRegisterName(int num);
 291  void        jumpto() { __libunwind_Registers_x86_64_jumpto(this); }
 292  static constexpr int lastDwarfRegNum() {
 293    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64;
 294  }
 295  static int  getArch() { return REGISTERS_X86_64; }
 296
 297  uint64_t  getSP() const          { return _registers.__rsp; }
 298  void      setSP(uint64_t value)  { _registers.__rsp = value; }
 299  uint64_t  getIP() const          { return _registers.__rip; }
 300  void      setIP(uint64_t value)  { _registers.__rip = value; }
 301  uint64_t  getRBP() const         { return _registers.__rbp; }
 302  void      setRBP(uint64_t value) { _registers.__rbp = value; }
 303  uint64_t  getRBX() const         { return _registers.__rbx; }
 304  void      setRBX(uint64_t value) { _registers.__rbx = value; }
 305  uint64_t  getR12() const         { return _registers.__r12; }
 306  void      setR12(uint64_t value) { _registers.__r12 = value; }
 307  uint64_t  getR13() const         { return _registers.__r13; }
 308  void      setR13(uint64_t value) { _registers.__r13 = value; }
 309  uint64_t  getR14() const         { return _registers.__r14; }
 310  void      setR14(uint64_t value) { _registers.__r14 = value; }
 311  uint64_t  getR15() const         { return _registers.__r15; }
 312  void      setR15(uint64_t value) { _registers.__r15 = value; }
 313
 314private:
 315  struct GPRs {
 316    uint64_t __rax;
 317    uint64_t __rbx;
 318    uint64_t __rcx;
 319    uint64_t __rdx;
 320    uint64_t __rdi;
 321    uint64_t __rsi;
 322    uint64_t __rbp;
 323    uint64_t __rsp;
 324    uint64_t __r8;
 325    uint64_t __r9;
 326    uint64_t __r10;
 327    uint64_t __r11;
 328    uint64_t __r12;
 329    uint64_t __r13;
 330    uint64_t __r14;
 331    uint64_t __r15;
 332    uint64_t __rip;
 333    uint64_t __rflags;
 334    uint64_t __cs;
 335    uint64_t __fs;
 336    uint64_t __gs;
 337#if defined(_WIN64)
 338    uint64_t __padding; // 16-byte align
 339#endif
 340  };
 341  GPRs _registers;
 342#if defined(_WIN64)
 343  v128 _xmm[16];
 344#endif
 345};
 346
 347inline Registers_x86_64::Registers_x86_64(const void *registers) {
 348  static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
 349                "x86_64 registers do not fit into unw_context_t");
 350  memcpy(&_registers, registers, sizeof(_registers));
 351}
 352
 353inline Registers_x86_64::Registers_x86_64() {
 354  memset(&_registers, 0, sizeof(_registers));
 355}
 356
 357inline bool Registers_x86_64::validRegister(int regNum) const {
 358  if (regNum == UNW_REG_IP)
 359    return true;
 360  if (regNum == UNW_REG_SP)
 361    return true;
 362  if (regNum < 0)
 363    return false;
 364  if (regNum > 16)
 365    return false;
 366  return true;
 367}
 368
 369inline uint64_t Registers_x86_64::getRegister(int regNum) const {
 370  switch (regNum) {
 371  case UNW_REG_IP:
 372  case UNW_X86_64_RIP:
 373    return _registers.__rip;
 374  case UNW_REG_SP:
 375    return _registers.__rsp;
 376  case UNW_X86_64_RAX:
 377    return _registers.__rax;
 378  case UNW_X86_64_RDX:
 379    return _registers.__rdx;
 380  case UNW_X86_64_RCX:
 381    return _registers.__rcx;
 382  case UNW_X86_64_RBX:
 383    return _registers.__rbx;
 384  case UNW_X86_64_RSI:
 385    return _registers.__rsi;
 386  case UNW_X86_64_RDI:
 387    return _registers.__rdi;
 388  case UNW_X86_64_RBP:
 389    return _registers.__rbp;
 390  case UNW_X86_64_RSP:
 391    return _registers.__rsp;
 392  case UNW_X86_64_R8:
 393    return _registers.__r8;
 394  case UNW_X86_64_R9:
 395    return _registers.__r9;
 396  case UNW_X86_64_R10:
 397    return _registers.__r10;
 398  case UNW_X86_64_R11:
 399    return _registers.__r11;
 400  case UNW_X86_64_R12:
 401    return _registers.__r12;
 402  case UNW_X86_64_R13:
 403    return _registers.__r13;
 404  case UNW_X86_64_R14:
 405    return _registers.__r14;
 406  case UNW_X86_64_R15:
 407    return _registers.__r15;
 408  }
 409  _LIBUNWIND_ABORT("unsupported x86_64 register");
 410}
 411
 412inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
 413  switch (regNum) {
 414  case UNW_REG_IP:
 415  case UNW_X86_64_RIP:
 416    _registers.__rip = value;
 417    return;
 418  case UNW_REG_SP:
 419    _registers.__rsp = value;
 420    return;
 421  case UNW_X86_64_RAX:
 422    _registers.__rax = value;
 423    return;
 424  case UNW_X86_64_RDX:
 425    _registers.__rdx = value;
 426    return;
 427  case UNW_X86_64_RCX:
 428    _registers.__rcx = value;
 429    return;
 430  case UNW_X86_64_RBX:
 431    _registers.__rbx = value;
 432    return;
 433  case UNW_X86_64_RSI:
 434    _registers.__rsi = value;
 435    return;
 436  case UNW_X86_64_RDI:
 437    _registers.__rdi = value;
 438    return;
 439  case UNW_X86_64_RBP:
 440    _registers.__rbp = value;
 441    return;
 442  case UNW_X86_64_RSP:
 443    _registers.__rsp = value;
 444    return;
 445  case UNW_X86_64_R8:
 446    _registers.__r8 = value;
 447    return;
 448  case UNW_X86_64_R9:
 449    _registers.__r9 = value;
 450    return;
 451  case UNW_X86_64_R10:
 452    _registers.__r10 = value;
 453    return;
 454  case UNW_X86_64_R11:
 455    _registers.__r11 = value;
 456    return;
 457  case UNW_X86_64_R12:
 458    _registers.__r12 = value;
 459    return;
 460  case UNW_X86_64_R13:
 461    _registers.__r13 = value;
 462    return;
 463  case UNW_X86_64_R14:
 464    _registers.__r14 = value;
 465    return;
 466  case UNW_X86_64_R15:
 467    _registers.__r15 = value;
 468    return;
 469  }
 470  _LIBUNWIND_ABORT("unsupported x86_64 register");
 471}
 472
 473inline const char *Registers_x86_64::getRegisterName(int regNum) {
 474  switch (regNum) {
 475  case UNW_REG_IP:
 476  case UNW_X86_64_RIP:
 477    return "rip";
 478  case UNW_REG_SP:
 479    return "rsp";
 480  case UNW_X86_64_RAX:
 481    return "rax";
 482  case UNW_X86_64_RDX:
 483    return "rdx";
 484  case UNW_X86_64_RCX:
 485    return "rcx";
 486  case UNW_X86_64_RBX:
 487    return "rbx";
 488  case UNW_X86_64_RSI:
 489    return "rsi";
 490  case UNW_X86_64_RDI:
 491    return "rdi";
 492  case UNW_X86_64_RBP:
 493    return "rbp";
 494  case UNW_X86_64_RSP:
 495    return "rsp";
 496  case UNW_X86_64_R8:
 497    return "r8";
 498  case UNW_X86_64_R9:
 499    return "r9";
 500  case UNW_X86_64_R10:
 501    return "r10";
 502  case UNW_X86_64_R11:
 503    return "r11";
 504  case UNW_X86_64_R12:
 505    return "r12";
 506  case UNW_X86_64_R13:
 507    return "r13";
 508  case UNW_X86_64_R14:
 509    return "r14";
 510  case UNW_X86_64_R15:
 511    return "r15";
 512  case UNW_X86_64_XMM0:
 513    return "xmm0";
 514  case UNW_X86_64_XMM1:
 515    return "xmm1";
 516  case UNW_X86_64_XMM2:
 517    return "xmm2";
 518  case UNW_X86_64_XMM3:
 519    return "xmm3";
 520  case UNW_X86_64_XMM4:
 521    return "xmm4";
 522  case UNW_X86_64_XMM5:
 523    return "xmm5";
 524  case UNW_X86_64_XMM6:
 525    return "xmm6";
 526  case UNW_X86_64_XMM7:
 527    return "xmm7";
 528  case UNW_X86_64_XMM8:
 529    return "xmm8";
 530  case UNW_X86_64_XMM9:
 531    return "xmm9";
 532  case UNW_X86_64_XMM10:
 533    return "xmm10";
 534  case UNW_X86_64_XMM11:
 535    return "xmm11";
 536  case UNW_X86_64_XMM12:
 537    return "xmm12";
 538  case UNW_X86_64_XMM13:
 539    return "xmm13";
 540  case UNW_X86_64_XMM14:
 541    return "xmm14";
 542  case UNW_X86_64_XMM15:
 543    return "xmm15";
 544  default:
 545    return "unknown register";
 546  }
 547}
 548
 549inline double Registers_x86_64::getFloatRegister(int) const {
 550  _LIBUNWIND_ABORT("no x86_64 float registers");
 551}
 552
 553inline void Registers_x86_64::setFloatRegister(int, double) {
 554  _LIBUNWIND_ABORT("no x86_64 float registers");
 555}
 556
 557inline bool Registers_x86_64::validVectorRegister(int regNum) const {
 558#if defined(_WIN64)
 559  if (regNum < UNW_X86_64_XMM0)
 560    return false;
 561  if (regNum > UNW_X86_64_XMM15)
 562    return false;
 563  return true;
 564#else
 565  (void)regNum; // suppress unused parameter warning
 566  return false;
 567#endif
 568}
 569
 570inline v128 Registers_x86_64::getVectorRegister(int regNum) const {
 571#if defined(_WIN64)
 572  assert(validVectorRegister(regNum));
 573  return _xmm[regNum - UNW_X86_64_XMM0];
 574#else
 575  (void)regNum; // suppress unused parameter warning
 576  _LIBUNWIND_ABORT("no x86_64 vector registers");
 577#endif
 578}
 579
 580inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {
 581#if defined(_WIN64)
 582  assert(validVectorRegister(regNum));
 583  _xmm[regNum - UNW_X86_64_XMM0] = value;
 584#else
 585  (void)regNum; (void)value; // suppress unused parameter warnings
 586  _LIBUNWIND_ABORT("no x86_64 vector registers");
 587#endif
 588}
 589#endif // _LIBUNWIND_TARGET_X86_64
 590
 591
 592#if defined(_LIBUNWIND_TARGET_PPC)
 593/// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
 594/// process.
 595class _LIBUNWIND_HIDDEN Registers_ppc {
 596public:
 597  Registers_ppc();
 598  Registers_ppc(const void *registers);
 599
 600  bool        validRegister(int num) const;
 601  uint32_t    getRegister(int num) const;
 602  void        setRegister(int num, uint32_t value);
 603  bool        validFloatRegister(int num) const;
 604  double      getFloatRegister(int num) const;
 605  void        setFloatRegister(int num, double value);
 606  bool        validVectorRegister(int num) const;
 607  v128        getVectorRegister(int num) const;
 608  void        setVectorRegister(int num, v128 value);
 609  static const char *getRegisterName(int num);
 610  void        jumpto();
 611  static constexpr int lastDwarfRegNum() {
 612    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC;
 613  }
 614  static int  getArch() { return REGISTERS_PPC; }
 615
 616  uint64_t  getSP() const         { return _registers.__r1; }
 617  void      setSP(uint32_t value) { _registers.__r1 = value; }
 618  uint64_t  getIP() const         { return _registers.__srr0; }
 619  void      setIP(uint32_t value) { _registers.__srr0 = value; }
 620  uint64_t  getCR() const         { return _registers.__cr; }
 621  void      setCR(uint32_t value) { _registers.__cr = value; }
 622  uint64_t  getLR() const         { return _registers.__lr; }
 623  void      setLR(uint32_t value) { _registers.__lr = value; }
 624
 625private:
 626  struct ppc_thread_state_t {
 627    unsigned int __srr0; /* Instruction address register (PC) */
 628    unsigned int __srr1; /* Machine state register (supervisor) */
 629    unsigned int __r0;
 630    unsigned int __r1;
 631    unsigned int __r2;
 632    unsigned int __r3;
 633    unsigned int __r4;
 634    unsigned int __r5;
 635    unsigned int __r6;
 636    unsigned int __r7;
 637    unsigned int __r8;
 638    unsigned int __r9;
 639    unsigned int __r10;
 640    unsigned int __r11;
 641    unsigned int __r12;
 642    unsigned int __r13;
 643    unsigned int __r14;
 644    unsigned int __r15;
 645    unsigned int __r16;
 646    unsigned int __r17;
 647    unsigned int __r18;
 648    unsigned int __r19;
 649    unsigned int __r20;
 650    unsigned int __r21;
 651    unsigned int __r22;
 652    unsigned int __r23;
 653    unsigned int __r24;
 654    unsigned int __r25;
 655    unsigned int __r26;
 656    unsigned int __r27;
 657    unsigned int __r28;
 658    unsigned int __r29;
 659    unsigned int __r30;
 660    unsigned int __r31;
 661    unsigned int __cr;     /* Condition register */
 662    unsigned int __xer;    /* User's integer exception register */
 663    unsigned int __lr;     /* Link register */
 664    unsigned int __ctr;    /* Count register */
 665    unsigned int __mq;     /* MQ register (601 only) */
 666    unsigned int __vrsave; /* Vector Save Register */
 667  };
 668
 669  struct ppc_float_state_t {
 670    double __fpregs[32];
 671
 672    unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
 673    unsigned int __fpscr;     /* floating point status register */
 674  };
 675
 676  ppc_thread_state_t _registers;
 677  ppc_float_state_t  _floatRegisters;
 678  v128               _vectorRegisters[32]; // offset 424
 679};
 680
 681inline Registers_ppc::Registers_ppc(const void *registers) {
 682  static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
 683                "ppc registers do not fit into unw_context_t");
 684  memcpy(&_registers, static_cast<const uint8_t *>(registers),
 685         sizeof(_registers));
 686  static_assert(sizeof(ppc_thread_state_t) == 160,
 687                "expected float register offset to be 160");
 688  memcpy(&_floatRegisters,
 689         static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
 690         sizeof(_floatRegisters));
 691  static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
 692                "expected vector register offset to be 424 bytes");
 693  memcpy(_vectorRegisters,
 694         static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
 695             sizeof(ppc_float_state_t),
 696         sizeof(_vectorRegisters));
 697}
 698
 699inline Registers_ppc::Registers_ppc() {
 700  memset(&_registers, 0, sizeof(_registers));
 701  memset(&_floatRegisters, 0, sizeof(_floatRegisters));
 702  memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
 703}
 704
 705inline bool Registers_ppc::validRegister(int regNum) const {
 706  if (regNum == UNW_REG_IP)
 707    return true;
 708  if (regNum == UNW_REG_SP)
 709    return true;
 710  if (regNum == UNW_PPC_VRSAVE)
 711    return true;
 712  if (regNum < 0)
 713    return false;
 714  if (regNum <= UNW_PPC_R31)
 715    return true;
 716  if (regNum == UNW_PPC_MQ)
 717    return true;
 718  if (regNum == UNW_PPC_LR)
 719    return true;
 720  if (regNum == UNW_PPC_CTR)
 721    return true;
 722  if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
 723    return true;
 724  return false;
 725}
 726
 727inline uint32_t Registers_ppc::getRegister(int regNum) const {
 728  switch (regNum) {
 729  case UNW_REG_IP:
 730    return _registers.__srr0;
 731  case UNW_REG_SP:
 732    return _registers.__r1;
 733  case UNW_PPC_R0:
 734    return _registers.__r0;
 735  case UNW_PPC_R1:
 736    return _registers.__r1;
 737  case UNW_PPC_R2:
 738    return _registers.__r2;
 739  case UNW_PPC_R3:
 740    return _registers.__r3;
 741  case UNW_PPC_R4:
 742    return _registers.__r4;
 743  case UNW_PPC_R5:
 744    return _registers.__r5;
 745  case UNW_PPC_R6:
 746    return _registers.__r6;
 747  case UNW_PPC_R7:
 748    return _registers.__r7;
 749  case UNW_PPC_R8:
 750    return _registers.__r8;
 751  case UNW_PPC_R9:
 752    return _registers.__r9;
 753  case UNW_PPC_R10:
 754    return _registers.__r10;
 755  case UNW_PPC_R11:
 756    return _registers.__r11;
 757  case UNW_PPC_R12:
 758    return _registers.__r12;
 759  case UNW_PPC_R13:
 760    return _registers.__r13;
 761  case UNW_PPC_R14:
 762    return _registers.__r14;
 763  case UNW_PPC_R15:
 764    return _registers.__r15;
 765  case UNW_PPC_R16:
 766    return _registers.__r16;
 767  case UNW_PPC_R17:
 768    return _registers.__r17;
 769  case UNW_PPC_R18:
 770    return _registers.__r18;
 771  case UNW_PPC_R19:
 772    return _registers.__r19;
 773  case UNW_PPC_R20:
 774    return _registers.__r20;
 775  case UNW_PPC_R21:
 776    return _registers.__r21;
 777  case UNW_PPC_R22:
 778    return _registers.__r22;
 779  case UNW_PPC_R23:
 780    return _registers.__r23;
 781  case UNW_PPC_R24:
 782    return _registers.__r24;
 783  case UNW_PPC_R25:
 784    return _registers.__r25;
 785  case UNW_PPC_R26:
 786    return _registers.__r26;
 787  case UNW_PPC_R27:
 788    return _registers.__r27;
 789  case UNW_PPC_R28:
 790    return _registers.__r28;
 791  case UNW_PPC_R29:
 792    return _registers.__r29;
 793  case UNW_PPC_R30:
 794    return _registers.__r30;
 795  case UNW_PPC_R31:
 796    return _registers.__r31;
 797  case UNW_PPC_LR:
 798    return _registers.__lr;
 799  case UNW_PPC_CR0:
 800    return (_registers.__cr & 0xF0000000);
 801  case UNW_PPC_CR1:
 802    return (_registers.__cr & 0x0F000000);
 803  case UNW_PPC_CR2:
 804    return (_registers.__cr & 0x00F00000);
 805  case UNW_PPC_CR3:
 806    return (_registers.__cr & 0x000F0000);
 807  case UNW_PPC_CR4:
 808    return (_registers.__cr & 0x0000F000);
 809  case UNW_PPC_CR5:
 810    return (_registers.__cr & 0x00000F00);
 811  case UNW_PPC_CR6:
 812    return (_registers.__cr & 0x000000F0);
 813  case UNW_PPC_CR7:
 814    return (_registers.__cr & 0x0000000F);
 815  case UNW_PPC_VRSAVE:
 816    return _registers.__vrsave;
 817  }
 818  _LIBUNWIND_ABORT("unsupported ppc register");
 819}
 820
 821inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
 822  //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
 823  switch (regNum) {
 824  case UNW_REG_IP:
 825    _registers.__srr0 = value;
 826    return;
 827  case UNW_REG_SP:
 828    _registers.__r1 = value;
 829    return;
 830  case UNW_PPC_R0:
 831    _registers.__r0 = value;
 832    return;
 833  case UNW_PPC_R1:
 834    _registers.__r1 = value;
 835    return;
 836  case UNW_PPC_R2:
 837    _registers.__r2 = value;
 838    return;
 839  case UNW_PPC_R3:
 840    _registers.__r3 = value;
 841    return;
 842  case UNW_PPC_R4:
 843    _registers.__r4 = value;
 844    return;
 845  case UNW_PPC_R5:
 846    _registers.__r5 = value;
 847    return;
 848  case UNW_PPC_R6:
 849    _registers.__r6 = value;
 850    return;
 851  case UNW_PPC_R7:
 852    _registers.__r7 = value;
 853    return;
 854  case UNW_PPC_R8:
 855    _registers.__r8 = value;
 856    return;
 857  case UNW_PPC_R9:
 858    _registers.__r9 = value;
 859    return;
 860  case UNW_PPC_R10:
 861    _registers.__r10 = value;
 862    return;
 863  case UNW_PPC_R11:
 864    _registers.__r11 = value;
 865    return;
 866  case UNW_PPC_R12:
 867    _registers.__r12 = value;
 868    return;
 869  case UNW_PPC_R13:
 870    _registers.__r13 = value;
 871    return;
 872  case UNW_PPC_R14:
 873    _registers.__r14 = value;
 874    return;
 875  case UNW_PPC_R15:
 876    _registers.__r15 = value;
 877    return;
 878  case UNW_PPC_R16:
 879    _registers.__r16 = value;
 880    return;
 881  case UNW_PPC_R17:
 882    _registers.__r17 = value;
 883    return;
 884  case UNW_PPC_R18:
 885    _registers.__r18 = value;
 886    return;
 887  case UNW_PPC_R19:
 888    _registers.__r19 = value;
 889    return;
 890  case UNW_PPC_R20:
 891    _registers.__r20 = value;
 892    return;
 893  case UNW_PPC_R21:
 894    _registers.__r21 = value;
 895    return;
 896  case UNW_PPC_R22:
 897    _registers.__r22 = value;
 898    return;
 899  case UNW_PPC_R23:
 900    _registers.__r23 = value;
 901    return;
 902  case UNW_PPC_R24:
 903    _registers.__r24 = value;
 904    return;
 905  case UNW_PPC_R25:
 906    _registers.__r25 = value;
 907    return;
 908  case UNW_PPC_R26:
 909    _registers.__r26 = value;
 910    return;
 911  case UNW_PPC_R27:
 912    _registers.__r27 = value;
 913    return;
 914  case UNW_PPC_R28:
 915    _registers.__r28 = value;
 916    return;
 917  case UNW_PPC_R29:
 918    _registers.__r29 = value;
 919    return;
 920  case UNW_PPC_R30:
 921    _registers.__r30 = value;
 922    return;
 923  case UNW_PPC_R31:
 924    _registers.__r31 = value;
 925    return;
 926  case UNW_PPC_MQ:
 927    _registers.__mq = value;
 928    return;
 929  case UNW_PPC_LR:
 930    _registers.__lr = value;
 931    return;
 932  case UNW_PPC_CTR:
 933    _registers.__ctr = value;
 934    return;
 935  case UNW_PPC_CR0:
 936    _registers.__cr &= 0x0FFFFFFF;
 937    _registers.__cr |= (value & 0xF0000000);
 938    return;
 939  case UNW_PPC_CR1:
 940    _registers.__cr &= 0xF0FFFFFF;
 941    _registers.__cr |= (value & 0x0F000000);
 942    return;
 943  case UNW_PPC_CR2:
 944    _registers.__cr &= 0xFF0FFFFF;
 945    _registers.__cr |= (value & 0x00F00000);
 946    return;
 947  case UNW_PPC_CR3:
 948    _registers.__cr &= 0xFFF0FFFF;
 949    _registers.__cr |= (value & 0x000F0000);
 950    return;
 951  case UNW_PPC_CR4:
 952    _registers.__cr &= 0xFFFF0FFF;
 953    _registers.__cr |= (value & 0x0000F000);
 954    return;
 955  case UNW_PPC_CR5:
 956    _registers.__cr &= 0xFFFFF0FF;
 957    _registers.__cr |= (value & 0x00000F00);
 958    return;
 959  case UNW_PPC_CR6:
 960    _registers.__cr &= 0xFFFFFF0F;
 961    _registers.__cr |= (value & 0x000000F0);
 962    return;
 963  case UNW_PPC_CR7:
 964    _registers.__cr &= 0xFFFFFFF0;
 965    _registers.__cr |= (value & 0x0000000F);
 966    return;
 967  case UNW_PPC_VRSAVE:
 968    _registers.__vrsave = value;
 969    return;
 970    // not saved
 971    return;
 972  case UNW_PPC_XER:
 973    _registers.__xer = value;
 974    return;
 975  case UNW_PPC_AP:
 976  case UNW_PPC_VSCR:
 977  case UNW_PPC_SPEFSCR:
 978    // not saved
 979    return;
 980  }
 981  _LIBUNWIND_ABORT("unsupported ppc register");
 982}
 983
 984inline bool Registers_ppc::validFloatRegister(int regNum) const {
 985  if (regNum < UNW_PPC_F0)
 986    return false;
 987  if (regNum > UNW_PPC_F31)
 988    return false;
 989  return true;
 990}
 991
 992inline double Registers_ppc::getFloatRegister(int regNum) const {
 993  assert(validFloatRegister(regNum));
 994  return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
 995}
 996
 997inline void Registers_ppc::setFloatRegister(int regNum, double value) {
 998  assert(validFloatRegister(regNum));
 999  _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
1000}
1001
1002inline bool Registers_ppc::validVectorRegister(int regNum) const {
1003  if (regNum < UNW_PPC_V0)
1004    return false;
1005  if (regNum > UNW_PPC_V31)
1006    return false;
1007  return true;
1008}
1009
1010inline v128 Registers_ppc::getVectorRegister(int regNum) const {
1011  assert(validVectorRegister(regNum));
1012  v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
1013  return result;
1014}
1015
1016inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
1017  assert(validVectorRegister(regNum));
1018  _vectorRegisters[regNum - UNW_PPC_V0] = value;
1019}
1020
1021inline const char *Registers_ppc::getRegisterName(int regNum) {
1022  switch (regNum) {
1023  case UNW_REG_IP:
1024    return "ip";
1025  case UNW_REG_SP:
1026    return "sp";
1027  case UNW_PPC_R0:
1028    return "r0";
1029  case UNW_PPC_R1:
1030    return "r1";
1031  case UNW_PPC_R2:
1032    return "r2";
1033  case UNW_PPC_R3:
1034    return "r3";
1035  case UNW_PPC_R4:
1036    return "r4";
1037  case UNW_PPC_R5:
1038    return "r5";
1039  case UNW_PPC_R6:
1040    return "r6";
1041  case UNW_PPC_R7:
1042    return "r7";
1043  case UNW_PPC_R8:
1044    return "r8";
1045  case UNW_PPC_R9:
1046    return "r9";
1047  case UNW_PPC_R10:
1048    return "r10";
1049  case UNW_PPC_R11:
1050    return "r11";
1051  case UNW_PPC_R12:
1052    return "r12";
1053  case UNW_PPC_R13:
1054    return "r13";
1055  case UNW_PPC_R14:
1056    return "r14";
1057  case UNW_PPC_R15:
1058    return "r15";
1059  case UNW_PPC_R16:
1060    return "r16";
1061  case UNW_PPC_R17:
1062    return "r17";
1063  case UNW_PPC_R18:
1064    return "r18";
1065  case UNW_PPC_R19:
1066    return "r19";
1067  case UNW_PPC_R20:
1068    return "r20";
1069  case UNW_PPC_R21:
1070    return "r21";
1071  case UNW_PPC_R22:
1072    return "r22";
1073  case UNW_PPC_R23:
1074    return "r23";
1075  case UNW_PPC_R24:
1076    return "r24";
1077  case UNW_PPC_R25:
1078    return "r25";
1079  case UNW_PPC_R26:
1080    return "r26";
1081  case UNW_PPC_R27:
1082    return "r27";
1083  case UNW_PPC_R28:
1084    return "r28";
1085  case UNW_PPC_R29:
1086    return "r29";
1087  case UNW_PPC_R30:
1088    return "r30";
1089  case UNW_PPC_R31:
1090    return "r31";
1091  case UNW_PPC_F0:
1092    return "fp0";
1093  case UNW_PPC_F1:
1094    return "fp1";
1095  case UNW_PPC_F2:
1096    return "fp2";
1097  case UNW_PPC_F3:
1098    return "fp3";
1099  case UNW_PPC_F4:
1100    return "fp4";
1101  case UNW_PPC_F5:
1102    return "fp5";
1103  case UNW_PPC_F6:
1104    return "fp6";
1105  case UNW_PPC_F7:
1106    return "fp7";
1107  case UNW_PPC_F8:
1108    return "fp8";
1109  case UNW_PPC_F9:
1110    return "fp9";
1111  case UNW_PPC_F10:
1112    return "fp10";
1113  case UNW_PPC_F11:
1114    return "fp11";
1115  case UNW_PPC_F12:
1116    return "fp12";
1117  case UNW_PPC_F13:
1118    return "fp13";
1119  case UNW_PPC_F14:
1120    return "fp14";
1121  case UNW_PPC_F15:
1122    return "fp15";
1123  case UNW_PPC_F16:
1124    return "fp16";
1125  case UNW_PPC_F17:
1126    return "fp17";
1127  case UNW_PPC_F18:
1128    return "fp18";
1129  case UNW_PPC_F19:
1130    return "fp19";
1131  case UNW_PPC_F20:
1132    return "fp20";
1133  case UNW_PPC_F21:
1134    return "fp21";
1135  case UNW_PPC_F22:
1136    return "fp22";
1137  case UNW_PPC_F23:
1138    return "fp23";
1139  case UNW_PPC_F24:
1140    return "fp24";
1141  case UNW_PPC_F25:
1142    return "fp25";
1143  case UNW_PPC_F26:
1144    return "fp26";
1145  case UNW_PPC_F27:
1146    return "fp27";
1147  case UNW_PPC_F28:
1148    return "fp28";
1149  case UNW_PPC_F29:
1150    return "fp29";
1151  case UNW_PPC_F30:
1152    return "fp30";
1153  case UNW_PPC_F31:
1154    return "fp31";
1155  case UNW_PPC_LR:
1156    return "lr";
1157  default:
1158    return "unknown register";
1159  }
1160
1161}
1162#endif // _LIBUNWIND_TARGET_PPC
1163
1164#if defined(_LIBUNWIND_TARGET_PPC64)
1165/// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC
1166/// process.
1167class _LIBUNWIND_HIDDEN Registers_ppc64 {
1168public:
1169  Registers_ppc64();
1170  Registers_ppc64(const void *registers);
1171
1172  bool        validRegister(int num) const;
1173  uint64_t    getRegister(int num) const;
1174  void        setRegister(int num, uint64_t value);
1175  bool        validFloatRegister(int num) const;
1176  double      getFloatRegister(int num) const;
1177  void        setFloatRegister(int num, double value);
1178  bool        validVectorRegister(int num) const;
1179  v128        getVectorRegister(int num) const;
1180  void        setVectorRegister(int num, v128 value);
1181  static const char *getRegisterName(int num);
1182  void        jumpto();
1183  static constexpr int lastDwarfRegNum() {
1184    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64;
1185  }
1186  static int  getArch() { return REGISTERS_PPC64; }
1187
1188  uint64_t  getSP() const         { return _registers.__r1; }
1189  void      setSP(uint64_t value) { _registers.__r1 = value; }
1190  uint64_t  getIP() const         { return _registers.__srr0; }
1191  void      setIP(uint64_t value) { _registers.__srr0 = value; }
1192  uint64_t  getCR() const         { return _registers.__cr; }
1193  void      setCR(uint64_t value) { _registers.__cr = value; }
1194  uint64_t  getLR() const         { return _registers.__lr; }
1195  void      setLR(uint64_t value) { _registers.__lr = value; }
1196
1197private:
1198  struct ppc64_thread_state_t {
1199    uint64_t __srr0;    // Instruction address register (PC)
1200    uint64_t __srr1;    // Machine state register (supervisor)
1201    uint64_t __r0;
1202    uint64_t __r1;
1203    uint64_t __r2;
1204    uint64_t __r3;
1205    uint64_t __r4;
1206    uint64_t __r5;
1207    uint64_t __r6;
1208    uint64_t __r7;
1209    uint64_t __r8;
1210    uint64_t __r9;
1211    uint64_t __r10;
1212    uint64_t __r11;
1213    uint64_t __r12;
1214    uint64_t __r13;
1215    uint64_t __r14;
1216    uint64_t __r15;
1217    uint64_t __r16;
1218    uint64_t __r17;
1219    uint64_t __r18;
1220    uint64_t __r19;
1221    uint64_t __r20;
1222    uint64_t __r21;
1223    uint64_t __r22;
1224    uint64_t __r23;
1225    uint64_t __r24;
1226    uint64_t __r25;
1227    uint64_t __r26;
1228    uint64_t __r27;
1229    uint64_t __r28;
1230    uint64_t __r29;
1231    uint64_t __r30;
1232    uint64_t __r31;
1233    uint64_t __cr;      // Condition register
1234    uint64_t __xer;     // User's integer exception register
1235    uint64_t __lr;      // Link register
1236    uint64_t __ctr;     // Count register
1237    uint64_t __vrsave;  // Vector Save Register
1238  };
1239
1240  union ppc64_vsr_t {
1241    struct asfloat_s {
1242      double f;
1243      uint64_t v2;
1244    } asfloat;
1245    v128 v;
1246  };
1247
1248  ppc64_thread_state_t _registers;
1249  ppc64_vsr_t          _vectorScalarRegisters[64];
1250
1251  static int getVectorRegNum(int num);
1252};
1253
1254inline Registers_ppc64::Registers_ppc64(const void *registers) {
1255  static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit),
1256                "ppc64 registers do not fit into unw_context_t");
1257  memcpy(&_registers, static_cast<const uint8_t *>(registers),
1258         sizeof(_registers));
1259  static_assert(sizeof(_registers) == 312,
1260                "expected vector scalar register offset to be 312");
1261  memcpy(&_vectorScalarRegisters,
1262         static_cast<const uint8_t *>(registers) + sizeof(_registers),
1263         sizeof(_vectorScalarRegisters));
1264  static_assert(sizeof(_registers) +
1265                sizeof(_vectorScalarRegisters) == 1336,
1266                "expected vector register offset to be 1336 bytes");
1267}
1268
1269inline Registers_ppc64::Registers_ppc64() {
1270  memset(&_registers, 0, sizeof(_registers));
1271  memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters));
1272}
1273
1274inline bool Registers_ppc64::validRegister(int regNum) const {
1275  switch (regNum) {
1276  case UNW_REG_IP:
1277  case UNW_REG_SP:
1278  case UNW_PPC64_XER:
1279  case UNW_PPC64_LR:
1280  case UNW_PPC64_CTR:
1281  case UNW_PPC64_VRSAVE:
1282      return true;
1283  }
1284
1285  if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31)
1286    return true;
1287  if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7)
1288    return true;
1289
1290  return false;
1291}
1292
1293inline uint64_t Registers_ppc64::getRegister(int regNum) const {
1294  switch (regNum) {
1295  case UNW_REG_IP:
1296    return _registers.__srr0;
1297  case UNW_PPC64_R0:
1298    return _registers.__r0;
1299  case UNW_PPC64_R1:
1300  case UNW_REG_SP:
1301    return _registers.__r1;
1302  case UNW_PPC64_R2:
1303    return _registers.__r2;
1304  case UNW_PPC64_R3:
1305    return _registers.__r3;
1306  case UNW_PPC64_R4:
1307    return _registers.__r4;
1308  case UNW_PPC64_R5:
1309    return _registers.__r5;
1310  case UNW_PPC64_R6:
1311    return _registers.__r6;
1312  case UNW_PPC64_R7:
1313    return _registers.__r7;
1314  case UNW_PPC64_R8:
1315    return _registers.__r8;
1316  case UNW_PPC64_R9:
1317    return _registers.__r9;
1318  case UNW_PPC64_R10:
1319    return _registers.__r10;
1320  case UNW_PPC64_R11:
1321    return _registers.__r11;
1322  case UNW_PPC64_R12:
1323    return _registers.__r12;
1324  case UNW_PPC64_R13:
1325    return _registers.__r13;
1326  case UNW_PPC64_R14:
1327    return _registers.__r14;
1328  case UNW_PPC64_R15:
1329    return _registers.__r15;
1330  case UNW_PPC64_R16:
1331    return _registers.__r16;
1332  case UNW_PPC64_R17:
1333    return _registers.__r17;
1334  case UNW_PPC64_R18:
1335    return _registers.__r18;
1336  case UNW_PPC64_R19:
1337    return _registers.__r19;
1338  case UNW_PPC64_R20:
1339    return _registers.__r20;
1340  case UNW_PPC64_R21:
1341    return _registers.__r21;
1342  case UNW_PPC64_R22:
1343    return _registers.__r22;
1344  case UNW_PPC64_R23:
1345    return _registers.__r23;
1346  case UNW_PPC64_R24:
1347    return _registers.__r24;
1348  case UNW_PPC64_R25:
1349    return _registers.__r25;
1350  case UNW_PPC64_R26:
1351    return _registers.__r26;
1352  case UNW_PPC64_R27:
1353    return _registers.__r27;
1354  case UNW_PPC64_R28:
1355    return _registers.__r28;
1356  case UNW_PPC64_R29:
1357    return _registers.__r29;
1358  case UNW_PPC64_R30:
1359    return _registers.__r30;
1360  case UNW_PPC64_R31:
1361    return _registers.__r31;
1362  case UNW_PPC64_CR0:
1363    return (_registers.__cr & 0xF0000000);
1364  case UNW_PPC64_CR1:
1365    return (_registers.__cr & 0x0F000000);
1366  case UNW_PPC64_CR2:
1367    return (_registers.__cr & 0x00F00000);
1368  case UNW_PPC64_CR3:
1369    return (_registers.__cr & 0x000F0000);
1370  case UNW_PPC64_CR4:
1371    return (_registers.__cr & 0x0000F000);
1372  case UNW_PPC64_CR5:
1373    return (_registers.__cr & 0x00000F00);
1374  case UNW_PPC64_CR6:
1375    return (_registers.__cr & 0x000000F0);
1376  case UNW_PPC64_CR7:
1377    return (_registers.__cr & 0x0000000F);
1378  case UNW_PPC64_XER:
1379    return _registers.__xer;
1380  case UNW_PPC64_LR:
1381    return _registers.__lr;
1382  case UNW_PPC64_CTR:
1383    return _registers.__ctr;
1384  case UNW_PPC64_VRSAVE:
1385    return _registers.__vrsave;
1386  }
1387  _LIBUNWIND_ABORT("unsupported ppc64 register");
1388}
1389
1390inline void Registers_ppc64::setRegister(int regNum, uint64_t value) {
1391  switch (regNum) {
1392  case UNW_REG_IP:
1393    _registers.__srr0 = value;
1394    return;
1395  case UNW_PPC64_R0:
1396    _registers.__r0 = value;
1397    return;
1398  case UNW_PPC64_R1:
1399  case UNW_REG_SP:
1400    _registers.__r1 = value;
1401    return;
1402  case UNW_PPC64_R2:
1403    _registers.__r2 = value;
1404    return;
1405  case UNW_PPC64_R3:
1406    _registers.__r3 = value;
1407    return;
1408  case UNW_PPC64_R4:
1409    _registers.__r4 = value;
1410    return;
1411  case UNW_PPC64_R5:
1412    _registers.__r5 = value;
1413    return;
1414  case UNW_PPC64_R6:
1415    _registers.__r6 = value;
1416    return;
1417  case UNW_PPC64_R7:
1418    _registers.__r7 = value;
1419    return;
1420  case UNW_PPC64_R8:
1421    _registers.__r8 = value;
1422    return;
1423  case UNW_PPC64_R9:
1424    _registers.__r9 = value;
1425    return;
1426  case UNW_PPC64_R10:
1427    _registers.__r10 = value;
1428    return;
1429  case UNW_PPC64_R11:
1430    _registers.__r11 = value;
1431    return;
1432  case UNW_PPC64_R12:
1433    _registers.__r12 = value;
1434    return;
1435  case UNW_PPC64_R13:
1436    _registers.__r13 = value;
1437    return;
1438  case UNW_PPC64_R14:
1439    _registers.__r14 = value;
1440    return;
1441  case UNW_PPC64_R15:
1442    _registers.__r15 = value;
1443    return;
1444  case UNW_PPC64_R16:
1445    _registers.__r16 = value;
1446    return;
1447  case UNW_PPC64_R17:
1448    _registers.__r17 = value;
1449    return;
1450  case UNW_PPC64_R18:
1451    _registers.__r18 = value;
1452    return;
1453  case UNW_PPC64_R19:
1454    _registers.__r19 = value;
1455    return;
1456  case UNW_PPC64_R20:
1457    _registers.__r20 = value;
1458    return;
1459  case UNW_PPC64_R21:
1460    _registers.__r21 = value;
1461    return;
1462  case UNW_PPC64_R22:
1463    _registers.__r22 = value;
1464    return;
1465  case UNW_PPC64_R23:
1466    _registers.__r23 = value;
1467    return;
1468  case UNW_PPC64_R24:
1469    _registers.__r24 = value;
1470    return;
1471  case UNW_PPC64_R25:
1472    _registers.__r25 = value;
1473    return;
1474  case UNW_PPC64_R26:
1475    _registers.__r26 = value;
1476    return;
1477  case UNW_PPC64_R27:
1478    _registers.__r27 = value;
1479    return;
1480  case UNW_PPC64_R28:
1481    _registers.__r28 = value;
1482    return;
1483  case UNW_PPC64_R29:
1484    _registers.__r29 = value;
1485    return;
1486  case UNW_PPC64_R30:
1487    _registers.__r30 = value;
1488    return;
1489  case UNW_PPC64_R31:
1490    _registers.__r31 = value;
1491    return;
1492  case UNW_PPC64_CR0:
1493    _registers.__cr &= 0x0FFFFFFF;
1494    _registers.__cr |= (value & 0xF0000000);
1495    return;
1496  case UNW_PPC64_CR1:
1497    _registers.__cr &= 0xF0FFFFFF;
1498    _registers.__cr |= (value & 0x0F000000);
1499    return;
1500  case UNW_PPC64_CR2:
1501    _registers.__cr &= 0xFF0FFFFF;
1502    _registers.__cr |= (value & 0x00F00000);
1503    return;
1504  case UNW_PPC64_CR3:
1505    _registers.__cr &= 0xFFF0FFFF;
1506    _registers.__cr |= (value & 0x000F0000);
1507    return;
1508  case UNW_PPC64_CR4:
1509    _registers.__cr &= 0xFFFF0FFF;
1510    _registers.__cr |= (value & 0x0000F000);
1511    return;
1512  case UNW_PPC64_CR5:
1513    _registers.__cr &= 0xFFFFF0FF;
1514    _registers.__cr |= (value & 0x00000F00);
1515    return;
1516  case UNW_PPC64_CR6:
1517    _registers.__cr &= 0xFFFFFF0F;
1518    _registers.__cr |= (value & 0x000000F0);
1519    return;
1520  case UNW_PPC64_CR7:
1521    _registers.__cr &= 0xFFFFFFF0;
1522    _registers.__cr |= (value & 0x0000000F);
1523    return;
1524  case UNW_PPC64_XER:
1525    _registers.__xer = value;
1526    return;
1527  case UNW_PPC64_LR:
1528    _registers.__lr = value;
1529    return;
1530  case UNW_PPC64_CTR:
1531    _registers.__ctr = value;
1532    return;
1533  case UNW_PPC64_VRSAVE:
1534    _registers.__vrsave = value;
1535    return;
1536  }
1537  _LIBUNWIND_ABORT("unsupported ppc64 register");
1538}
1539
1540inline bool Registers_ppc64::validFloatRegister(int regNum) const {
1541  return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31;
1542}
1543
1544inline double Registers_ppc64::getFloatRegister(int regNum) const {
1545  assert(validFloatRegister(regNum));
1546  return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f;
1547}
1548
1549inline void Registers_ppc64::setFloatRegister(int regNum, double value) {
1550  assert(validFloatRegister(regNum));
1551  _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value;
1552}
1553
1554inline bool Registers_ppc64::validVectorRegister(int regNum) const {
1555#if defined(__VSX__)
1556  if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)
1557    return true;
1558  if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)
1559    return true;
1560#elif defined(__ALTIVEC__)
1561  if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)
1562    return true;
1563#endif
1564  return false;
1565}
1566
1567inline int Registers_ppc64::getVectorRegNum(int num)
1568{
1569  if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31)
1570    return num - UNW_PPC64_VS0;
1571  else
1572    return num - UNW_PPC64_VS32 + 32;
1573}
1574
1575inline v128 Registers_ppc64::getVectorRegister(int regNum) const {
1576  assert(validVectorRegister(regNum));
1577  return _vectorScalarRegisters[getVectorRegNum(regNum)].v;
1578}
1579
1580inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) {
1581  assert(validVectorRegister(regNum));
1582  _vectorScalarRegisters[getVectorRegNum(regNum)].v = value;
1583}
1584
1585inline const char *Registers_ppc64::getRegisterName(int regNum) {
1586  switch (regNum) {
1587  case UNW_REG_IP:
1588    return "ip";
1589  case UNW_REG_SP:
1590    return "sp";
1591  case UNW_PPC64_R0:
1592    return "r0";
1593  case UNW_PPC64_R1:
1594    return "r1";
1595  case UNW_PPC64_R2:
1596    return "r2";
1597  case UNW_PPC64_R3:
1598    return "r3";
1599  case UNW_PPC64_R4:
1600    return "r4";
1601  case UNW_PPC64_R5:
1602    return "r5";
1603  case UNW_PPC64_R6:
1604    return "r6";
1605  case UNW_PPC64_R7:
1606    return "r7";
1607  case UNW_PPC64_R8:
1608    return "r8";
1609  case UNW_PPC64_R9:
1610    return "r9";
1611  case UNW_PPC64_R10:
1612    return "r10";
1613  case UNW_PPC64_R11:
1614    return "r11";
1615  case UNW_PPC64_R12:
1616    return "r12";
1617  case UNW_PPC64_R13:
1618    return "r13";
1619  case UNW_PPC64_R14:
1620    return "r14";
1621  case UNW_PPC64_R15:
1622    return "r15";
1623  case UNW_PPC64_R16:
1624    return "r16";
1625  case UNW_PPC64_R17:
1626    return "r17";
1627  case UNW_PPC64_R18:
1628    return "r18";
1629  case UNW_PPC64_R19:
1630    return "r19";
1631  case UNW_PPC64_R20:
1632    return "r20";
1633  case UNW_PPC64_R21:
1634    return "r21";
1635  case UNW_PPC64_R22:
1636    return "r22";
1637  case UNW_PPC64_R23:
1638    return "r23";
1639  case UNW_PPC64_R24:
1640    return "r24";
1641  case UNW_PPC64_R25:
1642    return "r25";
1643  case UNW_PPC64_R26:
1644    return "r26";
1645  case UNW_PPC64_R27:
1646    return "r27";
1647  case UNW_PPC64_R28:
1648    return "r28";
1649  case UNW_PPC64_R29:
1650    return "r29";
1651  case UNW_PPC64_R30:
1652    return "r30";
1653  case UNW_PPC64_R31:
1654    return "r31";
1655  case UNW_PPC64_CR0:
1656    return "cr0";
1657  case UNW_PPC64_CR1:
1658    return "cr1";
1659  case UNW_PPC64_CR2:
1660    return "cr2";
1661  case UNW_PPC64_CR3:
1662    return "cr3";
1663  case UNW_PPC64_CR4:
1664    return "cr4";
1665  case UNW_PPC64_CR5:
1666    return "cr5";
1667  case UNW_PPC64_CR6:
1668    return "cr6";
1669  case UNW_PPC64_CR7:
1670    return "cr7";
1671  case UNW_PPC64_XER:
1672    return "xer";
1673  case UNW_PPC64_LR:
1674    return "lr";
1675  case UNW_PPC64_CTR:
1676    return "ctr";
1677  case UNW_PPC64_VRSAVE:
1678    return "vrsave";
1679  case UNW_PPC64_F0:
1680    return "fp0";
1681  case UNW_PPC64_F1:
1682    return "fp1";
1683  case UNW_PPC64_F2:
1684    return "fp2";
1685  case UNW_PPC64_F3:
1686    return "fp3";
1687  case UNW_PPC64_F4:
1688    return "fp4";
1689  case UNW_PPC64_F5:
1690    return "fp5";
1691  case UNW_PPC64_F6:
1692    return "fp6";
1693  case UNW_PPC64_F7:
1694    return "fp7";
1695  case UNW_PPC64_F8:
1696    return "fp8";
1697  case UNW_PPC64_F9:
1698    return "fp9";
1699  case UNW_PPC64_F10:
1700    return "fp10";
1701  case UNW_PPC64_F11:
1702    return "fp11";
1703  case UNW_PPC64_F12:
1704    return "fp12";
1705  case UNW_PPC64_F13:
1706    return "fp13";
1707  case UNW_PPC64_F14:
1708    return "fp14";
1709  case UNW_PPC64_F15:
1710    return "fp15";
1711  case UNW_PPC64_F16:
1712    return "fp16";
1713  case UNW_PPC64_F17:
1714    return "fp17";
1715  case UNW_PPC64_F18:
1716    return "fp18";
1717  case UNW_PPC64_F19:
1718    return "fp19";
1719  case UNW_PPC64_F20:
1720    return "fp20";
1721  case UNW_PPC64_F21:
1722    return "fp21";
1723  case UNW_PPC64_F22:
1724    return "fp22";
1725  case UNW_PPC64_F23:
1726    return "fp23";
1727  case UNW_PPC64_F24:
1728    return "fp24";
1729  case UNW_PPC64_F25:
1730    return "fp25";
1731  case UNW_PPC64_F26:
1732    return "fp26";
1733  case UNW_PPC64_F27:
1734    return "fp27";
1735  case UNW_PPC64_F28:
1736    return "fp28";
1737  case UNW_PPC64_F29:
1738    return "fp29";
1739  case UNW_PPC64_F30:
1740    return "fp30";
1741  case UNW_PPC64_F31:
1742    return "fp31";
1743  case UNW_PPC64_V0:
1744    return "v0";
1745  case UNW_PPC64_V1:
1746    return "v1";
1747  case UNW_PPC64_V2:
1748    return "v2";
1749  case UNW_PPC64_V3:
1750    return "v3";
1751  case UNW_PPC64_V4:
1752    return "v4";
1753  case UNW_PPC64_V5:
1754    return "v5";
1755  case UNW_PPC64_V6:
1756    return "v6";
1757  case UNW_PPC64_V7:
1758    return "v7";
1759  case UNW_PPC64_V8:
1760    return "v8";
1761  case UNW_PPC64_V9:
1762    return "v9";
1763  case UNW_PPC64_V10:
1764    return "v10";
1765  case UNW_PPC64_V11:
1766    return "v11";
1767  case UNW_PPC64_V12:
1768    return "v12";
1769  case UNW_PPC64_V13:
1770    return "v13";
1771  case UNW_PPC64_V14:
1772    return "v14";
1773  case UNW_PPC64_V15:
1774    return "v15";
1775  case UNW_PPC64_V16:
1776    return "v16";
1777  case UNW_PPC64_V17:
1778    return "v17";
1779  case UNW_PPC64_V18:
1780    return "v18";
1781  case UNW_PPC64_V19:
1782    return "v19";
1783  case UNW_PPC64_V20:
1784    return "v20";
1785  case UNW_PPC64_V21:
1786    return "v21";
1787  case UNW_PPC64_V22:
1788    return "v22";
1789  case UNW_PPC64_V23:
1790    return "v23";
1791  case UNW_PPC64_V24:
1792    return "v24";
1793  case UNW_PPC64_V25:
1794    return "v25";
1795  case UNW_PPC64_V26:
1796    return "v26";
1797  case UNW_PPC64_V27:
1798    return "v27";
1799  case UNW_PPC64_V28:
1800    return "v28";
1801  case UNW_PPC64_V29:
1802    return "v29";
1803  case UNW_PPC64_V30:
1804    return "v30";
1805  case UNW_PPC64_V31:
1806    return "v31";
1807  }
1808  return "unknown register";
1809}
1810#endif // _LIBUNWIND_TARGET_PPC64
1811
1812
1813#if defined(_LIBUNWIND_TARGET_AARCH64)
1814/// Registers_arm64  holds the register state of a thread in a 64-bit arm
1815/// process.
1816class _LIBUNWIND_HIDDEN Registers_arm64;
1817extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
1818
1819#if defined(_LIBUNWIND_USE_GCS)
1820extern "C" void *__libunwind_shstk_get_jump_target() {
1821  return reinterpret_cast<void *>(&__libunwind_Registers_arm64_jumpto);
1822}
1823#endif
1824
1825class _LIBUNWIND_HIDDEN Registers_arm64 {
1826public:
1827  Registers_arm64();
1828  Registers_arm64(const void *registers);
1829
1830  bool        validRegister(int num) const;
1831  uint64_t    getRegister(int num) const;
1832  void        setRegister(int num, uint64_t value);
1833  bool        validFloatRegister(int num) const;
1834  double      getFloatRegister(int num) const;
1835  void        setFloatRegister(int num, double value);
1836  bool        validVectorRegister(int num) const;
1837  v128        getVectorRegister(int num) const;
1838  void        setVectorRegister(int num, v128 value);
1839  static const char *getRegisterName(int num);
1840  void        jumpto() { __libunwind_Registers_arm64_jumpto(this); }
1841  static constexpr int lastDwarfRegNum() {
1842    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64;
1843  }
1844  static int  getArch() { return REGISTERS_ARM64; }
1845
1846  uint64_t  getSP() const         { return _registers.__sp; }
1847  void      setSP(uint64_t value) { _registers.__sp = value; }
1848  uint64_t  getIP() const         { return _registers.__pc; }
1849  void      setIP(uint64_t value) { _registers.__pc = value; }
1850  uint64_t  getFP() const         { return _registers.__fp; }
1851  void      setFP(uint64_t value) { _registers.__fp = value; }
1852
1853private:
1854  struct GPRs {
1855    uint64_t __x[29]; // x0-x28
1856    uint64_t __fp;    // Frame pointer x29
1857    uint64_t __lr;    // Link register x30
1858    uint64_t __sp;    // Stack pointer x31
1859    uint64_t __pc;    // Program counter
1860    uint64_t __ra_sign_state; // RA sign state register
1861  };
1862
1863  GPRs    _registers;
1864  double  _vectorHalfRegisters[32];
1865  // Currently only the lower double in 128-bit vectore registers
1866  // is perserved during unwinding.  We could define new register
1867  // numbers (> 96) which mean whole vector registers, then this
1868  // struct would need to change to contain whole vector registers.
1869};
1870
1871inline Registers_arm64::Registers_arm64(const void *registers) {
1872  static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
1873                "arm64 registers do not fit into unw_context_t");
1874  memcpy(&_registers, registers, sizeof(_registers));
1875  static_assert(sizeof(GPRs) == 0x110,
1876                "expected VFP registers to be at offset 272");
1877  memcpy(_vectorHalfRegisters,
1878         static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1879         sizeof(_vectorHalfRegisters));
1880}
1881
1882inline Registers_arm64::Registers_arm64() {
1883  memset(&_registers, 0, sizeof(_registers));
1884  memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1885}
1886
1887inline bool Registers_arm64::validRegister(int regNum) const {
1888  if (regNum == UNW_REG_IP)
1889    return true;
1890  if (regNum == UNW_REG_SP)
1891    return true;
1892  if (regNum < 0)
1893    return false;
1894  if (regNum > 95)
1895    return false;
1896  if (regNum == UNW_AARCH64_RA_SIGN_STATE)
1897    return true;
1898  if ((regNum > 32) && (regNum < 64))
1899    return false;
1900  return true;
1901}
1902
1903inline uint64_t Registers_arm64::getRegister(int regNum) const {
1904  if (regNum == UNW_REG_IP || regNum == UNW_AARCH64_PC)
1905    return _registers.__pc;
1906  if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP)
1907    return _registers.__sp;
1908  if (regNum == UNW_AARCH64_RA_SIGN_STATE)
1909    return _registers.__ra_sign_state;
1910  if (regNum == UNW_AARCH64_FP)
1911    return _registers.__fp;
1912  if (regNum == UNW_AARCH64_LR)
1913    return _registers.__lr;
1914  if ((regNum >= 0) && (regNum < 29))
1915    return _registers.__x[regNum];
1916  _LIBUNWIND_ABORT("unsupported arm64 register");
1917}
1918
1919inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1920  if (regNum == UNW_REG_IP || regNum == UNW_AARCH64_PC)
1921    _registers.__pc = value;
1922  else if (regNum == UNW_REG_SP || regNum == UNW_AARCH64_SP)
1923    _registers.__sp = value;
1924  else if (regNum == UNW_AARCH64_RA_SIGN_STATE)
1925    _registers.__ra_sign_state = value;
1926  else if (regNum == UNW_AARCH64_FP)
1927    _registers.__fp = value;
1928  else if (regNum == UNW_AARCH64_LR)
1929    _registers.__lr = value;
1930  else if ((regNum >= 0) && (regNum < 29))
1931    _registers.__x[regNum] = value;
1932  else
1933    _LIBUNWIND_ABORT("unsupported arm64 register");
1934}
1935
1936inline const char *Registers_arm64::getRegisterName(int regNum) {
1937  switch (regNum) {
1938  case UNW_REG_IP:
1939    return "pc";
1940  case UNW_REG_SP:
1941    return "sp";
1942  case UNW_AARCH64_X0:
1943    return "x0";
1944  case UNW_AARCH64_X1:
1945    return "x1";
1946  case UNW_AARCH64_X2:
1947    return "x2";
1948  case UNW_AARCH64_X3:
1949    return "x3";
1950  case UNW_AARCH64_X4:
1951    return "x4";
1952  case UNW_AARCH64_X5:
1953    return "x5";
1954  case UNW_AARCH64_X6:
1955    return "x6";
1956  case UNW_AARCH64_X7:
1957    return "x7";
1958  case UNW_AARCH64_X8:
1959    return "x8";
1960  case UNW_AARCH64_X9:
1961    return "x9";
1962  case UNW_AARCH64_X10:
1963    return "x10";
1964  case UNW_AARCH64_X11:
1965    return "x11";
1966  case UNW_AARCH64_X12:
1967    return "x12";
1968  case UNW_AARCH64_X13:
1969    return "x13";
1970  case UNW_AARCH64_X14:
1971    return "x14";
1972  case UNW_AARCH64_X15:
1973    return "x15";
1974  case UNW_AARCH64_X16:
1975    return "x16";
1976  case UNW_AARCH64_X17:
1977    return "x17";
1978  case UNW_AARCH64_X18:
1979    return "x18";
1980  case UNW_AARCH64_X19:
1981    return "x19";
1982  case UNW_AARCH64_X20:
1983    return "x20";
1984  case UNW_AARCH64_X21:
1985    return "x21";
1986  case UNW_AARCH64_X22:
1987    return "x22";
1988  case UNW_AARCH64_X23:
1989    return "x23";
1990  case UNW_AARCH64_X24:
1991    return "x24";
1992  case UNW_AARCH64_X25:
1993    return "x25";
1994  case UNW_AARCH64_X26:
1995    return "x26";
1996  case UNW_AARCH64_X27:
1997    return "x27";
1998  case UNW_AARCH64_X28:
1999    return "x28";
2000  case UNW_AARCH64_FP:
2001    return "fp";
2002  case UNW_AARCH64_LR:
2003    return "lr";
2004  case UNW_AARCH64_SP:
2005    return "sp";
2006  case UNW_AARCH64_PC:
2007    return "pc";
2008  case UNW_AARCH64_V0:
2009    return "d0";
2010  case UNW_AARCH64_V1:
2011    return "d1";
2012  case UNW_AARCH64_V2:
2013    return "d2";
2014  case UNW_AARCH64_V3:
2015    return "d3";
2016  case UNW_AARCH64_V4:
2017    return "d4";
2018  case UNW_AARCH64_V5:
2019    return "d5";
2020  case UNW_AARCH64_V6:
2021    return "d6";
2022  case UNW_AARCH64_V7:
2023    return "d7";
2024  case UNW_AARCH64_V8:
2025    return "d8";
2026  case UNW_AARCH64_V9:
2027    return "d9";
2028  case UNW_AARCH64_V10:
2029    return "d10";
2030  case UNW_AARCH64_V11:
2031    return "d11";
2032  case UNW_AARCH64_V12:
2033    return "d12";
2034  case UNW_AARCH64_V13:
2035    return "d13";
2036  case UNW_AARCH64_V14:
2037    return "d14";
2038  case UNW_AARCH64_V15:
2039    return "d15";
2040  case UNW_AARCH64_V16:
2041    return "d16";
2042  case UNW_AARCH64_V17:
2043    return "d17";
2044  case UNW_AARCH64_V18:
2045    return "d18";
2046  case UNW_AARCH64_V19:
2047    return "d19";
2048  case UNW_AARCH64_V20:
2049    return "d20";
2050  case UNW_AARCH64_V21:
2051    return "d21";
2052  case UNW_AARCH64_V22:
2053    return "d22";
2054  case UNW_AARCH64_V23:
2055    return "d23";
2056  case UNW_AARCH64_V24:
2057    return "d24";
2058  case UNW_AARCH64_V25:
2059    return "d25";
2060  case UNW_AARCH64_V26:
2061    return "d26";
2062  case UNW_AARCH64_V27:
2063    return "d27";
2064  case UNW_AARCH64_V28:
2065    return "d28";
2066  case UNW_AARCH64_V29:
2067    return "d29";
2068  case UNW_AARCH64_V30:
2069    return "d30";
2070  case UNW_AARCH64_V31:
2071    return "d31";
2072  default:
2073    return "unknown register";
2074  }
2075}
2076
2077inline bool Registers_arm64::validFloatRegister(int regNum) const {
2078  if (regNum < UNW_AARCH64_V0)
2079    return false;
2080  if (regNum > UNW_AARCH64_V31)
2081    return false;
2082  return true;
2083}
2084
2085inline double Registers_arm64::getFloatRegister(int regNum) const {
2086  assert(validFloatRegister(regNum));
2087  return _vectorHalfRegisters[regNum - UNW_AARCH64_V0];
2088}
2089
2090inline void Registers_arm64::setFloatRegister(int regNum, double value) {
2091  assert(validFloatRegister(regNum));
2092  _vectorHalfRegisters[regNum - UNW_AARCH64_V0] = value;
2093}
2094
2095inline bool Registers_arm64::validVectorRegister(int) const {
2096  return false;
2097}
2098
2099inline v128 Registers_arm64::getVectorRegister(int) const {
2100  _LIBUNWIND_ABORT("no arm64 vector register support yet");
2101}
2102
2103inline void Registers_arm64::setVectorRegister(int, v128) {
2104  _LIBUNWIND_ABORT("no arm64 vector register support yet");
2105}
2106#endif // _LIBUNWIND_TARGET_AARCH64
2107
2108#if defined(_LIBUNWIND_TARGET_ARM)
2109/// Registers_arm holds the register state of a thread in a 32-bit arm
2110/// process.
2111///
2112/// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
2113/// this uses more memory than required.
2114class _LIBUNWIND_HIDDEN Registers_arm {
2115public:
2116  Registers_arm();
2117  Registers_arm(const void *registers);
2118
2119  bool        validRegister(int num) const;
2120  uint32_t    getRegister(int num) const;
2121  void        setRegister(int num, uint32_t value);
2122  bool        validFloatRegister(int num) const;
2123  unw_fpreg_t getFloatRegister(int num);
2124  void        setFloatRegister(int num, unw_fpreg_t value);
2125  bool        validVectorRegister(int num) const;
2126  v128        getVectorRegister(int num) const;
2127  void        setVectorRegister(int num, v128 value);
2128  static const char *getRegisterName(int num);
2129  void        jumpto() {
2130    restoreSavedFloatRegisters();
2131    restoreCoreAndJumpTo();
2132  }
2133  static constexpr int lastDwarfRegNum() {
2134    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM;
2135  }
2136  static int  getArch() { return REGISTERS_ARM; }
2137
2138  uint32_t  getSP() const         { return _registers.__sp; }
2139  void      setSP(uint32_t value) { _registers.__sp = value; }
2140  uint32_t  getIP() const         { return _registers.__pc; }
2141  void      setIP(uint32_t value) { _registers.__pc = value; }
2142
2143  void saveVFPAsX() {
2144    assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
2145    _use_X_for_vfp_save = true;
2146  }
2147
2148  void restoreSavedFloatRegisters() {
2149    if (_saved_vfp_d0_d15) {
2150      if (_use_X_for_vfp_save)
2151        restoreVFPWithFLDMX(_vfp_d0_d15_pad);
2152      else
2153        restoreVFPWithFLDMD(_vfp_d0_d15_pad);
2154    }
2155    if (_saved_vfp_d16_d31)
2156      restoreVFPv3(_vfp_d16_d31);
2157#if defined(__ARM_WMMX)
2158    if (_saved_iwmmx)
2159      restoreiWMMX(_iwmmx);
2160    if (_saved_iwmmx_control)
2161      restoreiWMMXControl(_iwmmx_control);
2162#endif
2163  }
2164
2165private:
2166  struct GPRs {
2167    uint32_t __r[13]; // r0-r12
2168    uint32_t __sp;    // Stack pointer r13
2169    uint32_t __lr;    // Link register r14
2170    uint32_t __pc;    // Program counter r15
2171  };
2172
2173  struct PseudoRegisters {
2174    uint32_t __pac; // Return Authentication Code (PAC)
2175  };
2176
2177  static void saveVFPWithFSTMD(void*);
2178  static void saveVFPWithFSTMX(void*);
2179  static void saveVFPv3(void*);
2180  static void restoreVFPWithFLDMD(void*);
2181  static void restoreVFPWithFLDMX(void*);
2182  static void restoreVFPv3(void*);
2183#if defined(__ARM_WMMX)
2184  static void saveiWMMX(void*);
2185  static void saveiWMMXControl(uint32_t*);
2186  static void restoreiWMMX(void*);
2187  static void restoreiWMMXControl(uint32_t*);
2188#endif
2189  void restoreCoreAndJumpTo();
2190
2191  // ARM registers
2192  GPRs _registers;
2193  PseudoRegisters _pseudo_registers;
2194
2195  // We save floating point registers lazily because we can't know ahead of
2196  // time which ones are used. See EHABI #4.7.
2197
2198  // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
2199  //
2200  // See EHABI #7.5 that explains how matching instruction sequences for load
2201  // and store need to be used to correctly restore the exact register bits.
2202  bool _use_X_for_vfp_save;
2203  // Whether VFP D0-D15 are saved.
2204  bool _saved_vfp_d0_d15;
2205  // Whether VFPv3 D16-D31 are saved.
2206  bool _saved_vfp_d16_d31;
2207  // VFP registers D0-D15, + padding if saved using FSTMX
2208  unw_fpreg_t _vfp_d0_d15_pad[17];
2209  // VFPv3 registers D16-D31, always saved using FSTMD
2210  unw_fpreg_t _vfp_d16_d31[16];
2211#if defined(__ARM_WMMX)
2212  // Whether iWMMX data registers are saved.
2213  bool _saved_iwmmx;
2214  // Whether iWMMX control registers are saved.
2215  mutable bool _saved_iwmmx_control;
2216  // iWMMX registers
2217  unw_fpreg_t _iwmmx[16];
2218  // iWMMX control registers
2219  mutable uint32_t _iwmmx_control[4];
2220#endif
2221};
2222
2223inline Registers_arm::Registers_arm(const void *registers)
2224  : _use_X_for_vfp_save(false),
2225    _saved_vfp_d0_d15(false),
2226    _saved_vfp_d16_d31(false) {
2227  static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
2228                "arm registers do not fit into unw_context_t");
2229  // See __unw_getcontext() note about data.
2230  memcpy(&_registers, registers, sizeof(_registers));
2231  memset(&_pseudo_registers, 0, sizeof(_pseudo_registers));
2232  memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2233  memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2234#if defined(__ARM_WMMX)
2235  _saved_iwmmx = false;
2236  _saved_iwmmx_control = false;
2237  memset(&_iwmmx, 0, sizeof(_iwmmx));
2238  memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2239#endif
2240}
2241
2242inline Registers_arm::Registers_arm()
2243  : _use_X_for_vfp_save(false),
2244    _saved_vfp_d0_d15(false),
2245    _saved_vfp_d16_d31(false) {
2246  memset(&_registers, 0, sizeof(_registers));
2247  memset(&_pseudo_registers, 0, sizeof(_pseudo_registers));
2248  memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2249  memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2250#if defined(__ARM_WMMX)
2251  _saved_iwmmx = false;
2252  _saved_iwmmx_control = false;
2253  memset(&_iwmmx, 0, sizeof(_iwmmx));
2254  memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2255#endif
2256}
2257
2258inline bool Registers_arm::validRegister(int regNum) const {
2259  // Returns true for all non-VFP registers supported by the EHABI
2260  // virtual register set (VRS).
2261  if (regNum == UNW_REG_IP)
2262    return true;
2263
2264  if (regNum == UNW_REG_SP)
2265    return true;
2266
2267  if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
2268    return true;
2269
2270#if defined(__ARM_WMMX)
2271  if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
2272    return true;
2273#endif
2274
2275#ifdef __ARM_FEATURE_PAUTH
2276  if (regNum == UNW_ARM_RA_AUTH_CODE)
2277    return true;
2278#endif
2279
2280  return false;
2281}
2282
2283inline uint32_t Registers_arm::getRegister(int regNum) const {
2284  if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
2285    return _registers.__sp;
2286
2287  if (regNum == UNW_ARM_LR)
2288    return _registers.__lr;
2289
2290  if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
2291    return _registers.__pc;
2292
2293  if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
2294    return _registers.__r[regNum];
2295
2296#if defined(__ARM_WMMX)
2297  if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2298    if (!_saved_iwmmx_control) {
2299      _saved_iwmmx_control = true;
2300      saveiWMMXControl(_iwmmx_control);
2301    }
2302    return _iwmmx_control[regNum - UNW_ARM_WC0];
2303  }
2304#endif
2305
2306#ifdef __ARM_FEATURE_PAUTH
2307  if (regNum == UNW_ARM_RA_AUTH_CODE)
2308    return _pseudo_registers.__pac;
2309#endif
2310
2311  _LIBUNWIND_ABORT("unsupported arm register");
2312}
2313
2314inline void Registers_arm::setRegister(int regNum, uint32_t value) {
2315  if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
2316    _registers.__sp = value;
2317    return;
2318  }
2319
2320  if (regNum == UNW_ARM_LR) {
2321    _registers.__lr = value;
2322    return;
2323  }
2324
2325  if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
2326    _registers.__pc = value;
2327    return;
2328  }
2329
2330  if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
2331    _registers.__r[regNum] = value;
2332    return;
2333  }
2334
2335#if defined(__ARM_WMMX)
2336  if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2337    if (!_saved_iwmmx_control) {
2338      _saved_iwmmx_control = true;
2339      saveiWMMXControl(_iwmmx_control);
2340    }
2341    _iwmmx_control[regNum - UNW_ARM_WC0] = value;
2342    return;
2343  }
2344#endif
2345
2346  if (regNum == UNW_ARM_RA_AUTH_CODE) {
2347    _pseudo_registers.__pac = value;
2348    return;
2349  }
2350
2351  _LIBUNWIND_ABORT("unsupported arm register");
2352}
2353
2354inline const char *Registers_arm::getRegisterName(int regNum) {
2355  switch (regNum) {
2356  case UNW_REG_IP:
2357  case UNW_ARM_IP: // UNW_ARM_R15 is alias
2358    return "pc";
2359  case UNW_ARM_LR: // UNW_ARM_R14 is alias
2360    return "lr";
2361  case UNW_REG_SP:
2362  case UNW_ARM_SP: // UNW_ARM_R13 is alias
2363    return "sp";
2364  case UNW_ARM_R0:
2365    return "r0";
2366  case UNW_ARM_R1:
2367    return "r1";
2368  case UNW_ARM_R2:
2369    return "r2";
2370  case UNW_ARM_R3:
2371    return "r3";
2372  case UNW_ARM_R4:
2373    return "r4";
2374  case UNW_ARM_R5:
2375    return "r5";
2376  case UNW_ARM_R6:
2377    return "r6";
2378  case UNW_ARM_R7:
2379    return "r7";
2380  case UNW_ARM_R8:
2381    return "r8";
2382  case UNW_ARM_R9:
2383    return "r9";
2384  case UNW_ARM_R10:
2385    return "r10";
2386  case UNW_ARM_R11:
2387    return "r11";
2388  case UNW_ARM_R12:
2389    return "r12";
2390  case UNW_ARM_S0:
2391    return "s0";
2392  case UNW_ARM_S1:
2393    return "s1";
2394  case UNW_ARM_S2:
2395    return "s2";
2396  case UNW_ARM_S3:
2397    return "s3";
2398  case UNW_ARM_S4:
2399    return "s4";
2400  case UNW_ARM_S5:
2401    return "s5";
2402  case UNW_ARM_S6:
2403    return "s6";
2404  case UNW_ARM_S7:
2405    return "s7";
2406  case UNW_ARM_S8:
2407    return "s8";
2408  case UNW_ARM_S9:
2409    return "s9";
2410  case UNW_ARM_S10:
2411    return "s10";
2412  case UNW_ARM_S11:
2413    return "s11";
2414  case UNW_ARM_S12:
2415    return "s12";
2416  case UNW_ARM_S13:
2417    return "s13";
2418  case UNW_ARM_S14:
2419    return "s14";
2420  case UNW_ARM_S15:
2421    return "s15";
2422  case UNW_ARM_S16:
2423    return "s16";
2424  case UNW_ARM_S17:
2425    return "s17";
2426  case UNW_ARM_S18:
2427    return "s18";
2428  case UNW_ARM_S19:
2429    return "s19";
2430  case UNW_ARM_S20:
2431    return "s20";
2432  case UNW_ARM_S21:
2433    return "s21";
2434  case UNW_ARM_S22:
2435    return "s22";
2436  case UNW_ARM_S23:
2437    return "s23";
2438  case UNW_ARM_S24:
2439    return "s24";
2440  case UNW_ARM_S25:
2441    return "s25";
2442  case UNW_ARM_S26:
2443    return "s26";
2444  case UNW_ARM_S27:
2445    return "s27";
2446  case UNW_ARM_S28:
2447    return "s28";
2448  case UNW_ARM_S29:
2449    return "s29";
2450  case UNW_ARM_S30:
2451    return "s30";
2452  case UNW_ARM_S31:
2453    return "s31";
2454  case UNW_ARM_D0:
2455    return "d0";
2456  case UNW_ARM_D1:
2457    return "d1";
2458  case UNW_ARM_D2:
2459    return "d2";
2460  case UNW_ARM_D3:
2461    return "d3";
2462  case UNW_ARM_D4:
2463    return "d4";
2464  case UNW_ARM_D5:
2465    return "d5";
2466  case UNW_ARM_D6:
2467    return "d6";
2468  case UNW_ARM_D7:
2469    return "d7";
2470  case UNW_ARM_D8:
2471    return "d8";
2472  case UNW_ARM_D9:
2473    return "d9";
2474  case UNW_ARM_D10:
2475    return "d10";
2476  case UNW_ARM_D11:
2477    return "d11";
2478  case UNW_ARM_D12:
2479    return "d12";
2480  case UNW_ARM_D13:
2481    return "d13";
2482  case UNW_ARM_D14:
2483    return "d14";
2484  case UNW_ARM_D15:
2485    return "d15";
2486  case UNW_ARM_D16:
2487    return "d16";
2488  case UNW_ARM_D17:
2489    return "d17";
2490  case UNW_ARM_D18:
2491    return "d18";
2492  case UNW_ARM_D19:
2493    return "d19";
2494  case UNW_ARM_D20:
2495    return "d20";
2496  case UNW_ARM_D21:
2497    return "d21";
2498  case UNW_ARM_D22:
2499    return "d22";
2500  case UNW_ARM_D23:
2501    return "d23";
2502  case UNW_ARM_D24:
2503    return "d24";
2504  case UNW_ARM_D25:
2505    return "d25";
2506  case UNW_ARM_D26:
2507    return "d26";
2508  case UNW_ARM_D27:
2509    return "d27";
2510  case UNW_ARM_D28:
2511    return "d28";
2512  case UNW_ARM_D29:
2513    return "d29";
2514  case UNW_ARM_D30:
2515    return "d30";
2516  case UNW_ARM_D31:
2517    return "d31";
2518  default:
2519    return "unknown register";
2520  }
2521}
2522
2523inline bool Registers_arm::validFloatRegister(int regNum) const {
2524  // NOTE: Consider the intel MMX registers floating points so the
2525  // __unw_get_fpreg can be used to transmit the 64-bit data back.
2526  return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
2527#if defined(__ARM_WMMX)
2528      || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
2529#endif
2530      ;
2531}
2532
2533inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
2534  if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2535    if (!_saved_vfp_d0_d15) {
2536      _saved_vfp_d0_d15 = true;
2537      if (_use_X_for_vfp_save)
2538        saveVFPWithFSTMX(_vfp_d0_d15_pad);
2539      else
2540        saveVFPWithFSTMD(_vfp_d0_d15_pad);
2541    }
2542    return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
2543  }
2544
2545  if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2546    if (!_saved_vfp_d16_d31) {
2547      _saved_vfp_d16_d31 = true;
2548      saveVFPv3(_vfp_d16_d31);
2549    }
2550    return _vfp_d16_d31[regNum - UNW_ARM_D16];
2551  }
2552
2553#if defined(__ARM_WMMX)
2554  if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2555    if (!_saved_iwmmx) {
2556      _saved_iwmmx = true;
2557      saveiWMMX(_iwmmx);
2558    }
2559    return _iwmmx[regNum - UNW_ARM_WR0];
2560  }
2561#endif
2562
2563  _LIBUNWIND_ABORT("Unknown ARM float register");
2564}
2565
2566inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
2567  if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2568    if (!_saved_vfp_d0_d15) {
2569      _saved_vfp_d0_d15 = true;
2570      if (_use_X_for_vfp_save)
2571        saveVFPWithFSTMX(_vfp_d0_d15_pad);
2572      else
2573        saveVFPWithFSTMD(_vfp_d0_d15_pad);
2574    }
2575    _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
2576    return;
2577  }
2578
2579  if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2580    if (!_saved_vfp_d16_d31) {
2581      _saved_vfp_d16_d31 = true;
2582      saveVFPv3(_vfp_d16_d31);
2583    }
2584    _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
2585    return;
2586  }
2587
2588#if defined(__ARM_WMMX)
2589  if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2590    if (!_saved_iwmmx) {
2591      _saved_iwmmx = true;
2592      saveiWMMX(_iwmmx);
2593    }
2594    _iwmmx[regNum - UNW_ARM_WR0] = value;
2595    return;
2596  }
2597#endif
2598
2599  _LIBUNWIND_ABORT("Unknown ARM float register");
2600}
2601
2602inline bool Registers_arm::validVectorRegister(int) const {
2603  return false;
2604}
2605
2606inline v128 Registers_arm::getVectorRegister(int) const {
2607  _LIBUNWIND_ABORT("ARM vector support not implemented");
2608}
2609
2610inline void Registers_arm::setVectorRegister(int, v128) {
2611  _LIBUNWIND_ABORT("ARM vector support not implemented");
2612}
2613#endif // _LIBUNWIND_TARGET_ARM
2614
2615
2616#if defined(_LIBUNWIND_TARGET_OR1K)
2617/// Registers_or1k holds the register state of a thread in an OpenRISC1000
2618/// process.
2619class _LIBUNWIND_HIDDEN Registers_or1k {
2620public:
2621  Registers_or1k();
2622  Registers_or1k(const void *registers);
2623
2624  bool        validRegister(int num) const;
2625  uint32_t    getRegister(int num) const;
2626  void        setRegister(int num, uint32_t value);
2627  bool        validFloatRegister(int num) const;
2628  double      getFloatRegister(int num) const;
2629  void        setFloatRegister(int num, double value);
2630  bool        validVectorRegister(int num) const;
2631  v128        getVectorRegister(int num) const;
2632  void        setVectorRegister(int num, v128 value);
2633  static const char *getRegisterName(int num);
2634  void        jumpto();
2635  static constexpr int lastDwarfRegNum() {
2636    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K;
2637  }
2638  static int  getArch() { return REGISTERS_OR1K; }
2639
2640  uint64_t  getSP() const         { return _registers.__r[1]; }
2641  void      setSP(uint32_t value) { _registers.__r[1] = value; }
2642  uint64_t  getIP() const         { return _registers.__pc; }
2643  void      setIP(uint32_t value) { _registers.__pc = value; }
2644
2645private:
2646  struct or1k_thread_state_t {
2647    unsigned int __r[32]; // r0-r31
2648    unsigned int __pc;    // Program counter
2649    unsigned int __epcr;  // Program counter at exception
2650  };
2651
2652  or1k_thread_state_t _registers;
2653};
2654
2655inline Registers_or1k::Registers_or1k(const void *registers) {
2656  static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
2657                "or1k registers do not fit into unw_context_t");
2658  memcpy(&_registers, static_cast<const uint8_t *>(registers),
2659         sizeof(_registers));
2660}
2661
2662inline Registers_or1k::Registers_or1k() {
2663  memset(&_registers, 0, sizeof(_registers));
2664}
2665
2666inline bool Registers_or1k::validRegister(int regNum) const {
2667  if (regNum == UNW_REG_IP)
2668    return true;
2669  if (regNum == UNW_REG_SP)
2670    return true;
2671  if (regNum < 0)
2672    return false;
2673  if (regNum <= UNW_OR1K_R31)
2674    return true;
2675  if (regNum == UNW_OR1K_EPCR)
2676    return true;
2677  return false;
2678}
2679
2680inline uint32_t Registers_or1k::getRegister(int regNum) const {
2681  if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
2682    return _registers.__r[regNum - UNW_OR1K_R0];
2683
2684  switch (regNum) {
2685  case UNW_REG_IP:
2686    return _registers.__pc;
2687  case UNW_REG_SP:
2688    return _registers.__r[1];
2689  case UNW_OR1K_EPCR:
2690    return _registers.__epcr;
2691  }
2692  _LIBUNWIND_ABORT("unsupported or1k register");
2693}
2694
2695inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
2696  if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
2697    _registers.__r[regNum - UNW_OR1K_R0] = value;
2698    return;
2699  }
2700
2701  switch (regNum) {
2702  case UNW_REG_IP:
2703    _registers.__pc = value;
2704    return;
2705  case UNW_REG_SP:
2706    _registers.__r[1] = value;
2707    return;
2708  case UNW_OR1K_EPCR:
2709    _registers.__epcr = value;
2710    return;
2711  }
2712  _LIBUNWIND_ABORT("unsupported or1k register");
2713}
2714
2715inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
2716  return false;
2717}
2718
2719inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
2720  _LIBUNWIND_ABORT("or1k float support not implemented");
2721}
2722
2723inline void Registers_or1k::setFloatRegister(int /* regNum */,
2724                                             double /* value */) {
2725  _LIBUNWIND_ABORT("or1k float support not implemented");
2726}
2727
2728inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
2729  return false;
2730}
2731
2732inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
2733  _LIBUNWIND_ABORT("or1k vector support not implemented");
2734}
2735
2736inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
2737  _LIBUNWIND_ABORT("or1k vector support not implemented");
2738}
2739
2740inline const char *Registers_or1k::getRegisterName(int regNum) {
2741  switch (regNum) {
2742  case UNW_OR1K_R0:
2743    return "r0";
2744  case UNW_OR1K_R1:
2745    return "r1";
2746  case UNW_OR1K_R2:
2747    return "r2";
2748  case UNW_OR1K_R3:
2749    return "r3";
2750  case UNW_OR1K_R4:
2751    return "r4";
2752  case UNW_OR1K_R5:
2753    return "r5";
2754  case UNW_OR1K_R6:
2755    return "r6";
2756  case UNW_OR1K_R7:
2757    return "r7";
2758  case UNW_OR1K_R8:
2759    return "r8";
2760  case UNW_OR1K_R9:
2761    return "r9";
2762  case UNW_OR1K_R10:
2763    return "r10";
2764  case UNW_OR1K_R11:
2765    return "r11";
2766  case UNW_OR1K_R12:
2767    return "r12";
2768  case UNW_OR1K_R13:
2769    return "r13";
2770  case UNW_OR1K_R14:
2771    return "r14";
2772  case UNW_OR1K_R15:
2773    return "r15";
2774  case UNW_OR1K_R16:
2775    return "r16";
2776  case UNW_OR1K_R17:
2777    return "r17";
2778  case UNW_OR1K_R18:
2779    return "r18";
2780  case UNW_OR1K_R19:
2781    return "r19";
2782  case UNW_OR1K_R20:
2783    return "r20";
2784  case UNW_OR1K_R21:
2785    return "r21";
2786  case UNW_OR1K_R22:
2787    return "r22";
2788  case UNW_OR1K_R23:
2789    return "r23";
2790  case UNW_OR1K_R24:
2791    return "r24";
2792  case UNW_OR1K_R25:
2793    return "r25";
2794  case UNW_OR1K_R26:
2795    return "r26";
2796  case UNW_OR1K_R27:
2797    return "r27";
2798  case UNW_OR1K_R28:
2799    return "r28";
2800  case UNW_OR1K_R29:
2801    return "r29";
2802  case UNW_OR1K_R30:
2803    return "r30";
2804  case UNW_OR1K_R31:
2805    return "r31";
2806  case UNW_OR1K_EPCR:
2807    return "EPCR";
2808  default:
2809    return "unknown register";
2810  }
2811
2812}
2813#endif // _LIBUNWIND_TARGET_OR1K
2814
2815#if defined(_LIBUNWIND_TARGET_MIPS_O32)
2816/// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
2817/// process.
2818class _LIBUNWIND_HIDDEN Registers_mips_o32 {
2819public:
2820  Registers_mips_o32();
2821  Registers_mips_o32(const void *registers);
2822
2823  bool        validRegister(int num) const;
2824  uint32_t    getRegister(int num) const;
2825  void        setRegister(int num, uint32_t value);
2826  bool        validFloatRegister(int num) const;
2827  double      getFloatRegister(int num) const;
2828  void        setFloatRegister(int num, double value);
2829  bool        validVectorRegister(int num) const;
2830  v128        getVectorRegister(int num) const;
2831  void        setVectorRegister(int num, v128 value);
2832  static const char *getRegisterName(int num);
2833  void        jumpto();
2834  static constexpr int lastDwarfRegNum() {
2835    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS;
2836  }
2837  static int  getArch() { return REGISTERS_MIPS_O32; }
2838
2839  uint32_t  getSP() const         { return _registers.__r[29]; }
2840  void      setSP(uint32_t value) { _registers.__r[29] = value; }
2841  uint32_t  getIP() const         { return _registers.__pc; }
2842  void      setIP(uint32_t value) { _registers.__pc = value; }
2843
2844private:
2845  struct mips_o32_thread_state_t {
2846    uint32_t __r[32];
2847    uint32_t __pc;
2848    uint32_t __hi;
2849    uint32_t __lo;
2850  };
2851
2852  mips_o32_thread_state_t _registers;
2853#ifdef __mips_hard_float
2854  /// O32 with 32-bit floating point registers only uses half of this
2855  /// space.  However, using the same layout for 32-bit vs 64-bit
2856  /// floating point registers results in a single context size for
2857  /// O32 with hard float.
2858  uint32_t _padding;
2859  double _floats[32];
2860#endif
2861};
2862
2863inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
2864  static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
2865                "mips_o32 registers do not fit into unw_context_t");
2866  memcpy(&_registers, static_cast<const uint8_t *>(registers),
2867         sizeof(_registers));
2868}
2869
2870inline Registers_mips_o32::Registers_mips_o32() {
2871  memset(&_registers, 0, sizeof(_registers));
2872}
2873
2874inline bool Registers_mips_o32::validRegister(int regNum) const {
2875  if (regNum == UNW_REG_IP)
2876    return true;
2877  if (regNum == UNW_REG_SP)
2878    return true;
2879  if (regNum < 0)
2880    return false;
2881  if (regNum <= UNW_MIPS_R31)
2882    return true;
2883#if __mips_isa_rev < 6
2884  if (regNum == UNW_MIPS_HI)
2885    return true;
2886  if (regNum == UNW_MIPS_LO)
2887    return true;
2888#endif
2889#if defined(__mips_hard_float) && __mips_fpr == 32
2890  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2891    return true;
2892#endif
2893  // FIXME: DSP accumulator registers, MSA registers
2894  return false;
2895}
2896
2897inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
2898  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
2899    return _registers.__r[regNum - UNW_MIPS_R0];
2900#if defined(__mips_hard_float) && __mips_fpr == 32
2901  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2902    uint32_t *p;
2903
2904    if (regNum % 2 == 0)
2905      p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2906    else
2907      p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2908    return *p;
2909  }
2910#endif
2911
2912  switch (regNum) {
2913  case UNW_REG_IP:
2914    return _registers.__pc;
2915  case UNW_REG_SP:
2916    return _registers.__r[29];
2917#if __mips_isa_rev < 6
2918  case UNW_MIPS_HI:
2919    return _registers.__hi;
2920  case UNW_MIPS_LO:
2921    return _registers.__lo;
2922#endif
2923  }
2924  _LIBUNWIND_ABORT("unsupported mips_o32 register");
2925}
2926
2927inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
2928  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
2929    _registers.__r[regNum - UNW_MIPS_R0] = value;
2930    return;
2931  }
2932#if defined(__mips_hard_float) && __mips_fpr == 32
2933  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2934    uint32_t *p;
2935
2936    if (regNum % 2 == 0)
2937      p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2938    else
2939      p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2940    *p = value;
2941    return;
2942  }
2943#endif
2944
2945  switch (regNum) {
2946  case UNW_REG_IP:
2947    _registers.__pc = value;
2948    return;
2949  case UNW_REG_SP:
2950    _registers.__r[29] = value;
2951    return;
2952#if __mips_isa_rev < 6
2953  case UNW_MIPS_HI:
2954    _registers.__hi = value;
2955    return;
2956  case UNW_MIPS_LO:
2957    _registers.__lo = value;
2958#endif
2959    return;
2960  }
2961  _LIBUNWIND_ABORT("unsupported mips_o32 register");
2962}
2963
2964inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
2965#if defined(__mips_hard_float) && __mips_fpr == 64
2966  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2967    return true;
2968#else
2969  (void)regNum;
2970#endif
2971  return false;
2972}
2973
2974inline double Registers_mips_o32::getFloatRegister(int regNum) const {
2975#if defined(__mips_hard_float) && __mips_fpr == 64
2976  assert(validFloatRegister(regNum));
2977  return _floats[regNum - UNW_MIPS_F0];
2978#else
2979  (void)regNum;
2980  _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2981#endif
2982}
2983
2984inline void Registers_mips_o32::setFloatRegister(int regNum,
2985                                                 double value) {
2986#if defined(__mips_hard_float) && __mips_fpr == 64
2987  assert(validFloatRegister(regNum));
2988  _floats[regNum - UNW_MIPS_F0] = value;
2989#else
2990  (void)regNum;
2991  (void)value;
2992  _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2993#endif
2994}
2995
2996inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
2997  return false;
2998}
2999
3000inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
3001  _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
3002}
3003
3004inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
3005  _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
3006}
3007
3008inline const char *Registers_mips_o32::getRegisterName(int regNum) {
3009  switch (regNum) {
3010  case UNW_MIPS_R0:
3011    return "$0";
3012  case UNW_MIPS_R1:
3013    return "$1";
3014  case UNW_MIPS_R2:
3015    return "$2";
3016  case UNW_MIPS_R3:
3017    return "$3";
3018  case UNW_MIPS_R4:
3019    return "$4";
3020  case UNW_MIPS_R5:
3021    return "$5";
3022  case UNW_MIPS_R6:
3023    return "$6";
3024  case UNW_MIPS_R7:
3025    return "$7";
3026  case UNW_MIPS_R8:
3027    return "$8";
3028  case UNW_MIPS_R9:
3029    return "$9";
3030  case UNW_MIPS_R10:
3031    return "$10";
3032  case UNW_MIPS_R11:
3033    return "$11";
3034  case UNW_MIPS_R12:
3035    return "$12";
3036  case UNW_MIPS_R13:
3037    return "$13";
3038  case UNW_MIPS_R14:
3039    return "$14";
3040  case UNW_MIPS_R15:
3041    return "$15";
3042  case UNW_MIPS_R16:
3043    return "$16";
3044  case UNW_MIPS_R17:
3045    return "$17";
3046  case UNW_MIPS_R18:
3047    return "$18";
3048  case UNW_MIPS_R19:
3049    return "$19";
3050  case UNW_MIPS_R20:
3051    return "$20";
3052  case UNW_MIPS_R21:
3053    return "$21";
3054  case UNW_MIPS_R22:
3055    return "$22";
3056  case UNW_MIPS_R23:
3057    return "$23";
3058  case UNW_MIPS_R24:
3059    return "$24";
3060  case UNW_MIPS_R25:
3061    return "$25";
3062  case UNW_MIPS_R26:
3063    return "$26";
3064  case UNW_MIPS_R27:
3065    return "$27";
3066  case UNW_MIPS_R28:
3067    return "$28";
3068  case UNW_MIPS_R29:
3069    return "$29";
3070  case UNW_MIPS_R30:
3071    return "$30";
3072  case UNW_MIPS_R31:
3073    return "$31";
3074  case UNW_MIPS_F0:
3075    return "$f0";
3076  case UNW_MIPS_F1:
3077    return "$f1";
3078  case UNW_MIPS_F2:
3079    return "$f2";
3080  case UNW_MIPS_F3:
3081    return "$f3";
3082  case UNW_MIPS_F4:
3083    return "$f4";
3084  case UNW_MIPS_F5:
3085    return "$f5";
3086  case UNW_MIPS_F6:
3087    return "$f6";
3088  case UNW_MIPS_F7:
3089    return "$f7";
3090  case UNW_MIPS_F8:
3091    return "$f8";
3092  case UNW_MIPS_F9:
3093    return "$f9";
3094  case UNW_MIPS_F10:
3095    return "$f10";
3096  case UNW_MIPS_F11:
3097    return "$f11";
3098  case UNW_MIPS_F12:
3099    return "$f12";
3100  case UNW_MIPS_F13:
3101    return "$f13";
3102  case UNW_MIPS_F14:
3103    return "$f14";
3104  case UNW_MIPS_F15:
3105    return "$f15";
3106  case UNW_MIPS_F16:
3107    return "$f16";
3108  case UNW_MIPS_F17:
3109    return "$f17";
3110  case UNW_MIPS_F18:
3111    return "$f18";
3112  case UNW_MIPS_F19:
3113    return "$f19";
3114  case UNW_MIPS_F20:
3115    return "$f20";
3116  case UNW_MIPS_F21:
3117    return "$f21";
3118  case UNW_MIPS_F22:
3119    return "$f22";
3120  case UNW_MIPS_F23:
3121    return "$f23";
3122  case UNW_MIPS_F24:
3123    return "$f24";
3124  case UNW_MIPS_F25:
3125    return "$f25";
3126  case UNW_MIPS_F26:
3127    return "$f26";
3128  case UNW_MIPS_F27:
3129    return "$f27";
3130  case UNW_MIPS_F28:
3131    return "$f28";
3132  case UNW_MIPS_F29:
3133    return "$f29";
3134  case UNW_MIPS_F30:
3135    return "$f30";
3136  case UNW_MIPS_F31:
3137    return "$f31";
3138#if __mips_isa_rev < 6
3139  case UNW_MIPS_HI:
3140    return "$hi";
3141  case UNW_MIPS_LO:
3142    return "$lo";
3143#endif
3144  default:
3145    return "unknown register";
3146  }
3147}
3148#endif // _LIBUNWIND_TARGET_MIPS_O32
3149
3150#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
3151/// Registers_mips_newabi holds the register state of a thread in a
3152/// MIPS process using NEWABI (the N32 or N64 ABIs).
3153class _LIBUNWIND_HIDDEN Registers_mips_newabi {
3154public:
3155  Registers_mips_newabi();
3156  Registers_mips_newabi(const void *registers);
3157
3158  bool        validRegister(int num) const;
3159  uint64_t    getRegister(int num) const;
3160  void        setRegister(int num, uint64_t value);
3161  bool        validFloatRegister(int num) const;
3162  double      getFloatRegister(int num) const;
3163  void        setFloatRegister(int num, double value);
3164  bool        validVectorRegister(int num) const;
3165  v128        getVectorRegister(int num) const;
3166  void        setVectorRegister(int num, v128 value);
3167  static const char *getRegisterName(int num);
3168  void        jumpto();
3169  static constexpr int lastDwarfRegNum() {
3170    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS;
3171  }
3172  static int  getArch() { return REGISTERS_MIPS_NEWABI; }
3173
3174  uint64_t  getSP() const         { return _registers.__r[29]; }
3175  void      setSP(uint64_t value) { _registers.__r[29] = value; }
3176  uint64_t  getIP() const         { return _registers.__pc; }
3177  void      setIP(uint64_t value) { _registers.__pc = value; }
3178
3179private:
3180  struct mips_newabi_thread_state_t {
3181    uint64_t __r[32];
3182    uint64_t __pc;
3183    uint64_t __hi;
3184    uint64_t __lo;
3185  };
3186
3187  mips_newabi_thread_state_t _registers;
3188#ifdef __mips_hard_float
3189  double _floats[32];
3190#endif
3191};
3192
3193inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {
3194  static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),
3195                "mips_newabi registers do not fit into unw_context_t");
3196  memcpy(&_registers, static_cast<const uint8_t *>(registers),
3197         sizeof(_registers));
3198}
3199
3200inline Registers_mips_newabi::Registers_mips_newabi() {
3201  memset(&_registers, 0, sizeof(_registers));
3202}
3203
3204inline bool Registers_mips_newabi::validRegister(int regNum) const {
3205  if (regNum == UNW_REG_IP)
3206    return true;
3207  if (regNum == UNW_REG_SP)
3208    return true;
3209  if (regNum < 0)
3210    return false;
3211  if (regNum <= UNW_MIPS_R31)
3212    return true;
3213#if __mips_isa_rev < 6
3214  if (regNum == UNW_MIPS_HI)
3215    return true;
3216  if (regNum == UNW_MIPS_LO)
3217    return true;
3218#endif
3219  // FIXME: Hard float, DSP accumulator registers, MSA registers
3220  return false;
3221}
3222
3223inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
3224  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3225    return _registers.__r[regNum - UNW_MIPS_R0];
3226
3227  switch (regNum) {
3228  case UNW_REG_IP:
3229    return _registers.__pc;
3230  case UNW_REG_SP:
3231    return _registers.__r[29];
3232#if __mips_isa_rev < 6
3233  case UNW_MIPS_HI:
3234    return _registers.__hi;
3235  case UNW_MIPS_LO:
3236    return _registers.__lo;
3237#endif
3238  }
3239  _LIBUNWIND_ABORT("unsupported mips_newabi register");
3240}
3241
3242inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
3243  if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3244    _registers.__r[regNum - UNW_MIPS_R0] = value;
3245    return;
3246  }
3247
3248  switch (regNum) {
3249  case UNW_REG_IP:
3250    _registers.__pc = value;
3251    return;
3252  case UNW_REG_SP:
3253    _registers.__r[29] = value;
3254    return;
3255#if __mips_isa_rev < 6
3256  case UNW_MIPS_HI:
3257    _registers.__hi = value;
3258    return;
3259  case UNW_MIPS_LO:
3260    _registers.__lo = value;
3261    return;
3262#endif
3263  }
3264  _LIBUNWIND_ABORT("unsupported mips_newabi register");
3265}
3266
3267inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {
3268#ifdef __mips_hard_float
3269  if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3270    return true;
3271#else
3272  (void)regNum;
3273#endif
3274  return false;
3275}
3276
3277inline double Registers_mips_newabi::getFloatRegister(int regNum) const {
3278#ifdef __mips_hard_float
3279  assert(validFloatRegister(regNum));
3280  return _floats[regNum - UNW_MIPS_F0];
3281#else
3282  (void)regNum;
3283  _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3284#endif
3285}
3286
3287inline void Registers_mips_newabi::setFloatRegister(int regNum,
3288                                                    double value) {
3289#ifdef __mips_hard_float
3290  assert(validFloatRegister(regNum));
3291  _floats[regNum - UNW_MIPS_F0] = value;
3292#else
3293  (void)regNum;
3294  (void)value;
3295  _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3296#endif
3297}
3298
3299inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {
3300  return false;
3301}
3302
3303inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {
3304  _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3305}
3306
3307inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {
3308  _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3309}
3310
3311inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
3312  switch (regNum) {
3313  case UNW_MIPS_R0:
3314    return "$0";
3315  case UNW_MIPS_R1:
3316    return "$1";
3317  case UNW_MIPS_R2:
3318    return "$2";
3319  case UNW_MIPS_R3:
3320    return "$3";
3321  case UNW_MIPS_R4:
3322    return "$4";
3323  case UNW_MIPS_R5:
3324    return "$5";
3325  case UNW_MIPS_R6:
3326    return "$6";
3327  case UNW_MIPS_R7:
3328    return "$7";
3329  case UNW_MIPS_R8:
3330    return "$8";
3331  case UNW_MIPS_R9:
3332    return "$9";
3333  case UNW_MIPS_R10:
3334    return "$10";
3335  case UNW_MIPS_R11:
3336    return "$11";
3337  case UNW_MIPS_R12:
3338    return "$12";
3339  case UNW_MIPS_R13:
3340    return "$13";
3341  case UNW_MIPS_R14:
3342    return "$14";
3343  case UNW_MIPS_R15:
3344    return "$15";
3345  case UNW_MIPS_R16:
3346    return "$16";
3347  case UNW_MIPS_R17:
3348    return "$17";
3349  case UNW_MIPS_R18:
3350    return "$18";
3351  case UNW_MIPS_R19:
3352    return "$19";
3353  case UNW_MIPS_R20:
3354    return "$20";
3355  case UNW_MIPS_R21:
3356    return "$21";
3357  case UNW_MIPS_R22:
3358    return "$22";
3359  case UNW_MIPS_R23:
3360    return "$23";
3361  case UNW_MIPS_R24:
3362    return "$24";
3363  case UNW_MIPS_R25:
3364    return "$25";
3365  case UNW_MIPS_R26:
3366    return "$26";
3367  case UNW_MIPS_R27:
3368    return "$27";
3369  case UNW_MIPS_R28:
3370    return "$28";
3371  case UNW_MIPS_R29:
3372    return "$29";
3373  case UNW_MIPS_R30:
3374    return "$30";
3375  case UNW_MIPS_R31:
3376    return "$31";
3377  case UNW_MIPS_F0:
3378    return "$f0";
3379  case UNW_MIPS_F1:
3380    return "$f1";
3381  case UNW_MIPS_F2:
3382    return "$f2";
3383  case UNW_MIPS_F3:
3384    return "$f3";
3385  case UNW_MIPS_F4:
3386    return "$f4";
3387  case UNW_MIPS_F5:
3388    return "$f5";
3389  case UNW_MIPS_F6:
3390    return "$f6";
3391  case UNW_MIPS_F7:
3392    return "$f7";
3393  case UNW_MIPS_F8:
3394    return "$f8";
3395  case UNW_MIPS_F9:
3396    return "$f9";
3397  case UNW_MIPS_F10:
3398    return "$f10";
3399  case UNW_MIPS_F11:
3400    return "$f11";
3401  case UNW_MIPS_F12:
3402    return "$f12";
3403  case UNW_MIPS_F13:
3404    return "$f13";
3405  case UNW_MIPS_F14:
3406    return "$f14";
3407  case UNW_MIPS_F15:
3408    return "$f15";
3409  case UNW_MIPS_F16:
3410    return "$f16";
3411  case UNW_MIPS_F17:
3412    return "$f17";
3413  case UNW_MIPS_F18:
3414    return "$f18";
3415  case UNW_MIPS_F19:
3416    return "$f19";
3417  case UNW_MIPS_F20:
3418    return "$f20";
3419  case UNW_MIPS_F21:
3420    return "$f21";
3421  case UNW_MIPS_F22:
3422    return "$f22";
3423  case UNW_MIPS_F23:
3424    return "$f23";
3425  case UNW_MIPS_F24:
3426    return "$f24";
3427  case UNW_MIPS_F25:
3428    return "$f25";
3429  case UNW_MIPS_F26:
3430    return "$f26";
3431  case UNW_MIPS_F27:
3432    return "$f27";
3433  case UNW_MIPS_F28:
3434    return "$f28";
3435  case UNW_MIPS_F29:
3436    return "$f29";
3437  case UNW_MIPS_F30:
3438    return "$f30";
3439  case UNW_MIPS_F31:
3440    return "$f31";
3441#if __mips_isa_rev < 6
3442  case UNW_MIPS_HI:
3443    return "$hi";
3444  case UNW_MIPS_LO:
3445    return "$lo";
3446#endif
3447  default:
3448    return "unknown register";
3449  }
3450}
3451#endif // _LIBUNWIND_TARGET_MIPS_NEWABI
3452
3453#if defined(_LIBUNWIND_TARGET_SPARC)
3454/// Registers_sparc holds the register state of a thread in a 32-bit Sparc
3455/// process.
3456class _LIBUNWIND_HIDDEN Registers_sparc {
3457public:
3458  Registers_sparc();
3459  Registers_sparc(const void *registers);
3460
3461  bool        validRegister(int num) const;
3462  uint32_t    getRegister(int num) const;
3463  void        setRegister(int num, uint32_t value);
3464  bool        validFloatRegister(int num) const;
3465  double      getFloatRegister(int num) const;
3466  void        setFloatRegister(int num, double value);
3467  bool        validVectorRegister(int num) const;
3468  v128        getVectorRegister(int num) const;
3469  void        setVectorRegister(int num, v128 value);
3470  static const char *getRegisterName(int num);
3471  void        jumpto();
3472  static constexpr int lastDwarfRegNum() {
3473    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC;
3474  }
3475  static int  getArch() { return REGISTERS_SPARC; }
3476
3477  uint64_t  getSP() const         { return _registers.__regs[UNW_SPARC_O6]; }
3478  void      setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; }
3479  uint64_t  getIP() const         { return _registers.__regs[UNW_SPARC_O7]; }
3480  void      setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
3481
3482private:
3483  struct sparc_thread_state_t {
3484    unsigned int __regs[32];
3485  };
3486
3487  sparc_thread_state_t _registers;
3488};
3489
3490inline Registers_sparc::Registers_sparc(const void *registers) {
3491  static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit),
3492                "sparc registers do not fit into unw_context_t");
3493  memcpy(&_registers, static_cast<const uint8_t *>(registers),
3494         sizeof(_registers));
3495}
3496
3497inline Registers_sparc::Registers_sparc() {
3498  memset(&_registers, 0, sizeof(_registers));
3499}
3500
3501inline bool Registers_sparc::validRegister(int regNum) const {
3502  if (regNum == UNW_REG_IP)
3503    return true;
3504  if (regNum == UNW_REG_SP)
3505    return true;
3506  if (regNum < 0)
3507    return false;
3508  if (regNum <= UNW_SPARC_I7)
3509    return true;
3510  return false;
3511}
3512
3513inline uint32_t Registers_sparc::getRegister(int regNum) const {
3514  if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3515    return _registers.__regs[regNum];
3516  }
3517
3518  switch (regNum) {
3519  case UNW_REG_IP:
3520    return _registers.__regs[UNW_SPARC_O7];
3521  case UNW_REG_SP:
3522    return _registers.__regs[UNW_SPARC_O6];
3523  }
3524  _LIBUNWIND_ABORT("unsupported sparc register");
3525}
3526
3527inline void Registers_sparc::setRegister(int regNum, uint32_t value) {
3528  if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3529    _registers.__regs[regNum] = value;
3530    return;
3531  }
3532
3533  switch (regNum) {
3534  case UNW_REG_IP:
3535    _registers.__regs[UNW_SPARC_O7] = value;
3536    return;
3537  case UNW_REG_SP:
3538    _registers.__regs[UNW_SPARC_O6] = value;
3539    return;
3540  }
3541  _LIBUNWIND_ABORT("unsupported sparc register");
3542}
3543
3544inline bool Registers_sparc::validFloatRegister(int) const { return false; }
3545
3546inline double Registers_sparc::getFloatRegister(int) const {
3547  _LIBUNWIND_ABORT("no Sparc float registers");
3548}
3549
3550inline void Registers_sparc::setFloatRegister(int, double) {
3551  _LIBUNWIND_ABORT("no Sparc float registers");
3552}
3553
3554inline bool Registers_sparc::validVectorRegister(int) const { return false; }
3555
3556inline v128 Registers_sparc::getVectorRegister(int) const {
3557  _LIBUNWIND_ABORT("no Sparc vector registers");
3558}
3559
3560inline void Registers_sparc::setVectorRegister(int, v128) {
3561  _LIBUNWIND_ABORT("no Sparc vector registers");
3562}
3563
3564inline const char *Registers_sparc::getRegisterName(int regNum) {
3565  switch (regNum) {
3566  case UNW_REG_IP:
3567    return "pc";
3568  case UNW_SPARC_G0:
3569    return "g0";
3570  case UNW_SPARC_G1:
3571    return "g1";
3572  case UNW_SPARC_G2:
3573    return "g2";
3574  case UNW_SPARC_G3:
3575    return "g3";
3576  case UNW_SPARC_G4:
3577    return "g4";
3578  case UNW_SPARC_G5:
3579    return "g5";
3580  case UNW_SPARC_G6:
3581    return "g6";
3582  case UNW_SPARC_G7:
3583    return "g7";
3584  case UNW_SPARC_O0:
3585    return "o0";
3586  case UNW_SPARC_O1:
3587    return "o1";
3588  case UNW_SPARC_O2:
3589    return "o2";
3590  case UNW_SPARC_O3:
3591    return "o3";
3592  case UNW_SPARC_O4:
3593    return "o4";
3594  case UNW_SPARC_O5:
3595    return "o5";
3596  case UNW_REG_SP:
3597  case UNW_SPARC_O6:
3598    return "sp";
3599  case UNW_SPARC_O7:
3600    return "o7";
3601  case UNW_SPARC_L0:
3602    return "l0";
3603  case UNW_SPARC_L1:
3604    return "l1";
3605  case UNW_SPARC_L2:
3606    return "l2";
3607  case UNW_SPARC_L3:
3608    return "l3";
3609  case UNW_SPARC_L4:
3610    return "l4";
3611  case UNW_SPARC_L5:
3612    return "l5";
3613  case UNW_SPARC_L6:
3614    return "l6";
3615  case UNW_SPARC_L7:
3616    return "l7";
3617  case UNW_SPARC_I0:
3618    return "i0";
3619  case UNW_SPARC_I1:
3620    return "i1";
3621  case UNW_SPARC_I2:
3622    return "i2";
3623  case UNW_SPARC_I3:
3624    return "i3";
3625  case UNW_SPARC_I4:
3626    return "i4";
3627  case UNW_SPARC_I5:
3628    return "i5";
3629  case UNW_SPARC_I6:
3630    return "fp";
3631  case UNW_SPARC_I7:
3632    return "i7";
3633  default:
3634    return "unknown register";
3635  }
3636}
3637#endif // _LIBUNWIND_TARGET_SPARC
3638
3639#if defined(_LIBUNWIND_TARGET_SPARC64)
3640/// Registers_sparc64 holds the register state of a thread in a 64-bit
3641/// sparc process.
3642class _LIBUNWIND_HIDDEN Registers_sparc64 {
3643public:
3644  Registers_sparc64() = default;
3645  Registers_sparc64(const void *registers);
3646
3647  bool validRegister(int num) const;
3648  uint64_t getRegister(int num) const;
3649  void setRegister(int num, uint64_t value);
3650  bool validFloatRegister(int num) const;
3651  double getFloatRegister(int num) const;
3652  void setFloatRegister(int num, double value);
3653  bool validVectorRegister(int num) const;
3654  v128 getVectorRegister(int num) const;
3655  void setVectorRegister(int num, v128 value);
3656  const char *getRegisterName(int num);
3657  void jumpto();
3658  static constexpr int lastDwarfRegNum() {
3659    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64;
3660  }
3661  static int getArch() { return REGISTERS_SPARC64; }
3662
3663  uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6] + 2047; }
3664  void setSP(uint64_t value) { _registers.__regs[UNW_SPARC_O6] = value - 2047; }
3665  uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; }
3666  void setIP(uint64_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
3667  uint64_t getWCookie() const { return _wcookie; }
3668
3669private:
3670  struct sparc64_thread_state_t {
3671    uint64_t __regs[32];
3672  };
3673
3674  sparc64_thread_state_t _registers{};
3675  uint64_t _wcookie = 0;
3676};
3677
3678inline Registers_sparc64::Registers_sparc64(const void *registers) {
3679  static_assert((check_fit<Registers_sparc64, unw_context_t>::does_fit),
3680                "sparc64 registers do not fit into unw_context_t");
3681  memcpy(&_registers, registers, sizeof(_registers));
3682  memcpy(&_wcookie,
3683         static_cast<const uint8_t *>(registers) + sizeof(_registers),
3684         sizeof(_wcookie));
3685}
3686
3687inline bool Registers_sparc64::validRegister(int regNum) const {
3688  if (regNum == UNW_REG_IP)
3689    return true;
3690  if (regNum == UNW_REG_SP)
3691    return true;
3692  if (regNum < 0)
3693    return false;
3694  if (regNum <= UNW_SPARC_I7)
3695    return true;
3696  return false;
3697}
3698
3699inline uint64_t Registers_sparc64::getRegister(int regNum) const {
3700  if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7)
3701    return _registers.__regs[regNum];
3702
3703  switch (regNum) {
3704  case UNW_REG_IP:
3705    return _registers.__regs[UNW_SPARC_O7];
3706  case UNW_REG_SP:
3707    return _registers.__regs[UNW_SPARC_O6] + 2047;
3708  }
3709  _LIBUNWIND_ABORT("unsupported sparc64 register");
3710}
3711
3712inline void Registers_sparc64::setRegister(int regNum, uint64_t value) {
3713  if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7) {
3714    _registers.__regs[regNum] = value;
3715    return;
3716  }
3717
3718  switch (regNum) {
3719  case UNW_REG_IP:
3720    _registers.__regs[UNW_SPARC_O7] = value;
3721    return;
3722  case UNW_REG_SP:
3723    _registers.__regs[UNW_SPARC_O6] = value - 2047;
3724    return;
3725  }
3726  _LIBUNWIND_ABORT("unsupported sparc64 register");
3727}
3728
3729inline bool Registers_sparc64::validFloatRegister(int) const { return false; }
3730
3731inline double Registers_sparc64::getFloatRegister(int) const {
3732  _LIBUNWIND_ABORT("no sparc64 float registers");
3733}
3734
3735inline void Registers_sparc64::setFloatRegister(int, double) {
3736  _LIBUNWIND_ABORT("no sparc64 float registers");
3737}
3738
3739inline bool Registers_sparc64::validVectorRegister(int) const { return false; }
3740
3741inline v128 Registers_sparc64::getVectorRegister(int) const {
3742  _LIBUNWIND_ABORT("no sparc64 vector registers");
3743}
3744
3745inline void Registers_sparc64::setVectorRegister(int, v128) {
3746  _LIBUNWIND_ABORT("no sparc64 vector registers");
3747}
3748
3749inline const char *Registers_sparc64::getRegisterName(int regNum) {
3750  switch (regNum) {
3751  case UNW_REG_IP:
3752    return "pc";
3753  case UNW_SPARC_G0:
3754    return "g0";
3755  case UNW_SPARC_G1:
3756    return "g1";
3757  case UNW_SPARC_G2:
3758    return "g2";
3759  case UNW_SPARC_G3:
3760    return "g3";
3761  case UNW_SPARC_G4:
3762    return "g4";
3763  case UNW_SPARC_G5:
3764    return "g5";
3765  case UNW_SPARC_G6:
3766    return "g6";
3767  case UNW_SPARC_G7:
3768    return "g7";
3769  case UNW_SPARC_O0:
3770    return "o0";
3771  case UNW_SPARC_O1:
3772    return "o1";
3773  case UNW_SPARC_O2:
3774    return "o2";
3775  case UNW_SPARC_O3:
3776    return "o3";
3777  case UNW_SPARC_O4:
3778    return "o4";
3779  case UNW_SPARC_O5:
3780    return "o5";
3781  case UNW_REG_SP:
3782  case UNW_SPARC_O6:
3783    return "o6";
3784  case UNW_SPARC_O7:
3785    return "o7";
3786  case UNW_SPARC_L0:
3787    return "l0";
3788  case UNW_SPARC_L1:
3789    return "l1";
3790  case UNW_SPARC_L2:
3791    return "l2";
3792  case UNW_SPARC_L3:
3793    return "l3";
3794  case UNW_SPARC_L4:
3795    return "l4";
3796  case UNW_SPARC_L5:
3797    return "l5";
3798  case UNW_SPARC_L6:
3799    return "l6";
3800  case UNW_SPARC_L7:
3801    return "l7";
3802  case UNW_SPARC_I0:
3803    return "i0";
3804  case UNW_SPARC_I1:
3805    return "i1";
3806  case UNW_SPARC_I2:
3807    return "i2";
3808  case UNW_SPARC_I3:
3809    return "i3";
3810  case UNW_SPARC_I4:
3811    return "i4";
3812  case UNW_SPARC_I5:
3813    return "i5";
3814  case UNW_SPARC_I6:
3815    return "i6";
3816  case UNW_SPARC_I7:
3817    return "i7";
3818  default:
3819    return "unknown register";
3820  }
3821}
3822#endif // _LIBUNWIND_TARGET_SPARC64
3823
3824#if defined(_LIBUNWIND_TARGET_HEXAGON)
3825/// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6
3826/// process.
3827class _LIBUNWIND_HIDDEN Registers_hexagon {
3828public:
3829  Registers_hexagon();
3830  Registers_hexagon(const void *registers);
3831
3832  bool        validRegister(int num) const;
3833  uint32_t    getRegister(int num) const;
3834  void        setRegister(int num, uint32_t value);
3835  bool        validFloatRegister(int num) const;
3836  double      getFloatRegister(int num) const;
3837  void        setFloatRegister(int num, double value);
3838  bool        validVectorRegister(int num) const;
3839  v128        getVectorRegister(int num) const;
3840  void        setVectorRegister(int num, v128 value);
3841  const char *getRegisterName(int num);
3842  void        jumpto();
3843  static constexpr int lastDwarfRegNum() {
3844    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON;
3845  }
3846  static int  getArch() { return REGISTERS_HEXAGON; }
3847
3848  uint32_t  getSP() const         { return _registers.__r[UNW_HEXAGON_R29]; }
3849  void      setSP(uint32_t value) { _registers.__r[UNW_HEXAGON_R29] = value; }
3850  uint32_t  getIP() const         { return _registers.__r[UNW_HEXAGON_PC]; }
3851  void      setIP(uint32_t value) { _registers.__r[UNW_HEXAGON_PC] = value; }
3852
3853private:
3854  struct hexagon_thread_state_t {
3855    unsigned int __r[35];
3856  };
3857
3858  hexagon_thread_state_t _registers;
3859};
3860
3861inline Registers_hexagon::Registers_hexagon(const void *registers) {
3862  static_assert((check_fit<Registers_hexagon, unw_context_t>::does_fit),
3863                "hexagon registers do not fit into unw_context_t");
3864  memcpy(&_registers, static_cast<const uint8_t *>(registers),
3865         sizeof(_registers));
3866}
3867
3868inline Registers_hexagon::Registers_hexagon() {
3869  memset(&_registers, 0, sizeof(_registers));
3870}
3871
3872inline bool Registers_hexagon::validRegister(int regNum) const {
3873  if (regNum <= UNW_HEXAGON_R31)
3874    return true;
3875  return false;
3876}
3877
3878inline uint32_t Registers_hexagon::getRegister(int regNum) const {
3879  if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31)
3880    return _registers.__r[regNum - UNW_HEXAGON_R0];
3881
3882  switch (regNum) {
3883  case UNW_REG_IP:
3884    return _registers.__r[UNW_HEXAGON_PC];
3885  case UNW_REG_SP:
3886    return _registers.__r[UNW_HEXAGON_R29];
3887  }
3888  _LIBUNWIND_ABORT("unsupported hexagon register");
3889}
3890
3891inline void Registers_hexagon::setRegister(int regNum, uint32_t value) {
3892  if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31) {
3893    _registers.__r[regNum - UNW_HEXAGON_R0] = value;
3894    return;
3895  }
3896
3897  switch (regNum) {
3898  case UNW_REG_IP:
3899    _registers.__r[UNW_HEXAGON_PC] = value;
3900    return;
3901  case UNW_REG_SP:
3902    _registers.__r[UNW_HEXAGON_R29] = value;
3903    return;
3904  }
3905  _LIBUNWIND_ABORT("unsupported hexagon register");
3906}
3907
3908inline bool Registers_hexagon::validFloatRegister(int /* regNum */) const {
3909  return false;
3910}
3911
3912inline double Registers_hexagon::getFloatRegister(int /* regNum */) const {
3913  _LIBUNWIND_ABORT("hexagon float support not implemented");
3914}
3915
3916inline void Registers_hexagon::setFloatRegister(int /* regNum */,
3917                                             double /* value */) {
3918  _LIBUNWIND_ABORT("hexagon float support not implemented");
3919}
3920
3921inline bool Registers_hexagon::validVectorRegister(int /* regNum */) const {
3922  return false;
3923}
3924
3925inline v128 Registers_hexagon::getVectorRegister(int /* regNum */) const {
3926  _LIBUNWIND_ABORT("hexagon vector support not implemented");
3927}
3928
3929inline void Registers_hexagon::setVectorRegister(int /* regNum */, v128 /* value */) {
3930  _LIBUNWIND_ABORT("hexagon vector support not implemented");
3931}
3932
3933inline const char *Registers_hexagon::getRegisterName(int regNum) {
3934  switch (regNum) {
3935  case UNW_HEXAGON_R0:
3936    return "r0";
3937  case UNW_HEXAGON_R1:
3938    return "r1";
3939  case UNW_HEXAGON_R2:
3940    return "r2";
3941  case UNW_HEXAGON_R3:
3942    return "r3";
3943  case UNW_HEXAGON_R4:
3944    return "r4";
3945  case UNW_HEXAGON_R5:
3946    return "r5";
3947  case UNW_HEXAGON_R6:
3948    return "r6";
3949  case UNW_HEXAGON_R7:
3950    return "r7";
3951  case UNW_HEXAGON_R8:
3952    return "r8";
3953  case UNW_HEXAGON_R9:
3954    return "r9";
3955  case UNW_HEXAGON_R10:
3956    return "r10";
3957  case UNW_HEXAGON_R11:
3958    return "r11";
3959  case UNW_HEXAGON_R12:
3960    return "r12";
3961  case UNW_HEXAGON_R13:
3962    return "r13";
3963  case UNW_HEXAGON_R14:
3964    return "r14";
3965  case UNW_HEXAGON_R15:
3966    return "r15";
3967  case UNW_HEXAGON_R16:
3968    return "r16";
3969  case UNW_HEXAGON_R17:
3970    return "r17";
3971  case UNW_HEXAGON_R18:
3972    return "r18";
3973  case UNW_HEXAGON_R19:
3974    return "r19";
3975  case UNW_HEXAGON_R20:
3976    return "r20";
3977  case UNW_HEXAGON_R21:
3978    return "r21";
3979  case UNW_HEXAGON_R22:
3980    return "r22";
3981  case UNW_HEXAGON_R23:
3982    return "r23";
3983  case UNW_HEXAGON_R24:
3984    return "r24";
3985  case UNW_HEXAGON_R25:
3986    return "r25";
3987  case UNW_HEXAGON_R26:
3988    return "r26";
3989  case UNW_HEXAGON_R27:
3990    return "r27";
3991  case UNW_HEXAGON_R28:
3992    return "r28";
3993  case UNW_HEXAGON_R29:
3994    return "r29";
3995  case UNW_HEXAGON_R30:
3996    return "r30";
3997  case UNW_HEXAGON_R31:
3998    return "r31";
3999  default:
4000    return "unknown register";
4001  }
4002
4003}
4004#endif // _LIBUNWIND_TARGET_HEXAGON
4005
4006
4007#if defined(_LIBUNWIND_TARGET_RISCV)
4008/// Registers_riscv holds the register state of a thread in a RISC-V
4009/// process.
4010
4011// This check makes it safe when LIBUNWIND_ENABLE_CROSS_UNWINDING enabled.
4012# ifdef __riscv
4013#  if __riscv_xlen == 32
4014typedef uint32_t reg_t;
4015#  elif __riscv_xlen == 64
4016typedef uint64_t reg_t;
4017#  else
4018#   error "Unsupported __riscv_xlen"
4019#  endif
4020
4021#  if defined(__riscv_flen)
4022#   if __riscv_flen == 64
4023typedef double fp_t;
4024#   elif __riscv_flen == 32
4025typedef float fp_t;
4026#   else
4027#    error "Unsupported __riscv_flen"
4028#   endif
4029#  else
4030// This is just for suppressing undeclared error of fp_t.
4031typedef double fp_t;
4032#  endif
4033# else
4034// Use Max possible width when cross unwinding
4035typedef uint64_t reg_t;
4036typedef double fp_t;
4037# define __riscv_xlen 64
4038# define __riscv_flen 64
4039#endif
4040
4041/// Registers_riscv holds the register state of a thread.
4042class _LIBUNWIND_HIDDEN Registers_riscv {
4043public:
4044  Registers_riscv();
4045  Registers_riscv(const void *registers);
4046
4047  bool        validRegister(int num) const;
4048  reg_t       getRegister(int num) const;
4049  void        setRegister(int num, reg_t value);
4050  bool        validFloatRegister(int num) const;
4051  fp_t        getFloatRegister(int num) const;
4052  void        setFloatRegister(int num, fp_t value);
4053  bool        validVectorRegister(int num) const;
4054  v128        getVectorRegister(int num) const;
4055  void        setVectorRegister(int num, v128 value);
4056  static const char *getRegisterName(int num);
4057  void        jumpto();
4058  static constexpr int lastDwarfRegNum() {
4059    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV;
4060  }
4061  static int  getArch() { return REGISTERS_RISCV; }
4062
4063  reg_t       getSP() const { return _registers[2]; }
4064  void        setSP(reg_t value) { _registers[2] = value; }
4065  reg_t       getIP() const { return _registers[0]; }
4066  void        setIP(reg_t value) { _registers[0] = value; }
4067
4068private:
4069  // _registers[0] holds the pc
4070  reg_t _registers[32];
4071# if defined(__riscv_flen)
4072  fp_t _floats[32];
4073# endif
4074};
4075
4076inline Registers_riscv::Registers_riscv(const void *registers) {
4077  static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
4078                "riscv registers do not fit into unw_context_t");
4079  memcpy(&_registers, registers, sizeof(_registers));
4080# if __riscv_xlen == 32
4081  static_assert(sizeof(_registers) == 0x80,
4082                "expected float registers to be at offset 128");
4083# elif __riscv_xlen == 64
4084  static_assert(sizeof(_registers) == 0x100,
4085                "expected float registers to be at offset 256");
4086# else
4087# error "Unexpected float registers."
4088# endif
4089
4090# if defined(__riscv_flen)
4091  memcpy(_floats,
4092         static_cast<const uint8_t *>(registers) + sizeof(_registers),
4093         sizeof(_floats));
4094# endif
4095}
4096
4097inline Registers_riscv::Registers_riscv() {
4098  memset(&_registers, 0, sizeof(_registers));
4099# if defined(__riscv_flen)
4100  memset(&_floats, 0, sizeof(_floats));
4101# endif
4102}
4103
4104inline bool Registers_riscv::validRegister(int regNum) const {
4105  if (regNum == UNW_REG_IP)
4106    return true;
4107  if (regNum == UNW_REG_SP)
4108    return true;
4109  if (regNum < 0)
4110    return false;
4111  if (regNum == UNW_RISCV_VLENB)
4112    return true;
4113  if (regNum > UNW_RISCV_F31)
4114    return false;
4115  return true;
4116}
4117
4118inline reg_t Registers_riscv::getRegister(int regNum) const {
4119  if (regNum == UNW_REG_IP)
4120    return _registers[0];
4121  if (regNum == UNW_REG_SP)
4122    return _registers[2];
4123  if (regNum == UNW_RISCV_X0)
4124    return 0;
4125  if ((regNum > 0) && (regNum < 32))
4126    return _registers[regNum];
4127  if (regNum == UNW_RISCV_VLENB) {
4128    reg_t vlenb;
4129    __asm__ volatile("csrr %0, 0xC22" : "=r"(vlenb));
4130    return vlenb;
4131  }
4132  _LIBUNWIND_ABORT("unsupported riscv register");
4133}
4134
4135inline void Registers_riscv::setRegister(int regNum, reg_t value) {
4136  if (regNum == UNW_REG_IP)
4137    _registers[0] = value;
4138  else if (regNum == UNW_REG_SP)
4139    _registers[2] = value;
4140  else if (regNum == UNW_RISCV_X0)
4141    /* x0 is hardwired to zero */
4142    return;
4143  else if ((regNum > 0) && (regNum < 32))
4144    _registers[regNum] = value;
4145  else
4146    _LIBUNWIND_ABORT("unsupported riscv register");
4147}
4148
4149inline const char *Registers_riscv::getRegisterName(int regNum) {
4150  switch (regNum) {
4151  case UNW_REG_IP:
4152    return "pc";
4153  case UNW_REG_SP:
4154    return "sp";
4155  case UNW_RISCV_X0:
4156    return "zero";
4157  case UNW_RISCV_X1:
4158    return "ra";
4159  case UNW_RISCV_X2:
4160    return "sp";
4161  case UNW_RISCV_X3:
4162    return "gp";
4163  case UNW_RISCV_X4:
4164    return "tp";
4165  case UNW_RISCV_X5:
4166    return "t0";
4167  case UNW_RISCV_X6:
4168    return "t1";
4169  case UNW_RISCV_X7:
4170    return "t2";
4171  case UNW_RISCV_X8:
4172    return "s0";
4173  case UNW_RISCV_X9:
4174    return "s1";
4175  case UNW_RISCV_X10:
4176    return "a0";
4177  case UNW_RISCV_X11:
4178    return "a1";
4179  case UNW_RISCV_X12:
4180    return "a2";
4181  case UNW_RISCV_X13:
4182    return "a3";
4183  case UNW_RISCV_X14:
4184    return "a4";
4185  case UNW_RISCV_X15:
4186    return "a5";
4187  case UNW_RISCV_X16:
4188    return "a6";
4189  case UNW_RISCV_X17:
4190    return "a7";
4191  case UNW_RISCV_X18:
4192    return "s2";
4193  case UNW_RISCV_X19:
4194    return "s3";
4195  case UNW_RISCV_X20:
4196    return "s4";
4197  case UNW_RISCV_X21:
4198    return "s5";
4199  case UNW_RISCV_X22:
4200    return "s6";
4201  case UNW_RISCV_X23:
4202    return "s7";
4203  case UNW_RISCV_X24:
4204    return "s8";
4205  case UNW_RISCV_X25:
4206    return "s9";
4207  case UNW_RISCV_X26:
4208    return "s10";
4209  case UNW_RISCV_X27:
4210    return "s11";
4211  case UNW_RISCV_X28:
4212    return "t3";
4213  case UNW_RISCV_X29:
4214    return "t4";
4215  case UNW_RISCV_X30:
4216    return "t5";
4217  case UNW_RISCV_X31:
4218    return "t6";
4219  case UNW_RISCV_F0:
4220    return "ft0";
4221  case UNW_RISCV_F1:
4222    return "ft1";
4223  case UNW_RISCV_F2:
4224    return "ft2";
4225  case UNW_RISCV_F3:
4226    return "ft3";
4227  case UNW_RISCV_F4:
4228    return "ft4";
4229  case UNW_RISCV_F5:
4230    return "ft5";
4231  case UNW_RISCV_F6:
4232    return "ft6";
4233  case UNW_RISCV_F7:
4234    return "ft7";
4235  case UNW_RISCV_F8:
4236    return "fs0";
4237  case UNW_RISCV_F9:
4238    return "fs1";
4239  case UNW_RISCV_F10:
4240    return "fa0";
4241  case UNW_RISCV_F11:
4242    return "fa1";
4243  case UNW_RISCV_F12:
4244    return "fa2";
4245  case UNW_RISCV_F13:
4246    return "fa3";
4247  case UNW_RISCV_F14:
4248    return "fa4";
4249  case UNW_RISCV_F15:
4250    return "fa5";
4251  case UNW_RISCV_F16:
4252    return "fa6";
4253  case UNW_RISCV_F17:
4254    return "fa7";
4255  case UNW_RISCV_F18:
4256    return "fs2";
4257  case UNW_RISCV_F19:
4258    return "fs3";
4259  case UNW_RISCV_F20:
4260    return "fs4";
4261  case UNW_RISCV_F21:
4262    return "fs5";
4263  case UNW_RISCV_F22:
4264    return "fs6";
4265  case UNW_RISCV_F23:
4266    return "fs7";
4267  case UNW_RISCV_F24:
4268    return "fs8";
4269  case UNW_RISCV_F25:
4270    return "fs9";
4271  case UNW_RISCV_F26:
4272    return "fs10";
4273  case UNW_RISCV_F27:
4274    return "fs11";
4275  case UNW_RISCV_F28:
4276    return "ft8";
4277  case UNW_RISCV_F29:
4278    return "ft9";
4279  case UNW_RISCV_F30:
4280    return "ft10";
4281  case UNW_RISCV_F31:
4282    return "ft11";
4283  case UNW_RISCV_VLENB:
4284    return "vlenb";
4285  default:
4286    return "unknown register";
4287  }
4288}
4289
4290inline bool Registers_riscv::validFloatRegister(int regNum) const {
4291# if defined(__riscv_flen)
4292  if (regNum < UNW_RISCV_F0)
4293    return false;
4294  if (regNum > UNW_RISCV_F31)
4295    return false;
4296  return true;
4297# else
4298  (void)regNum;
4299  return false;
4300# endif
4301}
4302
4303inline fp_t Registers_riscv::getFloatRegister(int regNum) const {
4304# if defined(__riscv_flen)
4305  assert(validFloatRegister(regNum));
4306  return _floats[regNum - UNW_RISCV_F0];
4307# else
4308  (void)regNum;
4309  _LIBUNWIND_ABORT("libunwind not built with float support");
4310# endif
4311}
4312
4313inline void Registers_riscv::setFloatRegister(int regNum, fp_t value) {
4314# if defined(__riscv_flen)
4315  assert(validFloatRegister(regNum));
4316  _floats[regNum - UNW_RISCV_F0] = value;
4317# else
4318  (void)regNum;
4319  (void)value;
4320  _LIBUNWIND_ABORT("libunwind not built with float support");
4321# endif
4322}
4323
4324inline bool Registers_riscv::validVectorRegister(int) const {
4325  return false;
4326}
4327
4328inline v128 Registers_riscv::getVectorRegister(int) const {
4329  _LIBUNWIND_ABORT("no riscv vector register support yet");
4330}
4331
4332inline void Registers_riscv::setVectorRegister(int, v128) {
4333  _LIBUNWIND_ABORT("no riscv vector register support yet");
4334}
4335#endif // _LIBUNWIND_TARGET_RISCV
4336
4337#if defined(_LIBUNWIND_TARGET_VE)
4338/// Registers_ve holds the register state of a thread in a VE process.
4339class _LIBUNWIND_HIDDEN Registers_ve {
4340public:
4341  Registers_ve();
4342  Registers_ve(const void *registers);
4343
4344  bool        validRegister(int num) const;
4345  uint64_t    getRegister(int num) const;
4346  void        setRegister(int num, uint64_t value);
4347  bool        validFloatRegister(int num) const;
4348  double      getFloatRegister(int num) const;
4349  void        setFloatRegister(int num, double value);
4350  bool        validVectorRegister(int num) const;
4351  v128        getVectorRegister(int num) const;
4352  void        setVectorRegister(int num, v128 value);
4353  static const char *getRegisterName(int num);
4354  void        jumpto();
4355  static constexpr int lastDwarfRegNum() {
4356    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE;
4357  }
4358  static int  getArch() { return REGISTERS_VE; }
4359
4360  uint64_t  getSP() const         { return _registers.__s[11]; }
4361  void      setSP(uint64_t value) { _registers.__s[11] = value; }
4362  uint64_t  getIP() const         { return _registers.__ic; }
4363  void      setIP(uint64_t value) { _registers.__ic = value; }
4364
4365private:
4366  // FIXME: Need to store not only scalar registers but also vector and vector
4367  // mask registers.  VEOS uses mcontext_t defined in ucontext.h.  It takes
4368  // 524288 bytes (65536*8 bytes), though.  Currently, we use libunwind for
4369  // SjLj exception support only, so Registers_ve is not implemented completely.
4370  struct ve_thread_state_t {
4371    uint64_t __s[64]; // s0-s64
4372    uint64_t __ic;    // Instruction counter (IC)
4373    uint64_t __vixr;  // Vector Index Register
4374    uint64_t __vl;    // Vector Length Register
4375  };
4376
4377  ve_thread_state_t _registers; // total 67 registers
4378
4379  // Currently no vector register is preserved.
4380};
4381
4382inline Registers_ve::Registers_ve(const void *registers) {
4383  static_assert((check_fit<Registers_ve, unw_context_t>::does_fit),
4384                "ve registers do not fit into unw_context_t");
4385  memcpy(&_registers, static_cast<const uint8_t *>(registers),
4386         sizeof(_registers));
4387  static_assert(sizeof(_registers) == 536,
4388                "expected vector register offset to be 536");
4389}
4390
4391inline Registers_ve::Registers_ve() {
4392  memset(&_registers, 0, sizeof(_registers));
4393}
4394
4395inline bool Registers_ve::validRegister(int regNum) const {
4396  if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
4397    return true;
4398
4399  switch (regNum) {
4400  case UNW_REG_IP:
4401  case UNW_REG_SP:
4402  case UNW_VE_VIXR:
4403  case UNW_VE_VL:
4404    return true;
4405  default:
4406    return false;
4407  }
4408}
4409
4410inline uint64_t Registers_ve::getRegister(int regNum) const {
4411  if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63)
4412    return _registers.__s[regNum - UNW_VE_S0];
4413
4414  switch (regNum) {
4415  case UNW_REG_IP:
4416    return _registers.__ic;
4417  case UNW_REG_SP:
4418    return _registers.__s[11];
4419  case UNW_VE_VIXR:
4420    return _registers.__vixr;
4421  case UNW_VE_VL:
4422    return _registers.__vl;
4423  }
4424  _LIBUNWIND_ABORT("unsupported ve register");
4425}
4426
4427inline void Registers_ve::setRegister(int regNum, uint64_t value) {
4428  if (regNum >= UNW_VE_S0 && regNum <= UNW_VE_S63) {
4429    _registers.__s[regNum - UNW_VE_S0] = value;
4430    return;
4431  }
4432
4433  switch (regNum) {
4434  case UNW_REG_IP:
4435    _registers.__ic = value;
4436    return;
4437  case UNW_REG_SP:
4438    _registers.__s[11] = value;
4439    return;
4440  case UNW_VE_VIXR:
4441    _registers.__vixr = value;
4442    return;
4443  case UNW_VE_VL:
4444    _registers.__vl = value;
4445    return;
4446  }
4447  _LIBUNWIND_ABORT("unsupported ve register");
4448}
4449
4450inline bool Registers_ve::validFloatRegister(int /* regNum */) const {
4451  return false;
4452}
4453
4454inline double Registers_ve::getFloatRegister(int /* regNum */) const {
4455  _LIBUNWIND_ABORT("VE doesn't have float registers");
4456}
4457
4458inline void Registers_ve::setFloatRegister(int /* regNum */,
4459                                           double /* value */) {
4460  _LIBUNWIND_ABORT("VE doesn't have float registers");
4461}
4462
4463inline bool Registers_ve::validVectorRegister(int /* regNum */) const {
4464  return false;
4465}
4466
4467inline v128 Registers_ve::getVectorRegister(int /* regNum */) const {
4468  _LIBUNWIND_ABORT("VE vector support not implemented");
4469}
4470
4471inline void Registers_ve::setVectorRegister(int /* regNum */,
4472                                            v128 /* value */) {
4473  _LIBUNWIND_ABORT("VE vector support not implemented");
4474}
4475
4476inline const char *Registers_ve::getRegisterName(int regNum) {
4477  switch (regNum) {
4478  case UNW_REG_IP:
4479    return "ip";
4480  case UNW_REG_SP:
4481    return "sp";
4482  case UNW_VE_VIXR:
4483    return "vixr";
4484  case UNW_VE_VL:
4485    return "vl";
4486  case UNW_VE_S0:
4487    return "s0";
4488  case UNW_VE_S1:
4489    return "s1";
4490  case UNW_VE_S2:
4491    return "s2";
4492  case UNW_VE_S3:
4493    return "s3";
4494  case UNW_VE_S4:
4495    return "s4";
4496  case UNW_VE_S5:
4497    return "s5";
4498  case UNW_VE_S6:
4499    return "s6";
4500  case UNW_VE_S7:
4501    return "s7";
4502  case UNW_VE_S8:
4503    return "s8";
4504  case UNW_VE_S9:
4505    return "s9";
4506  case UNW_VE_S10:
4507    return "s10";
4508  case UNW_VE_S11:
4509    return "s11";
4510  case UNW_VE_S12:
4511    return "s12";
4512  case UNW_VE_S13:
4513    return "s13";
4514  case UNW_VE_S14:
4515    return "s14";
4516  case UNW_VE_S15:
4517    return "s15";
4518  case UNW_VE_S16:
4519    return "s16";
4520  case UNW_VE_S17:
4521    return "s17";
4522  case UNW_VE_S18:
4523    return "s18";
4524  case UNW_VE_S19:
4525    return "s19";
4526  case UNW_VE_S20:
4527    return "s20";
4528  case UNW_VE_S21:
4529    return "s21";
4530  case UNW_VE_S22:
4531    return "s22";
4532  case UNW_VE_S23:
4533    return "s23";
4534  case UNW_VE_S24:
4535    return "s24";
4536  case UNW_VE_S25:
4537    return "s25";
4538  case UNW_VE_S26:
4539    return "s26";
4540  case UNW_VE_S27:
4541    return "s27";
4542  case UNW_VE_S28:
4543    return "s28";
4544  case UNW_VE_S29:
4545    return "s29";
4546  case UNW_VE_S30:
4547    return "s30";
4548  case UNW_VE_S31:
4549    return "s31";
4550  case UNW_VE_S32:
4551    return "s32";
4552  case UNW_VE_S33:
4553    return "s33";
4554  case UNW_VE_S34:
4555    return "s34";
4556  case UNW_VE_S35:
4557    return "s35";
4558  case UNW_VE_S36:
4559    return "s36";
4560  case UNW_VE_S37:
4561    return "s37";
4562  case UNW_VE_S38:
4563    return "s38";
4564  case UNW_VE_S39:
4565    return "s39";
4566  case UNW_VE_S40:
4567    return "s40";
4568  case UNW_VE_S41:
4569    return "s41";
4570  case UNW_VE_S42:
4571    return "s42";
4572  case UNW_VE_S43:
4573    return "s43";
4574  case UNW_VE_S44:
4575    return "s44";
4576  case UNW_VE_S45:
4577    return "s45";
4578  case UNW_VE_S46:
4579    return "s46";
4580  case UNW_VE_S47:
4581    return "s47";
4582  case UNW_VE_S48:
4583    return "s48";
4584  case UNW_VE_S49:
4585    return "s49";
4586  case UNW_VE_S50:
4587    return "s50";
4588  case UNW_VE_S51:
4589    return "s51";
4590  case UNW_VE_S52:
4591    return "s52";
4592  case UNW_VE_S53:
4593    return "s53";
4594  case UNW_VE_S54:
4595    return "s54";
4596  case UNW_VE_S55:
4597    return "s55";
4598  case UNW_VE_S56:
4599    return "s56";
4600  case UNW_VE_S57:
4601    return "s57";
4602  case UNW_VE_S58:
4603    return "s58";
4604  case UNW_VE_S59:
4605    return "s59";
4606  case UNW_VE_S60:
4607    return "s60";
4608  case UNW_VE_S61:
4609    return "s61";
4610  case UNW_VE_S62:
4611    return "s62";
4612  case UNW_VE_S63:
4613    return "s63";
4614  case UNW_VE_V0:
4615    return "v0";
4616  case UNW_VE_V1:
4617    return "v1";
4618  case UNW_VE_V2:
4619    return "v2";
4620  case UNW_VE_V3:
4621    return "v3";
4622  case UNW_VE_V4:
4623    return "v4";
4624  case UNW_VE_V5:
4625    return "v5";
4626  case UNW_VE_V6:
4627    return "v6";
4628  case UNW_VE_V7:
4629    return "v7";
4630  case UNW_VE_V8:
4631    return "v8";
4632  case UNW_VE_V9:
4633    return "v9";
4634  case UNW_VE_V10:
4635    return "v10";
4636  case UNW_VE_V11:
4637    return "v11";
4638  case UNW_VE_V12:
4639    return "v12";
4640  case UNW_VE_V13:
4641    return "v13";
4642  case UNW_VE_V14:
4643    return "v14";
4644  case UNW_VE_V15:
4645    return "v15";
4646  case UNW_VE_V16:
4647    return "v16";
4648  case UNW_VE_V17:
4649    return "v17";
4650  case UNW_VE_V18:
4651    return "v18";
4652  case UNW_VE_V19:
4653    return "v19";
4654  case UNW_VE_V20:
4655    return "v20";
4656  case UNW_VE_V21:
4657    return "v21";
4658  case UNW_VE_V22:
4659    return "v22";
4660  case UNW_VE_V23:
4661    return "v23";
4662  case UNW_VE_V24:
4663    return "v24";
4664  case UNW_VE_V25:
4665    return "v25";
4666  case UNW_VE_V26:
4667    return "v26";
4668  case UNW_VE_V27:
4669    return "v27";
4670  case UNW_VE_V28:
4671    return "v28";
4672  case UNW_VE_V29:
4673    return "v29";
4674  case UNW_VE_V30:
4675    return "v30";
4676  case UNW_VE_V31:
4677    return "v31";
4678  case UNW_VE_V32:
4679    return "v32";
4680  case UNW_VE_V33:
4681    return "v33";
4682  case UNW_VE_V34:
4683    return "v34";
4684  case UNW_VE_V35:
4685    return "v35";
4686  case UNW_VE_V36:
4687    return "v36";
4688  case UNW_VE_V37:
4689    return "v37";
4690  case UNW_VE_V38:
4691    return "v38";
4692  case UNW_VE_V39:
4693    return "v39";
4694  case UNW_VE_V40:
4695    return "v40";
4696  case UNW_VE_V41:
4697    return "v41";
4698  case UNW_VE_V42:
4699    return "v42";
4700  case UNW_VE_V43:
4701    return "v43";
4702  case UNW_VE_V44:
4703    return "v44";
4704  case UNW_VE_V45:
4705    return "v45";
4706  case UNW_VE_V46:
4707    return "v46";
4708  case UNW_VE_V47:
4709    return "v47";
4710  case UNW_VE_V48:
4711    return "v48";
4712  case UNW_VE_V49:
4713    return "v49";
4714  case UNW_VE_V50:
4715    return "v50";
4716  case UNW_VE_V51:
4717    return "v51";
4718  case UNW_VE_V52:
4719    return "v52";
4720  case UNW_VE_V53:
4721    return "v53";
4722  case UNW_VE_V54:
4723    return "v54";
4724  case UNW_VE_V55:
4725    return "v55";
4726  case UNW_VE_V56:
4727    return "v56";
4728  case UNW_VE_V57:
4729    return "v57";
4730  case UNW_VE_V58:
4731    return "v58";
4732  case UNW_VE_V59:
4733    return "v59";
4734  case UNW_VE_V60:
4735    return "v60";
4736  case UNW_VE_V61:
4737    return "v61";
4738  case UNW_VE_V62:
4739    return "v62";
4740  case UNW_VE_V63:
4741    return "v63";
4742  case UNW_VE_VM0:
4743    return "vm0";
4744  case UNW_VE_VM1:
4745    return "vm1";
4746  case UNW_VE_VM2:
4747    return "vm2";
4748  case UNW_VE_VM3:
4749    return "vm3";
4750  case UNW_VE_VM4:
4751    return "vm4";
4752  case UNW_VE_VM5:
4753    return "vm5";
4754  case UNW_VE_VM6:
4755    return "vm6";
4756  case UNW_VE_VM7:
4757    return "vm7";
4758  case UNW_VE_VM8:
4759    return "vm8";
4760  case UNW_VE_VM9:
4761    return "vm9";
4762  case UNW_VE_VM10:
4763    return "vm10";
4764  case UNW_VE_VM11:
4765    return "vm11";
4766  case UNW_VE_VM12:
4767    return "vm12";
4768  case UNW_VE_VM13:
4769    return "vm13";
4770  case UNW_VE_VM14:
4771    return "vm14";
4772  case UNW_VE_VM15:
4773    return "vm15";
4774  }
4775  return "unknown register";
4776}
4777#endif // _LIBUNWIND_TARGET_VE
4778
4779#if defined(_LIBUNWIND_TARGET_S390X)
4780/// Registers_s390x holds the register state of a thread in a
4781/// 64-bit Linux on IBM zSystems process.
4782class _LIBUNWIND_HIDDEN Registers_s390x {
4783public:
4784  Registers_s390x();
4785  Registers_s390x(const void *registers);
4786
4787  bool        validRegister(int num) const;
4788  uint64_t    getRegister(int num) const;
4789  void        setRegister(int num, uint64_t value);
4790  bool        validFloatRegister(int num) const;
4791  double      getFloatRegister(int num) const;
4792  void        setFloatRegister(int num, double value);
4793  bool        validVectorRegister(int num) const;
4794  v128        getVectorRegister(int num) const;
4795  void        setVectorRegister(int num, v128 value);
4796  static const char *getRegisterName(int num);
4797  void        jumpto();
4798  static constexpr int lastDwarfRegNum() {
4799    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X;
4800  }
4801  static int  getArch() { return REGISTERS_S390X; }
4802
4803  uint64_t  getSP() const         { return _registers.__gpr[15]; }
4804  void      setSP(uint64_t value) { _registers.__gpr[15] = value; }
4805  uint64_t  getIP() const         { return _registers.__pswa; }
4806  void      setIP(uint64_t value) { _registers.__pswa = value; }
4807
4808private:
4809  struct s390x_thread_state_t {
4810    uint64_t __pswm;    // Problem Status Word: Mask
4811    uint64_t __pswa;    // Problem Status Word: Address (PC)
4812    uint64_t __gpr[16]; // General Purpose Registers
4813    double __fpr[16];   // Floating-Point Registers
4814  };
4815
4816  s390x_thread_state_t _registers;
4817};
4818
4819inline Registers_s390x::Registers_s390x(const void *registers) {
4820  static_assert((check_fit<Registers_s390x, unw_context_t>::does_fit),
4821                "s390x registers do not fit into unw_context_t");
4822  memcpy(&_registers, static_cast<const uint8_t *>(registers),
4823         sizeof(_registers));
4824}
4825
4826inline Registers_s390x::Registers_s390x() {
4827  memset(&_registers, 0, sizeof(_registers));
4828}
4829
4830inline bool Registers_s390x::validRegister(int regNum) const {
4831  switch (regNum) {
4832  case UNW_S390X_PSWM:
4833  case UNW_S390X_PSWA:
4834  case UNW_REG_IP:
4835  case UNW_REG_SP:
4836      return true;
4837  }
4838
4839  if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15)
4840    return true;
4841
4842  return false;
4843}
4844
4845inline uint64_t Registers_s390x::getRegister(int regNum) const {
4846  if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15)
4847    return _registers.__gpr[regNum - UNW_S390X_R0];
4848
4849  switch (regNum) {
4850  case UNW_S390X_PSWM:
4851    return _registers.__pswm;
4852  case UNW_S390X_PSWA:
4853  case UNW_REG_IP:
4854    return _registers.__pswa;
4855  case UNW_REG_SP:
4856    return _registers.__gpr[15];
4857  }
4858  _LIBUNWIND_ABORT("unsupported s390x register");
4859}
4860
4861inline void Registers_s390x::setRegister(int regNum, uint64_t value) {
4862  if (regNum >= UNW_S390X_R0 && regNum <= UNW_S390X_R15) {
4863    _registers.__gpr[regNum - UNW_S390X_R0] = value;
4864    return;
4865  }
4866
4867  switch (regNum) {
4868  case UNW_S390X_PSWM:
4869    _registers.__pswm = value;
4870    return;
4871  case UNW_S390X_PSWA:
4872  case UNW_REG_IP:
4873    _registers.__pswa = value;
4874    return;
4875  case UNW_REG_SP:
4876    _registers.__gpr[15] = value;
4877    return;
4878  }
4879  _LIBUNWIND_ABORT("unsupported s390x register");
4880}
4881
4882inline bool Registers_s390x::validFloatRegister(int regNum) const {
4883  return regNum >= UNW_S390X_F0 && regNum <= UNW_S390X_F15;
4884}
4885
4886inline double Registers_s390x::getFloatRegister(int regNum) const {
4887  // NOTE: FPR DWARF register numbers are not consecutive.
4888  switch (regNum) {
4889  case UNW_S390X_F0:
4890    return _registers.__fpr[0];
4891  case UNW_S390X_F1:
4892    return _registers.__fpr[1];
4893  case UNW_S390X_F2:
4894    return _registers.__fpr[2];
4895  case UNW_S390X_F3:
4896    return _registers.__fpr[3];
4897  case UNW_S390X_F4:
4898    return _registers.__fpr[4];
4899  case UNW_S390X_F5:
4900    return _registers.__fpr[5];
4901  case UNW_S390X_F6:
4902    return _registers.__fpr[6];
4903  case UNW_S390X_F7:
4904    return _registers.__fpr[7];
4905  case UNW_S390X_F8:
4906    return _registers.__fpr[8];
4907  case UNW_S390X_F9:
4908    return _registers.__fpr[9];
4909  case UNW_S390X_F10:
4910    return _registers.__fpr[10];
4911  case UNW_S390X_F11:
4912    return _registers.__fpr[11];
4913  case UNW_S390X_F12:
4914    return _registers.__fpr[12];
4915  case UNW_S390X_F13:
4916    return _registers.__fpr[13];
4917  case UNW_S390X_F14:
4918    return _registers.__fpr[14];
4919  case UNW_S390X_F15:
4920    return _registers.__fpr[15];
4921  }
4922  _LIBUNWIND_ABORT("unsupported s390x register");
4923}
4924
4925inline void Registers_s390x::setFloatRegister(int regNum, double value) {
4926  // NOTE: FPR DWARF register numbers are not consecutive.
4927  switch (regNum) {
4928  case UNW_S390X_F0:
4929    _registers.__fpr[0] = value;
4930    return;
4931  case UNW_S390X_F1:
4932    _registers.__fpr[1] = value;
4933    return;
4934  case UNW_S390X_F2:
4935    _registers.__fpr[2] = value;
4936    return;
4937  case UNW_S390X_F3:
4938    _registers.__fpr[3] = value;
4939    return;
4940  case UNW_S390X_F4:
4941    _registers.__fpr[4] = value;
4942    return;
4943  case UNW_S390X_F5:
4944    _registers.__fpr[5] = value;
4945    return;
4946  case UNW_S390X_F6:
4947    _registers.__fpr[6] = value;
4948    return;
4949  case UNW_S390X_F7:
4950    _registers.__fpr[7] = value;
4951    return;
4952  case UNW_S390X_F8:
4953    _registers.__fpr[8] = value;
4954    return;
4955  case UNW_S390X_F9:
4956    _registers.__fpr[9] = value;
4957    return;
4958  case UNW_S390X_F10:
4959    _registers.__fpr[10] = value;
4960    return;
4961  case UNW_S390X_F11:
4962    _registers.__fpr[11] = value;
4963    return;
4964  case UNW_S390X_F12:
4965    _registers.__fpr[12] = value;
4966    return;
4967  case UNW_S390X_F13:
4968    _registers.__fpr[13] = value;
4969    return;
4970  case UNW_S390X_F14:
4971    _registers.__fpr[14] = value;
4972    return;
4973  case UNW_S390X_F15:
4974    _registers.__fpr[15] = value;
4975    return;
4976  }
4977  _LIBUNWIND_ABORT("unsupported s390x register");
4978}
4979
4980inline bool Registers_s390x::validVectorRegister(int /*regNum*/) const {
4981  return false;
4982}
4983
4984inline v128 Registers_s390x::getVectorRegister(int /*regNum*/) const {
4985  _LIBUNWIND_ABORT("s390x vector support not implemented");
4986}
4987
4988inline void Registers_s390x::setVectorRegister(int /*regNum*/, v128 /*value*/) {
4989  _LIBUNWIND_ABORT("s390x vector support not implemented");
4990}
4991
4992inline const char *Registers_s390x::getRegisterName(int regNum) {
4993  switch (regNum) {
4994  case UNW_REG_IP:
4995    return "ip";
4996  case UNW_REG_SP:
4997    return "sp";
4998  case UNW_S390X_R0:
4999    return "r0";
5000  case UNW_S390X_R1:
5001    return "r1";
5002  case UNW_S390X_R2:
5003    return "r2";
5004  case UNW_S390X_R3:
5005    return "r3";
5006  case UNW_S390X_R4:
5007    return "r4";
5008  case UNW_S390X_R5:
5009    return "r5";
5010  case UNW_S390X_R6:
5011    return "r6";
5012  case UNW_S390X_R7:
5013    return "r7";
5014  case UNW_S390X_R8:
5015    return "r8";
5016  case UNW_S390X_R9:
5017    return "r9";
5018  case UNW_S390X_R10:
5019    return "r10";
5020  case UNW_S390X_R11:
5021    return "r11";
5022  case UNW_S390X_R12:
5023    return "r12";
5024  case UNW_S390X_R13:
5025    return "r13";
5026  case UNW_S390X_R14:
5027    return "r14";
5028  case UNW_S390X_R15:
5029    return "r15";
5030  case UNW_S390X_F0:
5031    return "f0";
5032  case UNW_S390X_F1:
5033    return "f1";
5034  case UNW_S390X_F2:
5035    return "f2";
5036  case UNW_S390X_F3:
5037    return "f3";
5038  case UNW_S390X_F4:
5039    return "f4";
5040  case UNW_S390X_F5:
5041    return "f5";
5042  case UNW_S390X_F6:
5043    return "f6";
5044  case UNW_S390X_F7:
5045    return "f7";
5046  case UNW_S390X_F8:
5047    return "f8";
5048  case UNW_S390X_F9:
5049    return "f9";
5050  case UNW_S390X_F10:
5051    return "f10";
5052  case UNW_S390X_F11:
5053    return "f11";
5054  case UNW_S390X_F12:
5055    return "f12";
5056  case UNW_S390X_F13:
5057    return "f13";
5058  case UNW_S390X_F14:
5059    return "f14";
5060  case UNW_S390X_F15:
5061    return "f15";
5062  }
5063  return "unknown register";
5064}
5065#endif // _LIBUNWIND_TARGET_S390X
5066
5067#if defined(_LIBUNWIND_TARGET_LOONGARCH)
5068/// Registers_loongarch holds the register state of a thread in a 64-bit
5069/// LoongArch process.
5070class _LIBUNWIND_HIDDEN Registers_loongarch {
5071public:
5072  Registers_loongarch();
5073  Registers_loongarch(const void *registers);
5074
5075  bool validRegister(int num) const;
5076  uint64_t getRegister(int num) const;
5077  void setRegister(int num, uint64_t value);
5078  bool validFloatRegister(int num) const;
5079  double getFloatRegister(int num) const;
5080  void setFloatRegister(int num, double value);
5081  bool validVectorRegister(int num) const;
5082  v128 getVectorRegister(int num) const;
5083  void setVectorRegister(int num, v128 value);
5084  static const char *getRegisterName(int num);
5085  void jumpto();
5086  static constexpr int lastDwarfRegNum() {
5087    return _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH;
5088  }
5089  static int getArch() { return REGISTERS_LOONGARCH; }
5090
5091  uint64_t getSP() const { return _registers.__r[3]; }
5092  void setSP(uint64_t value) { _registers.__r[3] = value; }
5093  uint64_t getIP() const { return _registers.__pc; }
5094  void setIP(uint64_t value) { _registers.__pc = value; }
5095
5096private:
5097  struct loongarch_thread_state_t {
5098    uint64_t __r[32];
5099    uint64_t __pc;
5100  };
5101
5102  loongarch_thread_state_t _registers;
5103#if __loongarch_frlen == 64
5104  double _floats[32];
5105#endif
5106};
5107
5108inline Registers_loongarch::Registers_loongarch(const void *registers) {
5109  static_assert((check_fit<Registers_loongarch, unw_context_t>::does_fit),
5110                "loongarch registers do not fit into unw_context_t");
5111  memcpy(&_registers, registers, sizeof(_registers));
5112  static_assert(sizeof(_registers) == 0x108,
5113                "expected float registers to be at offset 264");
5114#if __loongarch_frlen == 64
5115  memcpy(_floats, static_cast<const uint8_t *>(registers) + sizeof(_registers),
5116         sizeof(_floats));
5117#endif
5118}
5119
5120inline Registers_loongarch::Registers_loongarch() {
5121  memset(&_registers, 0, sizeof(_registers));
5122#if __loongarch_frlen == 64
5123  memset(&_floats, 0, sizeof(_floats));
5124#endif
5125}
5126
5127inline bool Registers_loongarch::validRegister(int regNum) const {
5128  if (regNum == UNW_REG_IP || regNum == UNW_REG_SP)
5129    return true;
5130  if (regNum < 0 || regNum > UNW_LOONGARCH_F31)
5131    return false;
5132  return true;
5133}
5134
5135inline uint64_t Registers_loongarch::getRegister(int regNum) const {
5136  if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31)
5137    return _registers.__r[regNum - UNW_LOONGARCH_R0];
5138
5139  if (regNum == UNW_REG_IP)
5140    return _registers.__pc;
5141  if (regNum == UNW_REG_SP)
5142    return _registers.__r[3];
5143  _LIBUNWIND_ABORT("unsupported loongarch register");
5144}
5145
5146inline void Registers_loongarch::setRegister(int regNum, uint64_t value) {
5147  if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31)
5148    _registers.__r[regNum - UNW_LOONGARCH_R0] = value;
5149  else if (regNum == UNW_REG_IP)
5150    _registers.__pc = value;
5151  else if (regNum == UNW_REG_SP)
5152    _registers.__r[3] = value;
5153  else
5154    _LIBUNWIND_ABORT("unsupported loongarch register");
5155}
5156
5157inline const char *Registers_loongarch::getRegisterName(int regNum) {
5158  switch (regNum) {
5159  case UNW_REG_IP:
5160    return "$pc";
5161  case UNW_REG_SP:
5162    return "$sp";
5163  case UNW_LOONGARCH_R0:
5164    return "$r0";
5165  case UNW_LOONGARCH_R1:
5166    return "$r1";
5167  case UNW_LOONGARCH_R2:
5168    return "$r2";
5169  case UNW_LOONGARCH_R3:
5170    return "$r3";
5171  case UNW_LOONGARCH_R4:
5172    return "$r4";
5173  case UNW_LOONGARCH_R5:
5174    return "$r5";
5175  case UNW_LOONGARCH_R6:
5176    return "$r6";
5177  case UNW_LOONGARCH_R7:
5178    return "$r7";
5179  case UNW_LOONGARCH_R8:
5180    return "$r8";
5181  case UNW_LOONGARCH_R9:
5182    return "$r9";
5183  case UNW_LOONGARCH_R10:
5184    return "$r10";
5185  case UNW_LOONGARCH_R11:
5186    return "$r11";
5187  case UNW_LOONGARCH_R12:
5188    return "$r12";
5189  case UNW_LOONGARCH_R13:
5190    return "$r13";
5191  case UNW_LOONGARCH_R14:
5192    return "$r14";
5193  case UNW_LOONGARCH_R15:
5194    return "$r15";
5195  case UNW_LOONGARCH_R16:
5196    return "$r16";
5197  case UNW_LOONGARCH_R17:
5198    return "$r17";
5199  case UNW_LOONGARCH_R18:
5200    return "$r18";
5201  case UNW_LOONGARCH_R19:
5202    return "$r19";
5203  case UNW_LOONGARCH_R20:
5204    return "$r20";
5205  case UNW_LOONGARCH_R21:
5206    return "$r21";
5207  case UNW_LOONGARCH_R22:
5208    return "$r22";
5209  case UNW_LOONGARCH_R23:
5210    return "$r23";
5211  case UNW_LOONGARCH_R24:
5212    return "$r24";
5213  case UNW_LOONGARCH_R25:
5214    return "$r25";
5215  case UNW_LOONGARCH_R26:
5216    return "$r26";
5217  case UNW_LOONGARCH_R27:
5218    return "$r27";
5219  case UNW_LOONGARCH_R28:
5220    return "$r28";
5221  case UNW_LOONGARCH_R29:
5222    return "$r29";
5223  case UNW_LOONGARCH_R30:
5224    return "$r30";
5225  case UNW_LOONGARCH_R31:
5226    return "$r31";
5227  case UNW_LOONGARCH_F0:
5228    return "$f0";
5229  case UNW_LOONGARCH_F1:
5230    return "$f1";
5231  case UNW_LOONGARCH_F2:
5232    return "$f2";
5233  case UNW_LOONGARCH_F3:
5234    return "$f3";
5235  case UNW_LOONGARCH_F4:
5236    return "$f4";
5237  case UNW_LOONGARCH_F5:
5238    return "$f5";
5239  case UNW_LOONGARCH_F6:
5240    return "$f6";
5241  case UNW_LOONGARCH_F7:
5242    return "$f7";
5243  case UNW_LOONGARCH_F8:
5244    return "$f8";
5245  case UNW_LOONGARCH_F9:
5246    return "$f9";
5247  case UNW_LOONGARCH_F10:
5248    return "$f10";
5249  case UNW_LOONGARCH_F11:
5250    return "$f11";
5251  case UNW_LOONGARCH_F12:
5252    return "$f12";
5253  case UNW_LOONGARCH_F13:
5254    return "$f13";
5255  case UNW_LOONGARCH_F14:
5256    return "$f14";
5257  case UNW_LOONGARCH_F15:
5258    return "$f15";
5259  case UNW_LOONGARCH_F16:
5260    return "$f16";
5261  case UNW_LOONGARCH_F17:
5262    return "$f17";
5263  case UNW_LOONGARCH_F18:
5264    return "$f18";
5265  case UNW_LOONGARCH_F19:
5266    return "$f19";
5267  case UNW_LOONGARCH_F20:
5268    return "$f20";
5269  case UNW_LOONGARCH_F21:
5270    return "$f21";
5271  case UNW_LOONGARCH_F22:
5272    return "$f22";
5273  case UNW_LOONGARCH_F23:
5274    return "$f23";
5275  case UNW_LOONGARCH_F24:
5276    return "$f24";
5277  case UNW_LOONGARCH_F25:
5278    return "$f25";
5279  case UNW_LOONGARCH_F26:
5280    return "$f26";
5281  case UNW_LOONGARCH_F27:
5282    return "$f27";
5283  case UNW_LOONGARCH_F28:
5284    return "$f28";
5285  case UNW_LOONGARCH_F29:
5286    return "$f29";
5287  case UNW_LOONGARCH_F30:
5288    return "$f30";
5289  case UNW_LOONGARCH_F31:
5290    return "$f31";
5291  default:
5292    return "unknown register";
5293  }
5294}
5295
5296inline bool Registers_loongarch::validFloatRegister(int regNum) const {
5297  if (regNum < UNW_LOONGARCH_F0 || regNum > UNW_LOONGARCH_F31)
5298    return false;
5299  return true;
5300}
5301
5302inline double Registers_loongarch::getFloatRegister(int regNum) const {
5303#if __loongarch_frlen == 64
5304  assert(validFloatRegister(regNum));
5305  return _floats[regNum - UNW_LOONGARCH_F0];
5306#else
5307  _LIBUNWIND_ABORT("libunwind not built with float support");
5308#endif
5309}
5310
5311inline void Registers_loongarch::setFloatRegister(int regNum, double value) {
5312#if __loongarch_frlen == 64
5313  assert(validFloatRegister(regNum));
5314  _floats[regNum - UNW_LOONGARCH_F0] = value;
5315#else
5316  _LIBUNWIND_ABORT("libunwind not built with float support");
5317#endif
5318}
5319
5320inline bool Registers_loongarch::validVectorRegister(int) const {
5321  return false;
5322}
5323
5324inline v128 Registers_loongarch::getVectorRegister(int) const {
5325  _LIBUNWIND_ABORT("loongarch vector support not implemented");
5326}
5327
5328inline void Registers_loongarch::setVectorRegister(int, v128) {
5329  _LIBUNWIND_ABORT("loongarch vector support not implemented");
5330}
5331#endif //_LIBUNWIND_TARGET_LOONGARCH
5332
5333} // namespace libunwind
5334
5335#endif // __REGISTERS_HPP__