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 RETURN_MASK = 0, 39 }; 40 41 __dso_hidden Registers_x86(); 42 dwarf2regno(int num)43 static int dwarf2regno(int num) { return num; } 44 validRegister(int num) const45 bool validRegister(int num) const { 46 return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI; 47 } 48 getRegister(int num) const49 uint32_t getRegister(int num) const { 50 assert(validRegister(num)); 51 return reg[num]; 52 } 53 setRegister(int num,uint32_t value)54 void setRegister(int num, uint32_t value) { 55 assert(validRegister(num)); 56 reg[num] = value; 57 } 58 getIP() const59 uint32_t getIP() const { return reg[REGNO_X86_EIP]; } 60 setIP(uint32_t value)61 void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; } 62 getSP() const63 uint32_t getSP() const { return reg[REGNO_X86_ESP]; } 64 setSP(uint32_t value)65 void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; } 66 validFloatVectorRegister(int num) const67 bool validFloatVectorRegister(int num) const { return false; } 68 copyFloatVectorRegister(int num,uint32_t addr)69 void copyFloatVectorRegister(int num, uint32_t addr) { 70 } 71 72 __dso_hidden void jumpto() const __dead; 73 74 private: 75 uint32_t reg[REGNO_X86_EIP + 1]; 76 }; 77 78 enum { 79 REGNO_X86_64_RAX = 0, 80 REGNO_X86_64_RDX = 1, 81 REGNO_X86_64_RCX = 2, 82 REGNO_X86_64_RBX = 3, 83 REGNO_X86_64_RSI = 4, 84 REGNO_X86_64_RDI = 5, 85 REGNO_X86_64_RBP = 6, 86 REGNO_X86_64_RSP = 7, 87 REGNO_X86_64_R8 = 8, 88 REGNO_X86_64_R9 = 9, 89 REGNO_X86_64_R10 = 10, 90 REGNO_X86_64_R11 = 11, 91 REGNO_X86_64_R12 = 12, 92 REGNO_X86_64_R13 = 13, 93 REGNO_X86_64_R14 = 14, 94 REGNO_X86_64_R15 = 15, 95 REGNO_X86_64_RIP = 16, 96 }; 97 98 class Registers_x86_64 { 99 public: 100 enum { 101 LAST_REGISTER = REGNO_X86_64_RIP, 102 LAST_RESTORE_REG = REGNO_X86_64_RIP, 103 RETURN_OFFSET = 0, 104 RETURN_MASK = 0, 105 }; 106 107 __dso_hidden Registers_x86_64(); 108 dwarf2regno(int num)109 static int dwarf2regno(int num) { return num; } 110 validRegister(int num) const111 bool validRegister(int num) const { 112 return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15; 113 } 114 getRegister(int num) const115 uint64_t getRegister(int num) const { 116 assert(validRegister(num)); 117 return reg[num]; 118 } 119 setRegister(int num,uint64_t value)120 void setRegister(int num, uint64_t value) { 121 assert(validRegister(num)); 122 reg[num] = value; 123 } 124 getIP() const125 uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; } 126 setIP(uint64_t value)127 void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; } 128 getSP() const129 uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; } 130 setSP(uint64_t value)131 void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; } 132 validFloatVectorRegister(int num) const133 bool validFloatVectorRegister(int num) const { return false; } 134 copyFloatVectorRegister(int num,uint64_t addr)135 void copyFloatVectorRegister(int num, uint64_t addr) { 136 } 137 138 __dso_hidden void jumpto() const __dead; 139 140 private: 141 uint64_t reg[REGNO_X86_64_RIP + 1]; 142 }; 143 144 enum { 145 DWARF_PPC32_R0 = 0, 146 DWARF_PPC32_R31 = 31, 147 DWARF_PPC32_F0 = 32, 148 DWARF_PPC32_F31 = 63, 149 DWARF_PPC32_LR = 65, 150 DWARF_PPC32_CR = 70, 151 DWARF_PPC32_V0 = 77, 152 DWARF_PPC32_V31 = 108, 153 154 REGNO_PPC32_R0 = 0, 155 REGNO_PPC32_R1 = 1, 156 REGNO_PPC32_R31 = 31, 157 REGNO_PPC32_LR = 32, 158 REGNO_PPC32_CR = 33, 159 REGNO_PPC32_SRR0 = 34, 160 161 REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1, 162 REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31, 163 REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1, 164 REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31, 165 }; 166 167 class Registers_ppc32 { 168 public: 169 enum { 170 LAST_REGISTER = REGNO_PPC32_V31, 171 LAST_RESTORE_REG = REGNO_PPC32_V31, 172 RETURN_OFFSET = 0, 173 RETURN_MASK = 0, 174 }; 175 176 __dso_hidden Registers_ppc32(); 177 dwarf2regno(int num)178 static int dwarf2regno(int num) { 179 if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31) 180 return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0); 181 if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31) 182 return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0); 183 if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31) 184 return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0); 185 switch (num) { 186 case DWARF_PPC32_LR: 187 return REGNO_PPC32_LR; 188 case DWARF_PPC32_CR: 189 return REGNO_PPC32_CR; 190 default: 191 return LAST_REGISTER + 1; 192 } 193 } 194 validRegister(int num) const195 bool validRegister(int num) const { 196 return num >= 0 && num <= LAST_RESTORE_REG; 197 } 198 getRegister(int num) const199 uint64_t getRegister(int num) const { 200 assert(validRegister(num)); 201 return reg[num]; 202 } 203 setRegister(int num,uint64_t value)204 void setRegister(int num, uint64_t value) { 205 assert(validRegister(num)); 206 reg[num] = value; 207 } 208 getIP() const209 uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; } 210 setIP(uint64_t value)211 void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; } 212 getSP() const213 uint64_t getSP() const { return reg[REGNO_PPC32_R1]; } 214 setSP(uint64_t value)215 void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; } 216 validFloatVectorRegister(int num) const217 bool validFloatVectorRegister(int num) const { 218 return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) || 219 (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31); 220 } 221 copyFloatVectorRegister(int num,uint64_t addr_)222 void copyFloatVectorRegister(int num, uint64_t addr_) { 223 const void *addr = reinterpret_cast<const void *>(addr_); 224 if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) 225 memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0])); 226 else 227 memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0])); 228 } 229 230 __dso_hidden void jumpto() const __dead; 231 232 private: 233 struct vecreg_t { 234 uint64_t low, high; 235 }; 236 uint32_t reg[REGNO_PPC32_SRR0 + 1]; 237 uint32_t dummy; 238 uint64_t fpreg[32]; 239 vecreg_t vecreg[64]; 240 }; 241 242 enum { 243 DWARF_AARCH64_X0 = 0, 244 DWARF_AARCH64_X30 = 30, 245 DWARF_AARCH64_SP = 31, 246 DWARF_AARCH64_ELR_MODE = 33, 247 DWARF_AARCH64_V0 = 64, 248 DWARF_AARCH64_V31 = 95, 249 250 REGNO_AARCH64_X0 = 0, 251 REGNO_AARCH64_X30 = 30, 252 REGNO_AARCH64_SP = 31, 253 REGNO_AARCH64_ELR_MODE = 32, 254 REGNO_AARCH64_V0 = 33, 255 REGNO_AARCH64_V31 = 64, 256 }; 257 258 class Registers_aarch64 { 259 public: 260 enum { 261 LAST_RESTORE_REG = REGNO_AARCH64_V31, 262 LAST_REGISTER = REGNO_AARCH64_V31, 263 RETURN_OFFSET = 0, 264 RETURN_MASK = 0, 265 }; 266 267 __dso_hidden Registers_aarch64(); 268 dwarf2regno(int num)269 static int dwarf2regno(int num) { 270 if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30) 271 return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0); 272 if (num == DWARF_AARCH64_SP) 273 return REGNO_AARCH64_SP; 274 if (num == DWARF_AARCH64_ELR_MODE) 275 return REGNO_AARCH64_ELR_MODE; 276 if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31) 277 return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0); 278 return LAST_REGISTER + 1; 279 } 280 validRegister(int num) const281 bool validRegister(int num) const { 282 return num >= 0 && num <= LAST_RESTORE_REG; 283 } 284 getRegister(int num) const285 uint64_t getRegister(int num) const { 286 assert(validRegister(num)); 287 return reg[num]; 288 } 289 setRegister(int num,uint64_t value)290 void setRegister(int num, uint64_t value) { 291 assert(validRegister(num)); 292 reg[num] = value; 293 } 294 getIP() const295 uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; } 296 setIP(uint64_t value)297 void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; } 298 getSP() const299 uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; } 300 setSP(uint64_t value)301 void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; } 302 validFloatVectorRegister(int num) const303 bool validFloatVectorRegister(int num) const { 304 return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31); 305 } 306 copyFloatVectorRegister(int num,uint64_t addr_)307 void copyFloatVectorRegister(int num, uint64_t addr_) { 308 const void *addr = reinterpret_cast<const void *>(addr_); 309 memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, sizeof(vecreg[0])); 310 } 311 312 __dso_hidden void jumpto() const __dead; 313 314 private: 315 struct vecreg_t { 316 uint64_t low, high; 317 }; 318 uint64_t reg[REGNO_AARCH64_ELR_MODE + 1]; 319 vecreg_t vecreg[32]; 320 }; 321 322 enum { 323 DWARF_ARM32_R0 = 0, 324 DWARF_ARM32_R15 = 15, 325 DWARF_ARM32_SPSR = 128, 326 DWARF_ARM32_OLD_S0 = 64, 327 DWARF_ARM32_OLD_S31 = 91, 328 DWARF_ARM32_D0 = 256, 329 DWARF_ARM32_D31 = 287, 330 REGNO_ARM32_R0 = 0, 331 REGNO_ARM32_SP = 13, 332 REGNO_ARM32_R15 = 15, 333 REGNO_ARM32_SPSR = 16, 334 REGNO_ARM32_D0 = 17, 335 REGNO_ARM32_D15 = 32, 336 REGNO_ARM32_D31 = 48, 337 }; 338 339 class Registers_arm32 { 340 public: 341 enum { 342 LAST_REGISTER = REGNO_ARM32_D31, 343 LAST_RESTORE_REG = REGNO_ARM32_D31, 344 RETURN_OFFSET = 0, 345 RETURN_MASK = 0, 346 }; 347 348 __dso_hidden Registers_arm32(); 349 dwarf2regno(int num)350 static int dwarf2regno(int num) { 351 if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15) 352 return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0); 353 if (num == DWARF_ARM32_SPSR) 354 return REGNO_ARM32_SPSR; 355 if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31) 356 return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0); 357 if (num >= DWARF_ARM32_OLD_S0 && num <= DWARF_ARM32_OLD_S31) { 358 assert(num % 2 == 0); 359 return REGNO_ARM32_D0 + (num - DWARF_ARM32_OLD_S0) / 2; 360 } 361 return LAST_REGISTER + 1; 362 } 363 validRegister(int num) const364 bool validRegister(int num) const { 365 return num >= 0 && num <= REGNO_ARM32_SPSR; 366 } 367 getRegister(int num) const368 uint64_t getRegister(int num) const { 369 assert(validRegister(num)); 370 return reg[num]; 371 } 372 setRegister(int num,uint64_t value)373 void setRegister(int num, uint64_t value) { 374 assert(validRegister(num)); 375 reg[num] = value; 376 } 377 getIP() const378 uint64_t getIP() const { return reg[REGNO_ARM32_R15]; } 379 setIP(uint64_t value)380 void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; } 381 getSP() const382 uint64_t getSP() const { return reg[REGNO_ARM32_SP]; } 383 setSP(uint64_t value)384 void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; } 385 validFloatVectorRegister(int num) const386 bool validFloatVectorRegister(int num) const { 387 return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31); 388 } 389 copyFloatVectorRegister(int num,uint64_t addr_)390 void copyFloatVectorRegister(int num, uint64_t addr_) { 391 if (num <= REGNO_ARM32_D15) { 392 if ((flags & 1) == 0) { 393 lazyVFP1(); 394 flags |= 1; 395 } 396 } else { 397 if ((flags & 2) == 0) { 398 lazyVFP3(); 399 flags |= 2; 400 } 401 } 402 const void *addr = reinterpret_cast<const void *>(addr_); 403 memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0])); 404 } 405 406 __dso_hidden void lazyVFP1(); 407 __dso_hidden void lazyVFP3(); 408 __dso_hidden void jumpto() const __dead; 409 410 private: 411 uint32_t reg[REGNO_ARM32_SPSR + 1]; 412 uint32_t flags; 413 uint64_t fpreg[32]; 414 }; 415 416 enum { 417 DWARF_VAX_R0 = 0, 418 DWARF_VAX_R15 = 15, 419 DWARF_VAX_PSW = 16, 420 421 REGNO_VAX_R0 = 0, 422 REGNO_VAX_R14 = 14, 423 REGNO_VAX_R15 = 15, 424 REGNO_VAX_PSW = 16, 425 }; 426 427 class Registers_vax { 428 public: 429 enum { 430 LAST_REGISTER = REGNO_VAX_PSW, 431 LAST_RESTORE_REG = REGNO_VAX_PSW, 432 RETURN_OFFSET = 0, 433 RETURN_MASK = 0, 434 }; 435 436 __dso_hidden Registers_vax(); 437 dwarf2regno(int num)438 static int dwarf2regno(int num) { 439 if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15) 440 return REGNO_VAX_R0 + (num - DWARF_VAX_R0); 441 if (num == DWARF_VAX_PSW) 442 return REGNO_VAX_PSW; 443 return LAST_REGISTER + 1; 444 } 445 validRegister(int num) const446 bool validRegister(int num) const { 447 return num >= 0 && num <= LAST_RESTORE_REG; 448 } 449 getRegister(int num) const450 uint64_t getRegister(int num) const { 451 assert(validRegister(num)); 452 return reg[num]; 453 } 454 setRegister(int num,uint64_t value)455 void setRegister(int num, uint64_t value) { 456 assert(validRegister(num)); 457 reg[num] = value; 458 } 459 getIP() const460 uint64_t getIP() const { return reg[REGNO_VAX_R15]; } 461 setIP(uint64_t value)462 void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; } 463 getSP() const464 uint64_t getSP() const { return reg[REGNO_VAX_R14]; } 465 setSP(uint64_t value)466 void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; } 467 validFloatVectorRegister(int num) const468 bool validFloatVectorRegister(int num) const { 469 return false; 470 } 471 copyFloatVectorRegister(int num,uint64_t addr_)472 void copyFloatVectorRegister(int num, uint64_t addr_) { 473 } 474 475 __dso_hidden void jumpto() const __dead; 476 477 private: 478 uint32_t reg[REGNO_VAX_PSW + 1]; 479 }; 480 481 enum { 482 DWARF_M68K_A0 = 0, 483 DWARF_M68K_A7 = 7, 484 DWARF_M68K_D0 = 8, 485 DWARF_M68K_D7 = 15, 486 DWARF_M68K_FP0 = 16, 487 DWARF_M68K_FP7 = 23, 488 DWARF_M68K_PC = 24, 489 490 REGNO_M68K_A0 = 0, 491 REGNO_M68K_A7 = 7, 492 REGNO_M68K_D0 = 8, 493 REGNO_M68K_D7 = 15, 494 REGNO_M68K_PC = 16, 495 REGNO_M68K_FP0 = 17, 496 REGNO_M68K_FP7 = 24, 497 }; 498 499 class Registers_M68K { 500 public: 501 enum { 502 LAST_REGISTER = REGNO_M68K_FP7, 503 LAST_RESTORE_REG = REGNO_M68K_FP7, 504 RETURN_OFFSET = 0, 505 RETURN_MASK = 0, 506 }; 507 508 __dso_hidden Registers_M68K(); 509 dwarf2regno(int num)510 static int dwarf2regno(int num) { 511 if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7) 512 return REGNO_M68K_A0 + (num - DWARF_M68K_A0); 513 if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7) 514 return REGNO_M68K_D0 + (num - DWARF_M68K_D0); 515 if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7) 516 return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0); 517 if (num == DWARF_M68K_PC) 518 return REGNO_M68K_PC; 519 return LAST_REGISTER + 1; 520 } 521 validRegister(int num) const522 bool validRegister(int num) const { 523 return num >= 0 && num <= REGNO_M68K_PC; 524 } 525 getRegister(int num) const526 uint64_t getRegister(int num) const { 527 assert(validRegister(num)); 528 return reg[num]; 529 } 530 setRegister(int num,uint64_t value)531 void setRegister(int num, uint64_t value) { 532 assert(validRegister(num)); 533 reg[num] = value; 534 } 535 getIP() const536 uint64_t getIP() const { return reg[REGNO_M68K_PC]; } 537 setIP(uint64_t value)538 void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; } 539 getSP() const540 uint64_t getSP() const { return reg[REGNO_M68K_A7]; } 541 setSP(uint64_t value)542 void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; } 543 validFloatVectorRegister(int num) const544 bool validFloatVectorRegister(int num) const { 545 return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7; 546 } 547 copyFloatVectorRegister(int num,uint64_t addr_)548 void copyFloatVectorRegister(int num, uint64_t addr_) { 549 assert(validFloatVectorRegister(num)); 550 const void *addr = reinterpret_cast<const void *>(addr_); 551 memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0])); 552 } 553 554 __dso_hidden void jumpto() const __dead; 555 556 private: 557 typedef uint32_t fpreg_t[3]; 558 559 uint32_t reg[REGNO_M68K_PC + 1]; 560 uint32_t dummy; 561 fpreg_t fpreg[8]; 562 }; 563 564 enum { 565 DWARF_SH3_R0 = 0, 566 DWARF_SH3_R15 = 15, 567 DWARF_SH3_PC = 16, 568 DWARF_SH3_PR = 17, 569 570 REGNO_SH3_R0 = 0, 571 REGNO_SH3_R15 = 15, 572 REGNO_SH3_PC = 16, 573 REGNO_SH3_PR = 17, 574 }; 575 576 class Registers_SH3 { 577 public: 578 enum { 579 LAST_REGISTER = REGNO_SH3_PR, 580 LAST_RESTORE_REG = REGNO_SH3_PR, 581 RETURN_OFFSET = 0, 582 RETURN_MASK = 0, 583 }; 584 585 __dso_hidden Registers_SH3(); 586 dwarf2regno(int num)587 static int dwarf2regno(int num) { 588 if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15) 589 return REGNO_SH3_R0 + (num - DWARF_SH3_R0); 590 if (num == DWARF_SH3_PC) 591 return REGNO_SH3_PC; 592 if (num == DWARF_SH3_PR) 593 return REGNO_SH3_PR; 594 return LAST_REGISTER + 1; 595 } 596 validRegister(int num) const597 bool validRegister(int num) const { 598 return num >= 0 && num <= REGNO_SH3_PR; 599 } 600 getRegister(int num) const601 uint64_t getRegister(int num) const { 602 assert(validRegister(num)); 603 return reg[num]; 604 } 605 setRegister(int num,uint64_t value)606 void setRegister(int num, uint64_t value) { 607 assert(validRegister(num)); 608 reg[num] = value; 609 } 610 getIP() const611 uint64_t getIP() const { return reg[REGNO_SH3_PC]; } 612 setIP(uint64_t value)613 void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; } 614 getSP() const615 uint64_t getSP() const { return reg[REGNO_SH3_R15]; } 616 setSP(uint64_t value)617 void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; } 618 validFloatVectorRegister(int num) const619 bool validFloatVectorRegister(int num) const { return false; } 620 copyFloatVectorRegister(int num,uint64_t addr_)621 void copyFloatVectorRegister(int num, uint64_t addr_) {} 622 623 __dso_hidden void jumpto() const __dead; 624 625 private: 626 uint32_t reg[REGNO_SH3_PR + 1]; 627 }; 628 629 enum { 630 DWARF_SPARC64_R0 = 0, 631 DWARF_SPARC64_R31 = 31, 632 DWARF_SPARC64_PC = 32, 633 634 REGNO_SPARC64_R0 = 0, 635 REGNO_SPARC64_R14 = 14, 636 REGNO_SPARC64_R15 = 15, 637 REGNO_SPARC64_R31 = 31, 638 REGNO_SPARC64_PC = 32, 639 }; 640 641 class Registers_SPARC64 { 642 public: 643 enum { 644 LAST_REGISTER = REGNO_SPARC64_PC, 645 LAST_RESTORE_REG = REGNO_SPARC64_PC, 646 RETURN_OFFSET = 8, 647 RETURN_MASK = 0, 648 }; 649 typedef uint64_t reg_t; 650 651 __dso_hidden Registers_SPARC64(); 652 dwarf2regno(int num)653 static int dwarf2regno(int num) { 654 if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31) 655 return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0); 656 if (num == DWARF_SPARC64_PC) 657 return REGNO_SPARC64_PC; 658 return LAST_REGISTER + 1; 659 } 660 validRegister(int num) const661 bool validRegister(int num) const { 662 return num >= 0 && num <= REGNO_SPARC64_PC; 663 } 664 getRegister(int num) const665 uint64_t getRegister(int num) const { 666 assert(validRegister(num)); 667 return reg[num]; 668 } 669 setRegister(int num,uint64_t value)670 void setRegister(int num, uint64_t value) { 671 assert(validRegister(num)); 672 reg[num] = value; 673 } 674 getIP() const675 uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; } 676 setIP(uint64_t value)677 void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; } 678 getSP() const679 uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; } 680 setSP(uint64_t value)681 void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; } 682 validFloatVectorRegister(int num) const683 bool validFloatVectorRegister(int num) const { return false; } 684 copyFloatVectorRegister(int num,uint64_t addr_)685 void copyFloatVectorRegister(int num, uint64_t addr_) {} 686 687 __dso_hidden void jumpto() const __dead; 688 689 private: 690 uint64_t reg[REGNO_SPARC64_PC + 1]; 691 }; 692 693 enum { 694 DWARF_SPARC_R0 = 0, 695 DWARF_SPARC_R31 = 31, 696 DWARF_SPARC_PC = 32, 697 698 REGNO_SPARC_R0 = 0, 699 REGNO_SPARC_R14 = 14, 700 REGNO_SPARC_R15 = 15, 701 REGNO_SPARC_R31 = 31, 702 REGNO_SPARC_PC = 32, 703 }; 704 705 class Registers_SPARC { 706 public: 707 enum { 708 LAST_REGISTER = REGNO_SPARC_PC, 709 LAST_RESTORE_REG = REGNO_SPARC_PC, 710 RETURN_OFFSET = 8, 711 RETURN_MASK = 0, 712 }; 713 typedef uint32_t reg_t; 714 715 __dso_hidden Registers_SPARC(); 716 dwarf2regno(int num)717 static int dwarf2regno(int num) { 718 if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31) 719 return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0); 720 if (num == DWARF_SPARC_PC) 721 return REGNO_SPARC_PC; 722 return LAST_REGISTER + 1; 723 } 724 validRegister(int num) const725 bool validRegister(int num) const { 726 return num >= 0 && num <= REGNO_SPARC_PC; 727 } 728 getRegister(int num) const729 uint64_t getRegister(int num) const { 730 assert(validRegister(num)); 731 return reg[num]; 732 } 733 setRegister(int num,uint64_t value)734 void setRegister(int num, uint64_t value) { 735 assert(validRegister(num)); 736 reg[num] = value; 737 } 738 getIP() const739 uint64_t getIP() const { return reg[REGNO_SPARC_PC]; } 740 setIP(uint64_t value)741 void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; } 742 getSP() const743 uint64_t getSP() const { return reg[REGNO_SPARC_R14]; } 744 setSP(uint64_t value)745 void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; } 746 validFloatVectorRegister(int num) const747 bool validFloatVectorRegister(int num) const { return false; } 748 copyFloatVectorRegister(int num,uint64_t addr_)749 void copyFloatVectorRegister(int num, uint64_t addr_) {} 750 751 __dso_hidden void jumpto() const __dead; 752 753 private: 754 uint32_t reg[REGNO_SPARC_PC + 1]; 755 }; 756 757 enum { 758 DWARF_ALPHA_R0 = 0, 759 DWARF_ALPHA_R30 = 30, 760 DWARF_ALPHA_F0 = 32, 761 DWARF_ALPHA_F30 = 62, 762 763 REGNO_ALPHA_R0 = 0, 764 REGNO_ALPHA_R26 = 26, 765 REGNO_ALPHA_R30 = 30, 766 REGNO_ALPHA_PC = 31, 767 REGNO_ALPHA_F0 = 32, 768 REGNO_ALPHA_F30 = 62, 769 }; 770 771 class Registers_Alpha { 772 public: 773 enum { 774 LAST_REGISTER = REGNO_ALPHA_F30, 775 LAST_RESTORE_REG = REGNO_ALPHA_F30, 776 RETURN_OFFSET = 0, 777 RETURN_MASK = 0, 778 }; 779 typedef uint32_t reg_t; 780 781 __dso_hidden Registers_Alpha(); 782 dwarf2regno(int num)783 static int dwarf2regno(int num) { return num; } 784 validRegister(int num) const785 bool validRegister(int num) const { 786 return num >= 0 && num <= REGNO_ALPHA_PC; 787 } 788 getRegister(int num) const789 uint64_t getRegister(int num) const { 790 assert(validRegister(num)); 791 return reg[num]; 792 } 793 setRegister(int num,uint64_t value)794 void setRegister(int num, uint64_t value) { 795 assert(validRegister(num)); 796 reg[num] = value; 797 } 798 getIP() const799 uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; } 800 setIP(uint64_t value)801 void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; } 802 getSP() const803 uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; } 804 setSP(uint64_t value)805 void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; } 806 validFloatVectorRegister(int num) const807 bool validFloatVectorRegister(int num) const { 808 return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30; 809 } 810 copyFloatVectorRegister(int num,uint64_t addr_)811 void copyFloatVectorRegister(int num, uint64_t addr_) { 812 assert(validFloatVectorRegister(num)); 813 const void *addr = reinterpret_cast<const void *>(addr_); 814 memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0])); 815 } 816 817 __dso_hidden void jumpto() const __dead; 818 819 private: 820 uint64_t reg[REGNO_ALPHA_PC + 1]; 821 uint64_t fpreg[31]; 822 }; 823 824 enum { 825 DWARF_HPPA_R1 = 1, 826 DWARF_HPPA_R31 = 31, 827 DWARF_HPPA_FR4L = 32, 828 DWARF_HPPA_FR31H = 87, 829 830 REGNO_HPPA_PC = 0, 831 REGNO_HPPA_R1 = 1, 832 REGNO_HPPA_R2 = 2, 833 REGNO_HPPA_R30 = 30, 834 REGNO_HPPA_R31 = 31, 835 REGNO_HPPA_FR4L = 32, 836 REGNO_HPPA_FR31H = 87, 837 }; 838 839 class Registers_HPPA { 840 public: 841 enum { 842 LAST_REGISTER = REGNO_HPPA_FR31H, 843 LAST_RESTORE_REG = REGNO_HPPA_FR31H, 844 RETURN_OFFSET = 0, 845 RETURN_MASK = 3, 846 }; 847 848 __dso_hidden Registers_HPPA(); 849 dwarf2regno(int num)850 static int dwarf2regno(int num) { 851 if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31) 852 return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1); 853 if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H) 854 return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H); 855 return LAST_REGISTER + 1; 856 } 857 validRegister(int num) const858 bool validRegister(int num) const { 859 return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31; 860 } 861 getRegister(int num) const862 uint64_t getRegister(int num) const { 863 assert(validRegister(num)); 864 return reg[num]; 865 } 866 setRegister(int num,uint64_t value)867 void setRegister(int num, uint64_t value) { 868 assert(validRegister(num)); 869 reg[num] = value; 870 } 871 getIP() const872 uint64_t getIP() const { return reg[REGNO_HPPA_PC]; } 873 setIP(uint64_t value)874 void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; } 875 getSP() const876 uint64_t getSP() const { return reg[REGNO_HPPA_R30]; } 877 setSP(uint64_t value)878 void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; } 879 validFloatVectorRegister(int num) const880 bool validFloatVectorRegister(int num) const { 881 return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H; 882 } 883 copyFloatVectorRegister(int num,uint64_t addr_)884 void copyFloatVectorRegister(int num, uint64_t addr_) { 885 assert(validFloatVectorRegister(num)); 886 const void *addr = reinterpret_cast<const void *>(addr_); 887 memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0])); 888 } 889 890 __dso_hidden void jumpto() const __dead; 891 892 private: 893 uint32_t reg[REGNO_HPPA_R31 + 1]; 894 uint32_t fpreg[56]; 895 }; 896 897 enum { 898 DWARF_MIPS_R1 = 0, 899 DWARF_MIPS_R31 = 31, 900 DWARF_MIPS_F0 = 32, 901 DWARF_MIPS_F31 = 63, 902 903 REGNO_MIPS_PC = 0, 904 REGNO_MIPS_R1 = 0, 905 REGNO_MIPS_R29 = 29, 906 REGNO_MIPS_R31 = 31, 907 REGNO_MIPS_F0 = 33, 908 REGNO_MIPS_F31 = 64 909 }; 910 911 class Registers_MIPS { 912 public: 913 enum { 914 LAST_REGISTER = REGNO_MIPS_F31, 915 LAST_RESTORE_REG = REGNO_MIPS_F31, 916 RETURN_OFFSET = 0, 917 RETURN_MASK = 0, 918 }; 919 920 __dso_hidden Registers_MIPS(); 921 dwarf2regno(int num)922 static int dwarf2regno(int num) { 923 if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31) 924 return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1); 925 if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31) 926 return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0); 927 return LAST_REGISTER + 1; 928 } 929 validRegister(int num) const930 bool validRegister(int num) const { 931 return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31; 932 } 933 getRegister(int num) const934 uint64_t getRegister(int num) const { 935 assert(validRegister(num)); 936 return reg[num]; 937 } 938 setRegister(int num,uint64_t value)939 void setRegister(int num, uint64_t value) { 940 assert(validRegister(num)); 941 reg[num] = value; 942 } 943 getIP() const944 uint64_t getIP() const { return reg[REGNO_MIPS_PC]; } 945 setIP(uint64_t value)946 void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; } 947 getSP() const948 uint64_t getSP() const { return reg[REGNO_MIPS_R29]; } 949 setSP(uint64_t value)950 void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; } 951 validFloatVectorRegister(int num) const952 bool validFloatVectorRegister(int num) const { 953 return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31; 954 } 955 copyFloatVectorRegister(int num,uint64_t addr_)956 void copyFloatVectorRegister(int num, uint64_t addr_) { 957 assert(validFloatVectorRegister(num)); 958 const void *addr = reinterpret_cast<const void *>(addr_); 959 memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0])); 960 } 961 962 __dso_hidden void jumpto() const __dead; 963 964 private: 965 uint32_t reg[REGNO_MIPS_R31 + 1]; 966 uint64_t fpreg[32]; 967 }; 968 969 enum { 970 DWARF_MIPS64_R1 = 0, 971 DWARF_MIPS64_R31 = 31, 972 DWARF_MIPS64_F0 = 32, 973 DWARF_MIPS64_F31 = 63, 974 975 REGNO_MIPS64_PC = 0, 976 REGNO_MIPS64_R1 = 0, 977 REGNO_MIPS64_R29 = 29, 978 REGNO_MIPS64_R31 = 31, 979 REGNO_MIPS64_F0 = 33, 980 REGNO_MIPS64_F31 = 64 981 }; 982 983 class Registers_MIPS64 { 984 public: 985 enum { 986 LAST_REGISTER = REGNO_MIPS64_F31, 987 LAST_RESTORE_REG = REGNO_MIPS64_F31, 988 RETURN_OFFSET = 0, 989 RETURN_MASK = 0, 990 }; 991 992 __dso_hidden Registers_MIPS64(); 993 dwarf2regno(int num)994 static int dwarf2regno(int num) { 995 if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31) 996 return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1); 997 if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31) 998 return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0); 999 return LAST_REGISTER + 1; 1000 } 1001 validRegister(int num) const1002 bool validRegister(int num) const { 1003 return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31; 1004 } 1005 getRegister(int num) const1006 uint64_t getRegister(int num) const { 1007 assert(validRegister(num)); 1008 return reg[num]; 1009 } 1010 setRegister(int num,uint64_t value)1011 void setRegister(int num, uint64_t value) { 1012 assert(validRegister(num)); 1013 reg[num] = value; 1014 } 1015 getIP() const1016 uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; } 1017 setIP(uint64_t value)1018 void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; } 1019 getSP() const1020 uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; } 1021 setSP(uint64_t value)1022 void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; } 1023 validFloatVectorRegister(int num) const1024 bool validFloatVectorRegister(int num) const { 1025 return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31; 1026 } 1027 copyFloatVectorRegister(int num,uint64_t addr_)1028 void copyFloatVectorRegister(int num, uint64_t addr_) { 1029 assert(validFloatVectorRegister(num)); 1030 const void *addr = reinterpret_cast<const void *>(addr_); 1031 memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0])); 1032 } 1033 1034 __dso_hidden void jumpto() const __dead; 1035 1036 private: 1037 uint64_t reg[REGNO_MIPS64_R31 + 1]; 1038 uint64_t fpreg[32]; 1039 }; 1040 1041 enum { 1042 DWARF_OR1K_R0 = 0, 1043 DWARF_OR1K_SP = 1, 1044 DWARF_OR1K_LR = 9, 1045 DWARF_OR1K_R31 = 31, 1046 DWARF_OR1K_FPCSR = 32, 1047 1048 REGNO_OR1K_R0 = 0, 1049 REGNO_OR1K_SP = 1, 1050 REGNO_OR1K_LR = 9, 1051 REGNO_OR1K_R31 = 31, 1052 REGNO_OR1K_FPCSR = 32, 1053 }; 1054 1055 class Registers_or1k { 1056 public: 1057 enum { 1058 LAST_REGISTER = REGNO_OR1K_FPCSR, 1059 LAST_RESTORE_REG = REGNO_OR1K_FPCSR, 1060 RETURN_OFFSET = 0, 1061 RETURN_MASK = 0, 1062 }; 1063 1064 __dso_hidden Registers_or1k(); 1065 dwarf2regno(int num)1066 static int dwarf2regno(int num) { 1067 if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31) 1068 return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0); 1069 if (num == DWARF_OR1K_FPCSR) 1070 return REGNO_OR1K_FPCSR; 1071 return LAST_REGISTER + 1; 1072 } 1073 validRegister(int num) const1074 bool validRegister(int num) const { 1075 return num >= 0 && num <= LAST_RESTORE_REG; 1076 } 1077 getRegister(int num) const1078 uint64_t getRegister(int num) const { 1079 assert(validRegister(num)); 1080 return reg[num]; 1081 } 1082 setRegister(int num,uint64_t value)1083 void setRegister(int num, uint64_t value) { 1084 assert(validRegister(num)); 1085 reg[num] = value; 1086 } 1087 getIP() const1088 uint64_t getIP() const { return reg[REGNO_OR1K_LR]; } 1089 setIP(uint64_t value)1090 void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; } 1091 getSP() const1092 uint64_t getSP() const { return reg[REGNO_OR1K_SP]; } 1093 setSP(uint64_t value)1094 void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; } 1095 validFloatVectorRegister(int num) const1096 bool validFloatVectorRegister(int num) const { 1097 return false; 1098 } 1099 copyFloatVectorRegister(int num,uint64_t addr_)1100 void copyFloatVectorRegister(int num, uint64_t addr_) { 1101 } 1102 1103 __dso_hidden void jumpto() const __dead; 1104 1105 private: 1106 uint32_t reg[REGNO_OR1K_FPCSR + 1]; 1107 }; 1108 1109 #if __i386__ 1110 typedef Registers_x86 NativeUnwindRegisters; 1111 #elif __x86_64__ 1112 typedef Registers_x86_64 NativeUnwindRegisters; 1113 #elif __powerpc__ 1114 typedef Registers_ppc32 NativeUnwindRegisters; 1115 #elif __aarch64__ 1116 typedef Registers_aarch64 NativeUnwindRegisters; 1117 #elif __arm__ 1118 typedef Registers_arm32 NativeUnwindRegisters; 1119 #elif __vax__ 1120 typedef Registers_vax NativeUnwindRegisters; 1121 #elif __m68k__ 1122 typedef Registers_M68K NativeUnwindRegisters; 1123 #elif __mips_n64 || __mips_n32 1124 typedef Registers_MIPS64 NativeUnwindRegisters; 1125 #elif __mips__ 1126 typedef Registers_MIPS NativeUnwindRegisters; 1127 #elif __sh3__ 1128 typedef Registers_SH3 NativeUnwindRegisters; 1129 #elif __sparc64__ 1130 typedef Registers_SPARC64 NativeUnwindRegisters; 1131 #elif __sparc__ 1132 typedef Registers_SPARC NativeUnwindRegisters; 1133 #elif __alpha__ 1134 typedef Registers_Alpha NativeUnwindRegisters; 1135 #elif __hppa__ 1136 typedef Registers_HPPA NativeUnwindRegisters; 1137 #elif __or1k__ 1138 typedef Registers_or1k NativeUnwindRegisters; 1139 #endif 1140 } // namespace _Unwind 1141 1142 #endif // __REGISTERS_HPP__ 1143