1//===----------------------------- Registers.hpp --------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8// 9// Models register sets for supported processors. 10// 11//===----------------------------------------------------------------------===// 12#ifndef __REGISTERS_HPP__ 13#define __REGISTERS_HPP__ 14 15#include <sys/endian.h> 16#include <cassert> 17#include <cstdint> 18 19namespace _Unwind { 20 21enum { 22 REGNO_X86_EAX = 0, 23 REGNO_X86_ECX = 1, 24 REGNO_X86_EDX = 2, 25 REGNO_X86_EBX = 3, 26 REGNO_X86_ESP = 4, 27 REGNO_X86_EBP = 5, 28 REGNO_X86_ESI = 6, 29 REGNO_X86_EDI = 7, 30 REGNO_X86_EIP = 8, 31}; 32 33class Registers_x86 { 34public: 35 enum { 36 LAST_REGISTER = REGNO_X86_EIP, 37 LAST_RESTORE_REG = REGNO_X86_EIP, 38 RETURN_OFFSET = 0, 39 RETURN_MASK = 0, 40 }; 41 42 __dso_hidden Registers_x86(); 43 44 static int dwarf2regno(int num) { return num; } 45 46 bool validRegister(int num) const { 47 return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI; 48 } 49 50 uint32_t getRegister(int num) const { 51 assert(validRegister(num)); 52 return reg[num]; 53 } 54 55 void setRegister(int num, uint32_t value) { 56 assert(validRegister(num)); 57 reg[num] = value; 58 } 59 60 uint32_t getIP() const { return reg[REGNO_X86_EIP]; } 61 62 void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; } 63 64 uint32_t getSP() const { return reg[REGNO_X86_ESP]; } 65 66 void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; } 67 68 bool validFloatVectorRegister(int num) const { return false; } 69 70 void copyFloatVectorRegister(int num, uint32_t addr) { 71 } 72 73 __dso_hidden void jumpto() const __dead; 74 75private: 76 uint32_t reg[REGNO_X86_EIP + 1]; 77}; 78 79enum { 80 REGNO_X86_64_RAX = 0, 81 REGNO_X86_64_RDX = 1, 82 REGNO_X86_64_RCX = 2, 83 REGNO_X86_64_RBX = 3, 84 REGNO_X86_64_RSI = 4, 85 REGNO_X86_64_RDI = 5, 86 REGNO_X86_64_RBP = 6, 87 REGNO_X86_64_RSP = 7, 88 REGNO_X86_64_R8 = 8, 89 REGNO_X86_64_R9 = 9, 90 REGNO_X86_64_R10 = 10, 91 REGNO_X86_64_R11 = 11, 92 REGNO_X86_64_R12 = 12, 93 REGNO_X86_64_R13 = 13, 94 REGNO_X86_64_R14 = 14, 95 REGNO_X86_64_R15 = 15, 96 REGNO_X86_64_RIP = 16, 97}; 98 99class Registers_x86_64 { 100public: 101 enum { 102 LAST_REGISTER = REGNO_X86_64_RIP, 103 LAST_RESTORE_REG = REGNO_X86_64_RIP, 104 RETURN_OFFSET = 0, 105 RETURN_MASK = 0, 106 }; 107 108 __dso_hidden Registers_x86_64(); 109 110 static int dwarf2regno(int num) { return num; } 111 112 bool validRegister(int num) const { 113 return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15; 114 } 115 116 uint64_t getRegister(int num) const { 117 assert(validRegister(num)); 118 return reg[num]; 119 } 120 121 void setRegister(int num, uint64_t value) { 122 assert(validRegister(num)); 123 reg[num] = value; 124 } 125 126 uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; } 127 128 void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; } 129 130 uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; } 131 132 void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; } 133 134 bool validFloatVectorRegister(int num) const { return false; } 135 136 void copyFloatVectorRegister(int num, uint64_t addr) { 137 } 138 139 __dso_hidden void jumpto() const __dead; 140 141private: 142 uint64_t reg[REGNO_X86_64_RIP + 1]; 143}; 144 145enum { 146 DWARF_PPC32_R0 = 0, 147 DWARF_PPC32_R31 = 31, 148 DWARF_PPC32_F0 = 32, 149 DWARF_PPC32_F31 = 63, 150 DWARF_PPC32_LR = 65, 151 DWARF_PPC32_CTR = 66, 152 DWARF_PPC32_CR = 70, 153 DWARF_PPC32_XER = 76, 154 DWARF_PPC32_V0 = 77, 155 DWARF_PPC32_SIGRETURN = 99, 156 DWARF_PPC32_V31 = 108, 157 158 REGNO_PPC32_R0 = 0, 159 REGNO_PPC32_R1 = 1, 160 REGNO_PPC32_R31 = 31, 161 REGNO_PPC32_LR = 32, 162 REGNO_PPC32_CR = 33, 163 REGNO_PPC32_SRR0 = 34, 164 165 REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1, 166 REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31, 167 REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1, 168 REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31, 169 170 REGNO_PPC32_CTR = REGNO_PPC32_V31 + 1, 171 REGNO_PPC32_XER = REGNO_PPC32_CTR + 1, 172 REGNO_PPC32_SIGRETURN = REGNO_PPC32_XER + 1 173}; 174 175class Registers_ppc32 { 176public: 177 enum { 178 LAST_REGISTER = REGNO_PPC32_SIGRETURN, 179 LAST_RESTORE_REG = REGNO_PPC32_SIGRETURN, 180 RETURN_OFFSET = 0, 181 RETURN_MASK = 0, 182 }; 183 184 __dso_hidden Registers_ppc32(); 185 186 static int dwarf2regno(int num) { 187 if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31) 188 return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0); 189 if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31) 190 return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0); 191 if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31) 192 return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0); 193 switch (num) { 194 case DWARF_PPC32_LR: 195 return REGNO_PPC32_LR; 196 case DWARF_PPC32_CR: 197 return REGNO_PPC32_CR; 198 case DWARF_PPC32_CTR: 199 return REGNO_PPC32_CTR; 200 case DWARF_PPC32_XER: 201 return REGNO_PPC32_XER; 202 case DWARF_PPC32_SIGRETURN: 203 return REGNO_PPC32_SIGRETURN; 204 default: 205 return LAST_REGISTER + 1; 206 } 207 } 208 209 bool validRegister(int num) const { 210 return (num >= 0 && num <= REGNO_PPC32_SRR0) || 211 (num >= REGNO_PPC32_CTR && num <= REGNO_PPC32_SIGRETURN); 212 } 213 214 uint64_t getRegister(int num) const { 215 assert(validRegister(num)); 216 switch (num) { 217 case REGNO_PPC32_CTR: 218 return ctr_reg; 219 case REGNO_PPC32_XER: 220 return xer_reg; 221 case REGNO_PPC32_SIGRETURN: 222 return sigreturn_reg; 223 default: 224 return reg[num]; 225 } 226 } 227 228 void setRegister(int num, uint64_t value) { 229 assert(validRegister(num)); 230 switch (num) { 231 case REGNO_PPC32_CTR: 232 ctr_reg = value; 233 break; 234 case REGNO_PPC32_XER: 235 xer_reg = value; 236 break; 237 case REGNO_PPC32_SIGRETURN: 238 sigreturn_reg = value; 239 break; 240 default: 241 reg[num] = value; 242 } 243 } 244 245 uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; } 246 247 void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; } 248 249 uint64_t getSP() const { return reg[REGNO_PPC32_R1]; } 250 251 void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; } 252 253 bool validFloatVectorRegister(int num) const { 254 return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) || 255 (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31); 256 } 257 258 void copyFloatVectorRegister(int num, uint64_t addr_) { 259 const void *addr = reinterpret_cast<const void *>(addr_); 260 if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) 261 memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0])); 262 else 263 memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0])); 264 } 265 266 __dso_hidden void jumpto() const __dead; 267 268private: 269 struct vecreg_t { 270 uint64_t low, high; 271 }; 272 uint32_t reg[REGNO_PPC32_SRR0 + 1]; 273 uint32_t dummy; 274 uint64_t fpreg[32]; 275 vecreg_t vecreg[64]; 276 uint32_t ctr_reg; 277 uint32_t xer_reg; 278 uint32_t sigreturn_reg; 279}; 280 281enum { 282 DWARF_AARCH64_X0 = 0, 283 DWARF_AARCH64_X30 = 30, 284 DWARF_AARCH64_SP = 31, 285 DWARF_AARCH64_V0 = 64, 286 DWARF_AARCH64_V31 = 95, 287 DWARF_AARCH64_SIGRETURN = 96, 288 289 REGNO_AARCH64_X0 = 0, 290 REGNO_AARCH64_X30 = 30, 291 REGNO_AARCH64_SP = 31, 292 REGNO_AARCH64_V0 = 32, 293 REGNO_AARCH64_V31 = 63, 294 REGNO_AARCH64_SIGRETURN = 64, 295}; 296 297class Registers_aarch64 { 298public: 299 enum { 300 LAST_RESTORE_REG = REGNO_AARCH64_SIGRETURN, 301 LAST_REGISTER = REGNO_AARCH64_SIGRETURN, 302 RETURN_OFFSET = 0, 303 RETURN_MASK = 0, 304 }; 305 306 __dso_hidden Registers_aarch64(); 307 308 static int dwarf2regno(int num) { 309 if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30) 310 return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0); 311 if (num == DWARF_AARCH64_SP) 312 return REGNO_AARCH64_SP; 313 if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31) 314 return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0); 315 if (num == DWARF_AARCH64_SIGRETURN) 316 return REGNO_AARCH64_SIGRETURN; 317 return LAST_REGISTER + 1; 318 } 319 320 bool validRegister(int num) const { 321 return (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_SP) || 322 num == DWARF_AARCH64_SIGRETURN; 323 } 324 325 uint64_t getRegister(int num) const { 326 assert(validRegister(num)); 327 if (num == REGNO_AARCH64_SIGRETURN) 328 return sigreturn_reg; 329 return reg[num]; 330 } 331 332 void setRegister(int num, uint64_t value) { 333 assert(validRegister(num)); 334 if (num == REGNO_AARCH64_SIGRETURN) 335 sigreturn_reg = value; 336 else 337 reg[num] = value; 338 } 339 340 uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; } 341 342 void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; } 343 344 uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; } 345 346 void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; } 347 348 bool validFloatVectorRegister(int num) const { 349 return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31); 350 } 351 352 void copyFloatVectorRegister(int num, uint64_t addr_) { 353 const void *addr = reinterpret_cast<const void *>(addr_); 354 memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, 16); 355 } 356 357 __dso_hidden void jumpto() const __dead; 358 359private: 360 uint64_t reg[REGNO_AARCH64_SP + 1]; 361 uint64_t vecreg[64]; 362 uint64_t sigreturn_reg; 363}; 364 365enum { 366 DWARF_ARM32_R0 = 0, 367 DWARF_ARM32_R15 = 15, 368 DWARF_ARM32_SPSR = 128, 369 DWARF_ARM32_S0 = 64, 370 DWARF_ARM32_S31 = 95, 371 DWARF_ARM32_D0 = 256, 372 DWARF_ARM32_D31 = 287, 373 REGNO_ARM32_R0 = 0, 374 REGNO_ARM32_SP = 13, 375 REGNO_ARM32_R15 = 15, 376 REGNO_ARM32_SPSR = 16, 377 REGNO_ARM32_D0 = 17, 378 REGNO_ARM32_D15 = 32, 379 REGNO_ARM32_D31 = 48, 380 REGNO_ARM32_S0 = 49, 381 REGNO_ARM32_S31 = 80, 382}; 383 384#define FLAGS_VFPV2_USED 0x1 385#define FLAGS_VFPV3_USED 0x2 386#define FLAGS_LEGACY_VFPV2_REGNO 0x4 387#define FLAGS_EXTENDED_VFPV2_REGNO 0x8 388 389class Registers_arm32 { 390public: 391 enum { 392 LAST_REGISTER = REGNO_ARM32_S31, 393 LAST_RESTORE_REG = REGNO_ARM32_S31, 394 RETURN_OFFSET = 0, 395 RETURN_MASK = 0, 396 }; 397 398 __dso_hidden Registers_arm32(); 399 400 static int dwarf2regno(int num) { 401 if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15) 402 return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0); 403 if (num == DWARF_ARM32_SPSR) 404 return REGNO_ARM32_SPSR; 405 if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31) 406 return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0); 407 if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31) 408 return REGNO_ARM32_S0 + (num - DWARF_ARM32_S0); 409 return LAST_REGISTER + 1; 410 } 411 412 bool validRegister(int num) const { 413 return num >= 0 && num <= REGNO_ARM32_SPSR; 414 } 415 416 uint64_t getRegister(int num) const { 417 assert(validRegister(num)); 418 return reg[num]; 419 } 420 421 void setRegister(int num, uint64_t value) { 422 assert(validRegister(num)); 423 reg[num] = value; 424 } 425 426 uint64_t getIP() const { return reg[REGNO_ARM32_R15]; } 427 428 void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; } 429 430 uint64_t getSP() const { return reg[REGNO_ARM32_SP]; } 431 432 void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; } 433 434 bool validFloatVectorRegister(int num) const { 435 return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31); 436 } 437 438 void copyFloatVectorRegister(int num, uint64_t addr_) { 439 assert(validFloatVectorRegister(num)); 440 const void *addr = reinterpret_cast<const void *>(addr_); 441 if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) { 442 /* 443 * XXX 444 * There are two numbering schemes for VFPv2 registers: s0-s31 445 * (used by GCC) and d0-d15 (used by LLVM). We won't support both 446 * schemes simultaneously in a same frame. 447 */ 448 assert((flags & FLAGS_EXTENDED_VFPV2_REGNO) == 0); 449 flags |= FLAGS_LEGACY_VFPV2_REGNO; 450 if ((flags & FLAGS_VFPV2_USED) == 0) { 451 lazyVFPv2(); 452 flags |= FLAGS_VFPV2_USED; 453 } 454 /* 455 * Emulate single precision register as half of the 456 * corresponding double register. 457 */ 458 int dnum = (num - REGNO_ARM32_S0) / 2; 459 int part = (num - REGNO_ARM32_S0) % 2; 460#if _BYTE_ORDER == _BIG_ENDIAN 461 part = 1 - part; 462#endif 463 memcpy((uint8_t *)(fpreg + dnum) + part * sizeof(fpreg[0]) / 2, 464 addr, sizeof(fpreg[0]) / 2); 465 } else { 466 if (num <= REGNO_ARM32_D15) { 467 /* 468 * XXX 469 * See XXX comment above. 470 */ 471 assert((flags & FLAGS_LEGACY_VFPV2_REGNO) == 0); 472 flags |= FLAGS_EXTENDED_VFPV2_REGNO; 473 if ((flags & FLAGS_VFPV2_USED) == 0) { 474 lazyVFPv2(); 475 flags |= FLAGS_VFPV2_USED; 476 } 477 } else { 478 if ((flags & FLAGS_VFPV3_USED) == 0) { 479 lazyVFPv3(); 480 flags |= FLAGS_VFPV3_USED; 481 } 482 } 483 memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0])); 484 } 485 } 486 487 __dso_hidden void lazyVFPv2(); 488 __dso_hidden void lazyVFPv3(); 489 __dso_hidden void jumpto() const __dead; 490 491private: 492 uint32_t reg[REGNO_ARM32_SPSR + 1]; 493 uint32_t flags; 494 uint64_t fpreg[32]; 495}; 496 497#undef FLAGS_VFPV2_USED 498#undef FLAGS_VFPV3_USED 499#undef FLAGS_LEGACY_VFPV2_REGNO 500#undef FLAGS_EXTENDED_VFPV2_REGNO 501 502enum { 503 DWARF_VAX_R0 = 0, 504 DWARF_VAX_R15 = 15, 505 DWARF_VAX_PSW = 16, 506 507 REGNO_VAX_R0 = 0, 508 REGNO_VAX_R14 = 14, 509 REGNO_VAX_R15 = 15, 510 REGNO_VAX_PSW = 16, 511}; 512 513class Registers_vax { 514public: 515 enum { 516 LAST_REGISTER = REGNO_VAX_PSW, 517 LAST_RESTORE_REG = REGNO_VAX_PSW, 518 RETURN_OFFSET = 0, 519 RETURN_MASK = 0, 520 }; 521 522 __dso_hidden Registers_vax(); 523 524 static int dwarf2regno(int num) { 525 if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15) 526 return REGNO_VAX_R0 + (num - DWARF_VAX_R0); 527 if (num == DWARF_VAX_PSW) 528 return REGNO_VAX_PSW; 529 return LAST_REGISTER + 1; 530 } 531 532 bool validRegister(int num) const { 533 return num >= 0 && num <= LAST_RESTORE_REG; 534 } 535 536 uint64_t getRegister(int num) const { 537 assert(validRegister(num)); 538 return reg[num]; 539 } 540 541 void setRegister(int num, uint64_t value) { 542 assert(validRegister(num)); 543 reg[num] = value; 544 } 545 546 uint64_t getIP() const { return reg[REGNO_VAX_R15]; } 547 548 void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; } 549 550 uint64_t getSP() const { return reg[REGNO_VAX_R14]; } 551 552 void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; } 553 554 bool validFloatVectorRegister(int num) const { 555 return false; 556 } 557 558 void copyFloatVectorRegister(int num, uint64_t addr_) { 559 } 560 561 __dso_hidden void jumpto() const __dead; 562 563private: 564 uint32_t reg[REGNO_VAX_PSW + 1]; 565}; 566 567enum { 568 DWARF_M68K_A0 = 0, 569 DWARF_M68K_A7 = 7, 570 DWARF_M68K_D0 = 8, 571 DWARF_M68K_D7 = 15, 572 DWARF_M68K_FP0 = 16, 573 DWARF_M68K_FP7 = 23, 574 DWARF_M68K_PC = 24, 575 // DWARF pseudo-register that is an alternate that may be used 576 // for the return address. 577 DWARF_M68K_ALT_PC = 25, 578 579 REGNO_M68K_A0 = 0, 580 REGNO_M68K_A7 = 7, 581 REGNO_M68K_D0 = 8, 582 REGNO_M68K_D7 = 15, 583 REGNO_M68K_PC = 16, 584 REGNO_M68K_FP0 = 17, 585 REGNO_M68K_FP7 = 24, 586}; 587 588class Registers_M68K { 589public: 590 enum { 591 LAST_REGISTER = REGNO_M68K_FP7, 592 LAST_RESTORE_REG = REGNO_M68K_FP7, 593 RETURN_OFFSET = 0, 594 RETURN_MASK = 0, 595 }; 596 597 __dso_hidden Registers_M68K(); 598 599 static int dwarf2regno(int num) { 600 if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7) 601 return REGNO_M68K_A0 + (num - DWARF_M68K_A0); 602 if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7) 603 return REGNO_M68K_D0 + (num - DWARF_M68K_D0); 604 if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7) 605 return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0); 606 if (num == DWARF_M68K_PC || num == DWARF_M68K_ALT_PC) 607 return REGNO_M68K_PC; 608 return LAST_REGISTER + 1; 609 } 610 611 bool validRegister(int num) const { 612 return num >= 0 && num <= REGNO_M68K_PC; 613 } 614 615 uint64_t getRegister(int num) const { 616 assert(validRegister(num)); 617 return reg[num]; 618 } 619 620 void setRegister(int num, uint64_t value) { 621 assert(validRegister(num)); 622 reg[num] = value; 623 } 624 625 uint64_t getIP() const { return reg[REGNO_M68K_PC]; } 626 627 void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; } 628 629 uint64_t getSP() const { return reg[REGNO_M68K_A7]; } 630 631 void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; } 632 633 bool validFloatVectorRegister(int num) const { 634 return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7; 635 } 636 637 void copyFloatVectorRegister(int num, uint64_t addr_) { 638 assert(validFloatVectorRegister(num)); 639 const void *addr = reinterpret_cast<const void *>(addr_); 640 memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0])); 641 } 642 643 __dso_hidden void jumpto() const __dead; 644 645private: 646 typedef uint32_t fpreg_t[3]; 647 648 uint32_t reg[REGNO_M68K_PC + 1]; 649 uint32_t dummy; 650 fpreg_t fpreg[8]; 651}; 652 653enum { 654 DWARF_SH3_R0 = 0, 655 DWARF_SH3_R15 = 15, 656 DWARF_SH3_PC = 16, 657 DWARF_SH3_PR = 17, 658 DWARF_SH3_GBR = 18, 659 DWARF_SH3_MACH = 20, 660 DWARF_SH3_MACL = 21, 661 DWARF_SH3_SR = 22, 662 663 REGNO_SH3_R0 = 0, 664 REGNO_SH3_R15 = 15, 665 REGNO_SH3_PC = 16, 666 REGNO_SH3_PR = 17, 667 REGNO_SH3_GBR = 18, 668 REGNO_SH3_MACH = 20, 669 REGNO_SH3_MACL = 21, 670 REGNO_SH3_SR = 22, 671}; 672 673class Registers_SH3 { 674public: 675 enum { 676 LAST_REGISTER = REGNO_SH3_SR, 677 LAST_RESTORE_REG = REGNO_SH3_SR, 678 RETURN_OFFSET = 0, 679 RETURN_MASK = 0, 680 }; 681 682 __dso_hidden Registers_SH3(); 683 684 static int dwarf2regno(int num) { 685 if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15) 686 return REGNO_SH3_R0 + (num - DWARF_SH3_R0); 687 switch (num) { 688 case DWARF_SH3_PC: 689 return REGNO_SH3_PC; 690 case DWARF_SH3_PR: 691 return REGNO_SH3_PR; 692 case DWARF_SH3_GBR: 693 return REGNO_SH3_GBR; 694 case DWARF_SH3_MACH: 695 return REGNO_SH3_MACH; 696 case DWARF_SH3_MACL: 697 return REGNO_SH3_MACL; 698 case DWARF_SH3_SR: 699 return REGNO_SH3_SR; 700 default: 701 return LAST_REGISTER + 1; 702 } 703 } 704 705 bool validRegister(int num) const { 706 return (num >= 0 && num <= REGNO_SH3_GBR) || 707 (num >= REGNO_SH3_MACH && num <= REGNO_SH3_SR); 708 } 709 710 uint64_t getRegister(int num) const { 711 assert(validRegister(num)); 712 return reg[num]; 713 } 714 715 void setRegister(int num, uint64_t value) { 716 assert(validRegister(num)); 717 reg[num] = value; 718 } 719 720 uint64_t getIP() const { return reg[REGNO_SH3_PC]; } 721 722 void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; } 723 724 uint64_t getSP() const { return reg[REGNO_SH3_R15]; } 725 726 void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; } 727 728 bool validFloatVectorRegister(int num) const { return false; } 729 730 void copyFloatVectorRegister(int num, uint64_t addr_) {} 731 732 __dso_hidden void jumpto() const __dead; 733 734private: 735 uint32_t reg[REGNO_SH3_SR + 1]; 736}; 737 738enum { 739 DWARF_SPARC64_R0 = 0, 740 DWARF_SPARC64_R31 = 31, 741 DWARF_SPARC64_PC = 32, 742 743 REGNO_SPARC64_R0 = 0, 744 REGNO_SPARC64_R14 = 14, 745 REGNO_SPARC64_R15 = 15, 746 REGNO_SPARC64_R31 = 31, 747 REGNO_SPARC64_PC = 32, 748}; 749 750class Registers_SPARC64 { 751public: 752 enum { 753 LAST_REGISTER = REGNO_SPARC64_PC, 754 LAST_RESTORE_REG = REGNO_SPARC64_PC, 755 RETURN_OFFSET = 8, 756 RETURN_MASK = 0, 757 }; 758 typedef uint64_t reg_t; 759 760 __dso_hidden Registers_SPARC64(); 761 762 static int dwarf2regno(int num) { 763 if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31) 764 return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0); 765 if (num == DWARF_SPARC64_PC) 766 return REGNO_SPARC64_PC; 767 return LAST_REGISTER + 1; 768 } 769 770 bool validRegister(int num) const { 771 return num >= 0 && num <= REGNO_SPARC64_PC; 772 } 773 774 uint64_t getRegister(int num) const { 775 assert(validRegister(num)); 776 return reg[num]; 777 } 778 779 void setRegister(int num, uint64_t value) { 780 assert(validRegister(num)); 781 reg[num] = value; 782 } 783 784 uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; } 785 786 void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; } 787 788 uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; } 789 790 void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; } 791 792 bool validFloatVectorRegister(int num) const { return false; } 793 794 void copyFloatVectorRegister(int num, uint64_t addr_) {} 795 796 __dso_hidden void jumpto() const __dead; 797 798private: 799 uint64_t reg[REGNO_SPARC64_PC + 1]; 800}; 801 802enum { 803 DWARF_SPARC_R0 = 0, 804 DWARF_SPARC_R31 = 31, 805 DWARF_SPARC_PC = 32, 806 807 REGNO_SPARC_R0 = 0, 808 REGNO_SPARC_R14 = 14, 809 REGNO_SPARC_R15 = 15, 810 REGNO_SPARC_R31 = 31, 811 REGNO_SPARC_PC = 32, 812}; 813 814class Registers_SPARC { 815public: 816 enum { 817 LAST_REGISTER = REGNO_SPARC_PC, 818 LAST_RESTORE_REG = REGNO_SPARC_PC, 819 RETURN_OFFSET = 8, 820 RETURN_MASK = 0, 821 }; 822 typedef uint32_t reg_t; 823 824 __dso_hidden Registers_SPARC(); 825 826 static int dwarf2regno(int num) { 827 if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31) 828 return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0); 829 if (num == DWARF_SPARC_PC) 830 return REGNO_SPARC_PC; 831 return LAST_REGISTER + 1; 832 } 833 834 bool validRegister(int num) const { 835 return num >= 0 && num <= REGNO_SPARC_PC; 836 } 837 838 uint64_t getRegister(int num) const { 839 assert(validRegister(num)); 840 return reg[num]; 841 } 842 843 void setRegister(int num, uint64_t value) { 844 assert(validRegister(num)); 845 reg[num] = value; 846 } 847 848 uint64_t getIP() const { return reg[REGNO_SPARC_PC]; } 849 850 void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; } 851 852 uint64_t getSP() const { return reg[REGNO_SPARC_R14]; } 853 854 void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; } 855 856 bool validFloatVectorRegister(int num) const { return false; } 857 858 void copyFloatVectorRegister(int num, uint64_t addr_) {} 859 860 __dso_hidden void jumpto() const __dead; 861 862private: 863 uint32_t reg[REGNO_SPARC_PC + 1]; 864}; 865 866enum { 867 DWARF_ALPHA_R0 = 0, 868 DWARF_ALPHA_R30 = 30, 869 DWARF_ALPHA_F0 = 32, 870 DWARF_ALPHA_F30 = 62, 871 DWARF_ALPHA_SIGRETURN = 64, 872 873 REGNO_ALPHA_R0 = 0, 874 REGNO_ALPHA_R26 = 26, 875 REGNO_ALPHA_R30 = 30, 876 REGNO_ALPHA_PC = 31, 877 REGNO_ALPHA_F0 = 32, 878 REGNO_ALPHA_F30 = 62, 879 REGNO_ALPHA_SIGRETURN = 64, 880}; 881 882class Registers_Alpha { 883public: 884 enum { 885 LAST_REGISTER = REGNO_ALPHA_SIGRETURN, 886 LAST_RESTORE_REG = REGNO_ALPHA_SIGRETURN, 887 RETURN_OFFSET = 0, 888 RETURN_MASK = 0, 889 }; 890 891 __dso_hidden Registers_Alpha(); 892 893 static int dwarf2regno(int num) { return num; } 894 895 bool validRegister(int num) const { 896 return (num >= 0 && num <= REGNO_ALPHA_PC) || 897 num == REGNO_ALPHA_SIGRETURN; 898 } 899 900 uint64_t getRegister(int num) const { 901 assert(validRegister(num)); 902 if (num == REGNO_ALPHA_SIGRETURN) 903 return sigreturn_reg; 904 else 905 return reg[num]; 906 } 907 908 void setRegister(int num, uint64_t value) { 909 assert(validRegister(num)); 910 if (num == REGNO_ALPHA_SIGRETURN) 911 sigreturn_reg = value; 912 else 913 reg[num] = value; 914 } 915 916 uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; } 917 918 void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; } 919 920 uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; } 921 922 void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; } 923 924 bool validFloatVectorRegister(int num) const { 925 return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30; 926 } 927 928 void copyFloatVectorRegister(int num, uint64_t addr_) { 929 assert(validFloatVectorRegister(num)); 930 const void *addr = reinterpret_cast<const void *>(addr_); 931 memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0])); 932 } 933 934 __dso_hidden void jumpto() const __dead; 935 936private: 937 uint64_t reg[REGNO_ALPHA_PC + 1]; 938 uint64_t fpreg[31]; 939 uint64_t sigreturn_reg; 940}; 941 942enum { 943 DWARF_HPPA_R1 = 1, 944 DWARF_HPPA_R31 = 31, 945 DWARF_HPPA_FR4L = 32, 946 DWARF_HPPA_FR31H = 87, 947 DWARF_HPPA_SIGRETURN = 89, 948 949 REGNO_HPPA_PC = 0, 950 REGNO_HPPA_R1 = 1, 951 REGNO_HPPA_R2 = 2, 952 REGNO_HPPA_R30 = 30, 953 REGNO_HPPA_R31 = 31, 954 REGNO_HPPA_FR4L = 32, 955 REGNO_HPPA_FR31H = 87, 956 REGNO_HPPA_SIGRETURN = 89, 957}; 958 959class Registers_HPPA { 960public: 961 enum { 962 LAST_REGISTER = REGNO_HPPA_FR31H, 963 LAST_RESTORE_REG = REGNO_HPPA_SIGRETURN, 964 RETURN_OFFSET = 0, 965 RETURN_MASK = 3, 966 }; 967 968 __dso_hidden Registers_HPPA(); 969 970 static int dwarf2regno(int num) { 971 if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31) 972 return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1); 973 if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H) 974 return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H); 975 if (num == DWARF_HPPA_SIGRETURN) 976 return REGNO_HPPA_SIGRETURN; 977 return LAST_REGISTER + 1; 978 } 979 980 bool validRegister(int num) const { 981 return (num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31) || 982 num == REGNO_HPPA_SIGRETURN; 983 } 984 985 uint64_t getRegister(int num) const { 986 assert(validRegister(num)); 987 if (num == REGNO_HPPA_SIGRETURN) 988 return sigreturn_reg; 989 else 990 return reg[num]; 991 } 992 993 void setRegister(int num, uint64_t value) { 994 assert(validRegister(num)); 995 if (num == REGNO_HPPA_SIGRETURN) 996 sigreturn_reg = value; 997 else 998 reg[num] = value; 999 } 1000 1001 uint64_t getIP() const { return reg[REGNO_HPPA_PC]; } 1002 1003 void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; } 1004 1005 uint64_t getSP() const { return reg[REGNO_HPPA_R30]; } 1006 1007 void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; } 1008 1009 bool validFloatVectorRegister(int num) const { 1010 return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H; 1011 } 1012 1013 void copyFloatVectorRegister(int num, uint64_t addr_) { 1014 assert(validFloatVectorRegister(num)); 1015 const void *addr = reinterpret_cast<const void *>(addr_); 1016 memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0])); 1017 } 1018 1019 __dso_hidden void jumpto() const __dead; 1020 1021private: 1022 uint32_t reg[REGNO_HPPA_R31 + 1]; 1023 uint32_t fpreg[56]; 1024 uint32_t sigreturn_reg; 1025}; 1026 1027enum { 1028 DWARF_MIPS_R1 = 0, 1029 DWARF_MIPS_R31 = 31, 1030 DWARF_MIPS_F0 = 32, 1031 DWARF_MIPS_F31 = 63, 1032 // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and 1033 // signal handler return address. 1034 DWARF_MIPS_MDHI = 64, 1035 DWARF_MIPS_MDLO = 65, 1036 DWARF_MIPS_SIGRETURN = 66, 1037 1038 REGNO_MIPS_PC = 0, 1039 REGNO_MIPS_R1 = 0, 1040 REGNO_MIPS_R29 = 29, 1041 REGNO_MIPS_R31 = 31, 1042 REGNO_MIPS_F0 = 33, 1043 REGNO_MIPS_F31 = 64, 1044 // these live in other_reg[] 1045 REGNO_MIPS_MDHI = 65, 1046 REGNO_MIPS_MDLO = 66, 1047 REGNO_MIPS_SIGRETURN = 67 1048}; 1049 1050class Registers_MIPS { 1051public: 1052 enum { 1053 LAST_REGISTER = REGNO_MIPS_SIGRETURN, 1054 LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN, 1055 RETURN_OFFSET = 0, 1056 RETURN_MASK = 0, 1057 }; 1058 1059 __dso_hidden Registers_MIPS(); 1060 1061 static int dwarf2regno(int num) { 1062 if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31) 1063 return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1); 1064 if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31) 1065 return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0); 1066 if (num >= DWARF_MIPS_MDHI && num <= DWARF_MIPS_SIGRETURN) 1067 return REGNO_MIPS_MDHI + (num - DWARF_MIPS_MDHI); 1068 return LAST_REGISTER + 1; 1069 } 1070 1071 bool validRegister(int num) const { 1072 return (num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31) || 1073 (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN); 1074 } 1075 1076 uint64_t getRegister(int num) const { 1077 assert(validRegister(num)); 1078 if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN) 1079 return other_reg[num - REGNO_MIPS_MDHI]; 1080 return reg[num]; 1081 } 1082 1083 void setRegister(int num, uint64_t value) { 1084 assert(validRegister(num)); 1085 if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN) 1086 other_reg[num - REGNO_MIPS_MDHI] = value; 1087 else 1088 reg[num] = value; 1089 } 1090 1091 uint64_t getIP() const { return reg[REGNO_MIPS_PC]; } 1092 1093 void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; } 1094 1095 uint64_t getSP() const { return reg[REGNO_MIPS_R29]; } 1096 1097 void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; } 1098 1099 bool validFloatVectorRegister(int num) const { 1100 return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31; 1101 } 1102 1103 void copyFloatVectorRegister(int num, uint64_t addr_) { 1104 assert(validFloatVectorRegister(num)); 1105 const void *addr = reinterpret_cast<const void *>(addr_); 1106 memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0])); 1107 } 1108 1109 __dso_hidden void jumpto() const __dead; 1110 1111private: 1112 uint32_t reg[REGNO_MIPS_R31 + 1]; 1113 uint64_t fpreg[32]; 1114 uint32_t other_reg[3]; 1115}; 1116 1117enum { 1118 DWARF_MIPS64_R1 = 0, 1119 DWARF_MIPS64_R31 = 31, 1120 DWARF_MIPS64_F0 = 32, 1121 DWARF_MIPS64_F31 = 63, 1122 // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and 1123 // signal handler return address. 1124 DWARF_MIPS64_MDHI = 64, 1125 DWARF_MIPS64_MDLO = 65, 1126 DWARF_MIPS64_SIGRETURN = 66, 1127 1128 REGNO_MIPS64_PC = 0, 1129 REGNO_MIPS64_R1 = 0, 1130 REGNO_MIPS64_R29 = 29, 1131 REGNO_MIPS64_R31 = 31, 1132 REGNO_MIPS64_F0 = 33, 1133 REGNO_MIPS64_F31 = 64, 1134 // these live in other_reg[] 1135 REGNO_MIPS64_MDHI = 65, 1136 REGNO_MIPS64_MDLO = 66, 1137 REGNO_MIPS64_SIGRETURN = 67 1138}; 1139 1140class Registers_MIPS64 { 1141public: 1142 enum { 1143 LAST_REGISTER = REGNO_MIPS_SIGRETURN, 1144 LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN, 1145 RETURN_OFFSET = 0, 1146 RETURN_MASK = 0, 1147 }; 1148 1149 __dso_hidden Registers_MIPS64(); 1150 1151 static int dwarf2regno(int num) { 1152 if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31) 1153 return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1); 1154 if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31) 1155 return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0); 1156 if (num >= DWARF_MIPS64_MDHI && num <= DWARF_MIPS64_SIGRETURN) 1157 return REGNO_MIPS64_MDHI + (num - DWARF_MIPS64_MDHI); 1158 return LAST_REGISTER + 1; 1159 } 1160 1161 bool validRegister(int num) const { 1162 return (num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31) || 1163 (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN); 1164 } 1165 1166 uint64_t getRegister(int num) const { 1167 assert(validRegister(num)); 1168 if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN) 1169 return other_reg[num - REGNO_MIPS64_MDHI]; 1170 return reg[num]; 1171 } 1172 1173 void setRegister(int num, uint64_t value) { 1174 assert(validRegister(num)); 1175 if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN) 1176 other_reg[num - REGNO_MIPS64_MDHI] = value; 1177 else 1178 reg[num] = value; 1179 } 1180 1181 uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; } 1182 1183 void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; } 1184 1185 uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; } 1186 1187 void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; } 1188 1189 bool validFloatVectorRegister(int num) const { 1190 return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31; 1191 } 1192 1193 void copyFloatVectorRegister(int num, uint64_t addr_) { 1194 assert(validFloatVectorRegister(num)); 1195 const void *addr = reinterpret_cast<const void *>(addr_); 1196 memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0])); 1197 } 1198 1199 __dso_hidden void jumpto() const __dead; 1200 1201private: 1202 uint64_t reg[REGNO_MIPS64_R31 + 1]; 1203 uint64_t fpreg[32]; 1204 uint64_t other_reg[3]; 1205}; 1206 1207enum { 1208 DWARF_OR1K_R0 = 0, 1209 DWARF_OR1K_SP = 1, 1210 DWARF_OR1K_LR = 9, 1211 DWARF_OR1K_R31 = 31, 1212 DWARF_OR1K_FPCSR = 32, 1213 1214 REGNO_OR1K_R0 = 0, 1215 REGNO_OR1K_SP = 1, 1216 REGNO_OR1K_LR = 9, 1217 REGNO_OR1K_R31 = 31, 1218 REGNO_OR1K_FPCSR = 32, 1219}; 1220 1221class Registers_or1k { 1222public: 1223 enum { 1224 LAST_REGISTER = REGNO_OR1K_FPCSR, 1225 LAST_RESTORE_REG = REGNO_OR1K_FPCSR, 1226 RETURN_OFFSET = 0, 1227 RETURN_MASK = 0, 1228 }; 1229 1230 __dso_hidden Registers_or1k(); 1231 1232 static int dwarf2regno(int num) { 1233 if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31) 1234 return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0); 1235 if (num == DWARF_OR1K_FPCSR) 1236 return REGNO_OR1K_FPCSR; 1237 return LAST_REGISTER + 1; 1238 } 1239 1240 bool validRegister(int num) const { 1241 return num >= 0 && num <= LAST_RESTORE_REG; 1242 } 1243 1244 uint64_t getRegister(int num) const { 1245 assert(validRegister(num)); 1246 return reg[num]; 1247 } 1248 1249 void setRegister(int num, uint64_t value) { 1250 assert(validRegister(num)); 1251 reg[num] = value; 1252 } 1253 1254 uint64_t getIP() const { return reg[REGNO_OR1K_LR]; } 1255 1256 void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; } 1257 1258 uint64_t getSP() const { return reg[REGNO_OR1K_SP]; } 1259 1260 void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; } 1261 1262 bool validFloatVectorRegister(int num) const { 1263 return false; 1264 } 1265 1266 void copyFloatVectorRegister(int num, uint64_t addr_) { 1267 } 1268 1269 __dso_hidden void jumpto() const __dead; 1270 1271private: 1272 uint32_t reg[REGNO_OR1K_FPCSR + 1]; 1273}; 1274 1275#if __i386__ 1276typedef Registers_x86 NativeUnwindRegisters; 1277#elif __x86_64__ 1278typedef Registers_x86_64 NativeUnwindRegisters; 1279#elif __powerpc__ 1280typedef Registers_ppc32 NativeUnwindRegisters; 1281#elif __aarch64__ 1282typedef Registers_aarch64 NativeUnwindRegisters; 1283#elif __arm__ 1284typedef Registers_arm32 NativeUnwindRegisters; 1285#elif __vax__ 1286typedef Registers_vax NativeUnwindRegisters; 1287#elif __m68k__ 1288typedef Registers_M68K NativeUnwindRegisters; 1289#elif __mips_n64 || __mips_n32 1290typedef Registers_MIPS64 NativeUnwindRegisters; 1291#elif __mips__ 1292typedef Registers_MIPS NativeUnwindRegisters; 1293#elif __sh3__ 1294typedef Registers_SH3 NativeUnwindRegisters; 1295#elif __sparc64__ 1296typedef Registers_SPARC64 NativeUnwindRegisters; 1297#elif __sparc__ 1298typedef Registers_SPARC NativeUnwindRegisters; 1299#elif __alpha__ 1300typedef Registers_Alpha NativeUnwindRegisters; 1301#elif __hppa__ 1302typedef Registers_HPPA NativeUnwindRegisters; 1303#elif __or1k__ 1304typedef Registers_or1k NativeUnwindRegisters; 1305#endif 1306} // namespace _Unwind 1307 1308#endif // __REGISTERS_HPP__ 1309