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 <cassert> 16 #include <cstdint> 17 18 namespace _Unwind { 19 20 enum { 21 REGNO_X86_EAX = 0, 22 REGNO_X86_ECX = 1, 23 REGNO_X86_EDX = 2, 24 REGNO_X86_EBX = 3, 25 REGNO_X86_ESP = 4, 26 REGNO_X86_EBP = 5, 27 REGNO_X86_ESI = 6, 28 REGNO_X86_EDI = 7, 29 REGNO_X86_EIP = 8, 30 }; 31 32 class Registers_x86 { 33 public: 34 enum { 35 LAST_REGISTER = REGNO_X86_EIP, 36 LAST_RESTORE_REG = REGNO_X86_EIP, 37 RETURN_OFFSET = 0, 38 }; 39 40 __dso_hidden Registers_x86(); 41 42 static int dwarf2regno(int num) { return num; } 43 44 bool validRegister(int num) const { 45 return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI; 46 } 47 48 uint32_t getRegister(int num) const { 49 assert(validRegister(num)); 50 return reg[num]; 51 } 52 53 void setRegister(int num, uint32_t value) { 54 assert(validRegister(num)); 55 reg[num] = value; 56 } 57 58 uint32_t getIP() const { return reg[REGNO_X86_EIP]; } 59 60 void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; } 61 62 uint32_t getSP() const { return reg[REGNO_X86_ESP]; } 63 64 void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; } 65 66 bool validFloatVectorRegister(int num) const { return false; } 67 68 void copyFloatVectorRegister(int num, uint32_t addr) { 69 } 70 71 __dso_hidden void jumpto() const __dead; 72 73 private: 74 uint32_t reg[REGNO_X86_EIP + 1]; 75 }; 76 77 enum { 78 REGNO_X86_64_RAX = 0, 79 REGNO_X86_64_RDX = 1, 80 REGNO_X86_64_RCX = 2, 81 REGNO_X86_64_RBX = 3, 82 REGNO_X86_64_RSI = 4, 83 REGNO_X86_64_RDI = 5, 84 REGNO_X86_64_RBP = 6, 85 REGNO_X86_64_RSP = 7, 86 REGNO_X86_64_R8 = 8, 87 REGNO_X86_64_R9 = 9, 88 REGNO_X86_64_R10 = 10, 89 REGNO_X86_64_R11 = 11, 90 REGNO_X86_64_R12 = 12, 91 REGNO_X86_64_R13 = 13, 92 REGNO_X86_64_R14 = 14, 93 REGNO_X86_64_R15 = 15, 94 REGNO_X86_64_RIP = 16, 95 }; 96 97 class Registers_x86_64 { 98 public: 99 enum { 100 LAST_REGISTER = REGNO_X86_64_RIP, 101 LAST_RESTORE_REG = REGNO_X86_64_RIP, 102 RETURN_OFFSET = 0, 103 }; 104 105 __dso_hidden Registers_x86_64(); 106 107 static int dwarf2regno(int num) { return num; } 108 109 bool validRegister(int num) const { 110 return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15; 111 } 112 113 uint64_t getRegister(int num) const { 114 assert(validRegister(num)); 115 return reg[num]; 116 } 117 118 void setRegister(int num, uint64_t value) { 119 assert(validRegister(num)); 120 reg[num] = value; 121 } 122 123 uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; } 124 125 void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; } 126 127 uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; } 128 129 void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; } 130 131 bool validFloatVectorRegister(int num) const { return false; } 132 133 void copyFloatVectorRegister(int num, uint64_t addr) { 134 } 135 136 __dso_hidden void jumpto() const __dead; 137 138 private: 139 uint64_t reg[REGNO_X86_64_RIP + 1]; 140 }; 141 142 enum { 143 DWARF_PPC32_R0 = 0, 144 DWARF_PPC32_R31 = 31, 145 DWARF_PPC32_F0 = 32, 146 DWARF_PPC32_F31 = 63, 147 DWARF_PPC32_LR = 65, 148 DWARF_PPC32_CR = 70, 149 DWARF_PPC32_V0 = 77, 150 DWARF_PPC32_V31 = 108, 151 152 REGNO_PPC32_R0 = 0, 153 REGNO_PPC32_R1 = 1, 154 REGNO_PPC32_R31 = 31, 155 REGNO_PPC32_LR = 32, 156 REGNO_PPC32_CR = 33, 157 REGNO_PPC32_SRR0 = 34, 158 159 REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1, 160 REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31, 161 REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1, 162 REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31, 163 }; 164 165 class Registers_ppc32 { 166 public: 167 enum { 168 LAST_REGISTER = REGNO_PPC32_V31, 169 LAST_RESTORE_REG = REGNO_PPC32_V31, 170 RETURN_OFFSET = 0, 171 }; 172 173 __dso_hidden Registers_ppc32(); 174 175 static int dwarf2regno(int num) { 176 if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31) 177 return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0); 178 if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31) 179 return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0); 180 if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31) 181 return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0); 182 switch (num) { 183 case DWARF_PPC32_LR: 184 return REGNO_PPC32_LR; 185 case DWARF_PPC32_CR: 186 return REGNO_PPC32_CR; 187 default: 188 return LAST_REGISTER + 1; 189 } 190 } 191 192 bool validRegister(int num) const { 193 return num >= 0 && num <= LAST_RESTORE_REG; 194 } 195 196 uint64_t getRegister(int num) const { 197 assert(validRegister(num)); 198 return reg[num]; 199 } 200 201 void setRegister(int num, uint64_t value) { 202 assert(validRegister(num)); 203 reg[num] = value; 204 } 205 206 uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; } 207 208 void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; } 209 210 uint64_t getSP() const { return reg[REGNO_PPC32_R1]; } 211 212 void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; } 213 214 bool validFloatVectorRegister(int num) const { 215 return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) || 216 (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31); 217 } 218 219 void copyFloatVectorRegister(int num, uint64_t addr_) { 220 const void *addr = reinterpret_cast<const void *>(addr_); 221 if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) 222 memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0])); 223 else 224 memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0])); 225 } 226 227 __dso_hidden void jumpto() const __dead; 228 229 private: 230 struct vecreg_t { 231 uint64_t low, high; 232 }; 233 uint32_t reg[REGNO_PPC32_SRR0 + 1]; 234 uint32_t dummy; 235 uint64_t fpreg[32]; 236 vecreg_t vecreg[64]; 237 }; 238 239 enum { 240 DWARF_ARM32_R0 = 0, 241 DWARF_ARM32_R15 = 15, 242 DWARF_ARM32_SPSR = 128, 243 DWARF_ARM32_OLD_S0 = 64, 244 DWARF_ARM32_OLD_S31 = 91, 245 DWARF_ARM32_D0 = 256, 246 DWARF_ARM32_D31 = 287, 247 REGNO_ARM32_R0 = 0, 248 REGNO_ARM32_SP = 13, 249 REGNO_ARM32_R15 = 15, 250 REGNO_ARM32_SPSR = 16, 251 REGNO_ARM32_D0 = 17, 252 REGNO_ARM32_D15 = 32, 253 REGNO_ARM32_D31 = 48, 254 }; 255 256 class Registers_arm32 { 257 public: 258 enum { 259 LAST_REGISTER = REGNO_ARM32_D31, 260 LAST_RESTORE_REG = REGNO_ARM32_D31, 261 RETURN_OFFSET = 0, 262 }; 263 264 __dso_hidden Registers_arm32(); 265 266 static int dwarf2regno(int num) { 267 if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15) 268 return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0); 269 if (num == DWARF_ARM32_SPSR) 270 return REGNO_ARM32_SPSR; 271 if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31) 272 return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0); 273 if (num >= DWARF_ARM32_OLD_S0 && num <= DWARF_ARM32_OLD_S31) { 274 assert(num % 2 == 0); 275 return REGNO_ARM32_D0 + (num - DWARF_ARM32_OLD_S0) / 2; 276 } 277 return LAST_REGISTER + 1; 278 } 279 280 bool validRegister(int num) const { 281 return num >= 0 && num <= REGNO_ARM32_SPSR; 282 } 283 284 uint64_t getRegister(int num) const { 285 assert(validRegister(num)); 286 return reg[num]; 287 } 288 289 void setRegister(int num, uint64_t value) { 290 assert(validRegister(num)); 291 reg[num] = value; 292 } 293 294 uint64_t getIP() const { return reg[REGNO_ARM32_R15]; } 295 296 void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; } 297 298 uint64_t getSP() const { return reg[REGNO_ARM32_SP]; } 299 300 void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; } 301 302 bool validFloatVectorRegister(int num) const { 303 return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31); 304 } 305 306 void copyFloatVectorRegister(int num, uint64_t addr_) { 307 if (num <= REGNO_ARM32_D15) { 308 if ((flags & 1) == 0) { 309 lazyVFP1(); 310 flags |= 1; 311 } 312 } else { 313 if ((flags & 2) == 0) { 314 lazyVFP3(); 315 flags |= 2; 316 } 317 } 318 const void *addr = reinterpret_cast<const void *>(addr_); 319 memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0])); 320 } 321 322 __dso_hidden void lazyVFP1(); 323 __dso_hidden void lazyVFP3(); 324 __dso_hidden void jumpto() const __dead; 325 326 private: 327 uint32_t reg[REGNO_ARM32_SPSR + 1]; 328 uint32_t flags; 329 uint64_t fpreg[32]; 330 }; 331 332 enum { 333 DWARF_VAX_R0 = 0, 334 DWARF_VAX_R15 = 15, 335 DWARF_VAX_PSW = 16, 336 337 REGNO_VAX_R0 = 0, 338 REGNO_VAX_R14 = 14, 339 REGNO_VAX_R15 = 15, 340 REGNO_VAX_PSW = 16, 341 }; 342 343 class Registers_vax { 344 public: 345 enum { 346 LAST_REGISTER = REGNO_VAX_PSW, 347 LAST_RESTORE_REG = REGNO_VAX_PSW, 348 RETURN_OFFSET = 0, 349 }; 350 351 __dso_hidden Registers_vax(); 352 353 static int dwarf2regno(int num) { 354 if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15) 355 return REGNO_VAX_R0 + (num - DWARF_VAX_R0); 356 if (num == DWARF_VAX_PSW) 357 return REGNO_VAX_PSW; 358 return LAST_REGISTER + 1; 359 } 360 361 bool validRegister(int num) const { 362 return num >= 0 && num <= LAST_RESTORE_REG; 363 } 364 365 uint64_t getRegister(int num) const { 366 assert(validRegister(num)); 367 return reg[num]; 368 } 369 370 void setRegister(int num, uint64_t value) { 371 assert(validRegister(num)); 372 reg[num] = value; 373 } 374 375 uint64_t getIP() const { return reg[REGNO_VAX_R15]; } 376 377 void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; } 378 379 uint64_t getSP() const { return reg[REGNO_VAX_R14]; } 380 381 void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; } 382 383 bool validFloatVectorRegister(int num) const { 384 return false; 385 } 386 387 void copyFloatVectorRegister(int num, uint64_t addr_) { 388 } 389 390 __dso_hidden void jumpto() const __dead; 391 392 private: 393 uint32_t reg[REGNO_VAX_PSW + 1]; 394 }; 395 396 enum { 397 DWARF_M68K_A0 = 0, 398 DWARF_M68K_A7 = 7, 399 DWARF_M68K_D0 = 8, 400 DWARF_M68K_D7 = 15, 401 DWARF_M68K_FP0 = 16, 402 DWARF_M68K_FP7 = 23, 403 DWARF_M68K_PC = 24, 404 405 REGNO_M68K_A0 = 0, 406 REGNO_M68K_A7 = 7, 407 REGNO_M68K_D0 = 8, 408 REGNO_M68K_D7 = 15, 409 REGNO_M68K_PC = 16, 410 REGNO_M68K_FP0 = 17, 411 REGNO_M68K_FP7 = 24, 412 }; 413 414 class Registers_M68K { 415 public: 416 enum { 417 LAST_REGISTER = REGNO_M68K_FP7, 418 LAST_RESTORE_REG = REGNO_M68K_FP7, 419 RETURN_OFFSET = 0, 420 }; 421 422 __dso_hidden Registers_M68K(); 423 424 static int dwarf2regno(int num) { 425 if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7) 426 return REGNO_M68K_A0 + (num - DWARF_M68K_A0); 427 if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7) 428 return REGNO_M68K_D0 + (num - DWARF_M68K_D0); 429 if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7) 430 return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0); 431 if (num == DWARF_M68K_PC) 432 return REGNO_M68K_PC; 433 return LAST_REGISTER + 1; 434 } 435 436 bool validRegister(int num) const { 437 return num >= 0 && num <= REGNO_M68K_PC; 438 } 439 440 uint64_t getRegister(int num) const { 441 assert(validRegister(num)); 442 return reg[num]; 443 } 444 445 void setRegister(int num, uint64_t value) { 446 assert(validRegister(num)); 447 reg[num] = value; 448 } 449 450 uint64_t getIP() const { return reg[REGNO_M68K_PC]; } 451 452 void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; } 453 454 uint64_t getSP() const { return reg[REGNO_M68K_A7]; } 455 456 void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; } 457 458 bool validFloatVectorRegister(int num) const { 459 return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7; 460 } 461 462 void copyFloatVectorRegister(int num, uint64_t addr_) { 463 assert(validFloatVectorRegister(num)); 464 const void *addr = reinterpret_cast<const void *>(addr_); 465 memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0])); 466 } 467 468 __dso_hidden void jumpto() const __dead; 469 470 private: 471 typedef uint32_t fpreg_t[3]; 472 473 uint32_t reg[REGNO_M68K_PC + 1]; 474 uint32_t dummy; 475 fpreg_t fpreg[8]; 476 }; 477 478 enum { 479 DWARF_SH3_R0 = 0, 480 DWARF_SH3_R15 = 15, 481 DWARF_SH3_PC = 16, 482 DWARF_SH3_PR = 17, 483 484 REGNO_SH3_R0 = 0, 485 REGNO_SH3_R15 = 15, 486 REGNO_SH3_PC = 16, 487 REGNO_SH3_PR = 17, 488 }; 489 490 class Registers_SH3 { 491 public: 492 enum { 493 LAST_REGISTER = REGNO_SH3_PR, 494 LAST_RESTORE_REG = REGNO_SH3_PR, 495 RETURN_OFFSET = 0, 496 }; 497 498 __dso_hidden Registers_SH3(); 499 500 static int dwarf2regno(int num) { 501 if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15) 502 return REGNO_SH3_R0 + (num - DWARF_SH3_R0); 503 if (num == DWARF_SH3_PC) 504 return REGNO_SH3_PC; 505 if (num == DWARF_SH3_PR) 506 return REGNO_SH3_PR; 507 return LAST_REGISTER + 1; 508 } 509 510 bool validRegister(int num) const { 511 return num >= 0 && num <= REGNO_SH3_PR; 512 } 513 514 uint64_t getRegister(int num) const { 515 assert(validRegister(num)); 516 return reg[num]; 517 } 518 519 void setRegister(int num, uint64_t value) { 520 assert(validRegister(num)); 521 reg[num] = value; 522 } 523 524 uint64_t getIP() const { return reg[REGNO_SH3_PC]; } 525 526 void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; } 527 528 uint64_t getSP() const { return reg[REGNO_SH3_R15]; } 529 530 void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; } 531 532 bool validFloatVectorRegister(int num) const { return false; } 533 534 void copyFloatVectorRegister(int num, uint64_t addr_) {} 535 536 __dso_hidden void jumpto() const __dead; 537 538 private: 539 uint32_t reg[REGNO_SH3_PR + 1]; 540 }; 541 542 enum { 543 DWARF_SPARC64_R0 = 0, 544 DWARF_SPARC64_R31 = 31, 545 DWARF_SPARC64_PC = 32, 546 547 REGNO_SPARC64_R0 = 0, 548 REGNO_SPARC64_R14 = 14, 549 REGNO_SPARC64_R15 = 15, 550 REGNO_SPARC64_R31 = 31, 551 REGNO_SPARC64_PC = 32, 552 }; 553 554 class Registers_SPARC64 { 555 public: 556 enum { 557 LAST_REGISTER = REGNO_SPARC64_PC, 558 LAST_RESTORE_REG = REGNO_SPARC64_PC, 559 RETURN_OFFSET = 8, 560 }; 561 typedef uint64_t reg_t; 562 563 __dso_hidden Registers_SPARC64(); 564 565 static int dwarf2regno(int num) { 566 if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31) 567 return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0); 568 if (num == DWARF_SPARC64_PC) 569 return REGNO_SPARC64_PC; 570 return LAST_REGISTER + 1; 571 } 572 573 bool validRegister(int num) const { 574 return num >= 0 && num <= REGNO_SPARC64_PC; 575 } 576 577 uint64_t getRegister(int num) const { 578 assert(validRegister(num)); 579 return reg[num]; 580 } 581 582 void setRegister(int num, uint64_t value) { 583 assert(validRegister(num)); 584 reg[num] = value; 585 } 586 587 uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; } 588 589 void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; } 590 591 uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; } 592 593 void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; } 594 595 bool validFloatVectorRegister(int num) const { return false; } 596 597 void copyFloatVectorRegister(int num, uint64_t addr_) {} 598 599 __dso_hidden void jumpto() const __dead; 600 601 private: 602 uint64_t reg[REGNO_SPARC64_PC + 1]; 603 }; 604 605 enum { 606 DWARF_SPARC_R0 = 0, 607 DWARF_SPARC_R31 = 31, 608 DWARF_SPARC_PC = 32, 609 610 REGNO_SPARC_R0 = 0, 611 REGNO_SPARC_R14 = 14, 612 REGNO_SPARC_R15 = 15, 613 REGNO_SPARC_R31 = 31, 614 REGNO_SPARC_PC = 32, 615 }; 616 617 class Registers_SPARC { 618 public: 619 enum { 620 LAST_REGISTER = REGNO_SPARC_PC, 621 LAST_RESTORE_REG = REGNO_SPARC_PC, 622 RETURN_OFFSET = 8, 623 }; 624 typedef uint32_t reg_t; 625 626 __dso_hidden Registers_SPARC(); 627 628 static int dwarf2regno(int num) { 629 if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31) 630 return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0); 631 if (num == DWARF_SPARC_PC) 632 return REGNO_SPARC_PC; 633 return LAST_REGISTER + 1; 634 } 635 636 bool validRegister(int num) const { 637 return num >= 0 && num <= REGNO_SPARC_PC; 638 } 639 640 uint64_t getRegister(int num) const { 641 assert(validRegister(num)); 642 return reg[num]; 643 } 644 645 void setRegister(int num, uint64_t value) { 646 assert(validRegister(num)); 647 reg[num] = value; 648 } 649 650 uint64_t getIP() const { return reg[REGNO_SPARC_PC]; } 651 652 void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; } 653 654 uint64_t getSP() const { return reg[REGNO_SPARC_R14]; } 655 656 void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; } 657 658 bool validFloatVectorRegister(int num) const { return false; } 659 660 void copyFloatVectorRegister(int num, uint64_t addr_) {} 661 662 __dso_hidden void jumpto() const __dead; 663 664 private: 665 uint32_t reg[REGNO_SPARC_PC + 1]; 666 }; 667 668 enum { 669 DWARF_ALPHA_R0 = 0, 670 DWARF_ALPHA_R30 = 30, 671 DWARF_ALPHA_F0 = 32, 672 DWARF_ALPHA_F30 = 62, 673 674 REGNO_ALPHA_R0 = 0, 675 REGNO_ALPHA_R26 = 26, 676 REGNO_ALPHA_R30 = 30, 677 REGNO_ALPHA_PC = 31, 678 REGNO_ALPHA_F0 = 32, 679 REGNO_ALPHA_F30 = 62, 680 }; 681 682 class Registers_Alpha { 683 public: 684 enum { 685 LAST_REGISTER = REGNO_ALPHA_F30, 686 LAST_RESTORE_REG = REGNO_ALPHA_F30, 687 RETURN_OFFSET = 0, 688 }; 689 typedef uint32_t reg_t; 690 691 __dso_hidden Registers_Alpha(); 692 693 static int dwarf2regno(int num) { return num; } 694 695 bool validRegister(int num) const { 696 return num >= 0 && num <= REGNO_ALPHA_PC; 697 } 698 699 uint64_t getRegister(int num) const { 700 assert(validRegister(num)); 701 return reg[num]; 702 } 703 704 void setRegister(int num, uint64_t value) { 705 assert(validRegister(num)); 706 reg[num] = value; 707 } 708 709 uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; } 710 711 void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; } 712 713 uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; } 714 715 void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; } 716 717 bool validFloatVectorRegister(int num) const { 718 return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30; 719 } 720 721 void copyFloatVectorRegister(int num, uint64_t addr_) { 722 assert(validFloatVectorRegister(num)); 723 const void *addr = reinterpret_cast<const void *>(addr_); 724 memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0])); 725 } 726 727 __dso_hidden void jumpto() const __dead; 728 729 private: 730 uint64_t reg[REGNO_ALPHA_PC + 1]; 731 uint64_t fpreg[31]; 732 }; 733 734 enum { 735 DWARF_HPPA_R1 = 1, 736 DWARF_HPPA_R31 = 31, 737 DWARF_HPPA_FR4L = 32, 738 DWARF_HPPA_FR31H = 87, 739 740 REGNO_HPPA_PC = 0, 741 REGNO_HPPA_R1 = 1, 742 REGNO_HPPA_R2 = 2, 743 REGNO_HPPA_R30 = 30, 744 REGNO_HPPA_R31 = 31, 745 REGNO_HPPA_FR4L = 32, 746 REGNO_HPPA_FR31H = 87, 747 }; 748 749 class Registers_HPPA { 750 public: 751 enum { 752 LAST_REGISTER = REGNO_HPPA_FR31H, 753 LAST_RESTORE_REG = REGNO_HPPA_FR31H, 754 RETURN_OFFSET = -3, // strictly speaking, this is a mask 755 }; 756 757 __dso_hidden Registers_HPPA(); 758 759 static int dwarf2regno(int num) { 760 if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31) 761 return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1); 762 if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H) 763 return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H); 764 return LAST_REGISTER + 1; 765 } 766 767 bool validRegister(int num) const { 768 return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31; 769 } 770 771 uint64_t getRegister(int num) const { 772 assert(validRegister(num)); 773 return reg[num]; 774 } 775 776 void setRegister(int num, uint64_t value) { 777 assert(validRegister(num)); 778 reg[num] = value; 779 } 780 781 uint64_t getIP() const { return reg[REGNO_HPPA_PC]; } 782 783 void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; } 784 785 uint64_t getSP() const { return reg[REGNO_HPPA_R30]; } 786 787 void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; } 788 789 bool validFloatVectorRegister(int num) const { 790 return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H; 791 } 792 793 void copyFloatVectorRegister(int num, uint64_t addr_) { 794 assert(validFloatVectorRegister(num)); 795 const void *addr = reinterpret_cast<const void *>(addr_); 796 memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0])); 797 } 798 799 __dso_hidden void jumpto() const __dead; 800 801 private: 802 uint32_t reg[REGNO_HPPA_R31 + 1]; 803 uint32_t fpreg[56]; 804 }; 805 806 enum { 807 DWARF_MIPS_R1 = 0, 808 DWARF_MIPS_R31 = 31, 809 DWARF_MIPS_F0 = 32, 810 DWARF_MIPS_F31 = 63, 811 812 REGNO_MIPS_PC = 0, 813 REGNO_MIPS_R1 = 0, 814 REGNO_MIPS_R29 = 29, 815 REGNO_MIPS_R31 = 31, 816 REGNO_MIPS_F0 = 33, 817 REGNO_MIPS_F31 = 64 818 }; 819 820 class Registers_MIPS { 821 public: 822 enum { 823 LAST_REGISTER = REGNO_MIPS_F31, 824 LAST_RESTORE_REG = REGNO_MIPS_F31, 825 RETURN_OFFSET = 0, 826 }; 827 828 __dso_hidden Registers_MIPS(); 829 830 static int dwarf2regno(int num) { 831 if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31) 832 return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1); 833 if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31) 834 return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0); 835 return LAST_REGISTER + 1; 836 } 837 838 bool validRegister(int num) const { 839 return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31; 840 } 841 842 uint64_t getRegister(int num) const { 843 assert(validRegister(num)); 844 return reg[num]; 845 } 846 847 void setRegister(int num, uint64_t value) { 848 assert(validRegister(num)); 849 reg[num] = value; 850 } 851 852 uint64_t getIP() const { return reg[REGNO_MIPS_PC]; } 853 854 void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; } 855 856 uint64_t getSP() const { return reg[REGNO_MIPS_R29]; } 857 858 void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; } 859 860 bool validFloatVectorRegister(int num) const { 861 return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31; 862 } 863 864 void copyFloatVectorRegister(int num, uint64_t addr_) { 865 assert(validFloatVectorRegister(num)); 866 const void *addr = reinterpret_cast<const void *>(addr_); 867 memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0])); 868 } 869 870 __dso_hidden void jumpto() const __dead; 871 872 private: 873 uint32_t reg[REGNO_MIPS_R31 + 1]; 874 uint64_t fpreg[32]; 875 }; 876 877 enum { 878 DWARF_MIPS64_R1 = 0, 879 DWARF_MIPS64_R31 = 31, 880 DWARF_MIPS64_F0 = 32, 881 DWARF_MIPS64_F31 = 63, 882 883 REGNO_MIPS64_PC = 0, 884 REGNO_MIPS64_R1 = 0, 885 REGNO_MIPS64_R29 = 29, 886 REGNO_MIPS64_R31 = 31, 887 REGNO_MIPS64_F0 = 33, 888 REGNO_MIPS64_F31 = 64 889 }; 890 891 class Registers_MIPS64 { 892 public: 893 enum { 894 LAST_REGISTER = REGNO_MIPS64_F31, 895 LAST_RESTORE_REG = REGNO_MIPS64_F31, 896 RETURN_OFFSET = 0, 897 }; 898 899 __dso_hidden Registers_MIPS64(); 900 901 static int dwarf2regno(int num) { 902 if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31) 903 return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1); 904 if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31) 905 return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0); 906 return LAST_REGISTER + 1; 907 } 908 909 bool validRegister(int num) const { 910 return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31; 911 } 912 913 uint64_t getRegister(int num) const { 914 assert(validRegister(num)); 915 return reg[num]; 916 } 917 918 void setRegister(int num, uint64_t value) { 919 assert(validRegister(num)); 920 reg[num] = value; 921 } 922 923 uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; } 924 925 void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; } 926 927 uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; } 928 929 void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; } 930 931 bool validFloatVectorRegister(int num) const { 932 return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31; 933 } 934 935 void copyFloatVectorRegister(int num, uint64_t addr_) { 936 assert(validFloatVectorRegister(num)); 937 const void *addr = reinterpret_cast<const void *>(addr_); 938 memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0])); 939 } 940 941 __dso_hidden void jumpto() const __dead; 942 943 private: 944 uint64_t reg[REGNO_MIPS64_R31 + 1]; 945 uint64_t fpreg[32]; 946 }; 947 948 #if __i386__ 949 typedef Registers_x86 NativeUnwindRegisters; 950 #elif __x86_64__ 951 typedef Registers_x86_64 NativeUnwindRegisters; 952 #elif __powerpc__ 953 typedef Registers_ppc32 NativeUnwindRegisters; 954 #elif __arm__ 955 typedef Registers_arm32 NativeUnwindRegisters; 956 #elif __vax__ 957 typedef Registers_vax NativeUnwindRegisters; 958 #elif __m68k__ 959 typedef Registers_M68K NativeUnwindRegisters; 960 #elif __mips_n64 || __mips_n32 961 typedef Registers_MIPS64 NativeUnwindRegisters; 962 #elif __mips__ 963 typedef Registers_MIPS NativeUnwindRegisters; 964 #elif __sh3__ 965 typedef Registers_SH3 NativeUnwindRegisters; 966 #elif __sparc64__ 967 typedef Registers_SPARC64 NativeUnwindRegisters; 968 #elif __sparc__ 969 typedef Registers_SPARC NativeUnwindRegisters; 970 #elif __alpha__ 971 typedef Registers_Alpha NativeUnwindRegisters; 972 #elif __hppa__ 973 typedef Registers_HPPA NativeUnwindRegisters; 974 #endif 975 } // namespace _Unwind 976 977 #endif // __REGISTERS_HPP__ 978