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 19 namespace _Unwind { 20 21 enum { 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 33 class Registers_x86 { 34 public: 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 dwarf2regno(int num)44 static int dwarf2regno(int num) { return num; } 45 validRegister(int num) const46 bool validRegister(int num) const { 47 return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI; 48 } 49 getRegister(int num) const50 uint32_t getRegister(int num) const { 51 assert(validRegister(num)); 52 return reg[num]; 53 } 54 setRegister(int num,uint32_t value)55 void setRegister(int num, uint32_t value) { 56 assert(validRegister(num)); 57 reg[num] = value; 58 } 59 getIP() const60 uint32_t getIP() const { return reg[REGNO_X86_EIP]; } 61 setIP(uint32_t value)62 void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; } 63 getSP() const64 uint32_t getSP() const { return reg[REGNO_X86_ESP]; } 65 setSP(uint32_t value)66 void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; } 67 validFloatVectorRegister(int num) const68 bool validFloatVectorRegister(int num) const { return false; } 69 copyFloatVectorRegister(int num,uint32_t addr)70 void copyFloatVectorRegister(int num, uint32_t addr) { 71 } 72 73 __dso_hidden void jumpto() const __dead; 74 75 private: 76 uint32_t reg[REGNO_X86_EIP + 1]; 77 }; 78 79 enum { 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 99 class Registers_x86_64 { 100 public: 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 dwarf2regno(int num)110 static int dwarf2regno(int num) { return num; } 111 validRegister(int num) const112 bool validRegister(int num) const { 113 return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15; 114 } 115 getRegister(int num) const116 uint64_t getRegister(int num) const { 117 assert(validRegister(num)); 118 return reg[num]; 119 } 120 setRegister(int num,uint64_t value)121 void setRegister(int num, uint64_t value) { 122 assert(validRegister(num)); 123 reg[num] = value; 124 } 125 getIP() const126 uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; } 127 setIP(uint64_t value)128 void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; } 129 getSP() const130 uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; } 131 setSP(uint64_t value)132 void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; } 133 validFloatVectorRegister(int num) const134 bool validFloatVectorRegister(int num) const { return false; } 135 copyFloatVectorRegister(int num,uint64_t addr)136 void copyFloatVectorRegister(int num, uint64_t addr) { 137 } 138 139 __dso_hidden void jumpto() const __dead; 140 141 private: 142 uint64_t reg[REGNO_X86_64_RIP + 1]; 143 }; 144 145 enum { 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 175 class Registers_ppc32 { 176 public: 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 dwarf2regno(int num)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 validRegister(int num) const209 bool validRegister(int num) const { 210 return (num >= 0 && num <= REGNO_PPC32_SRR0) || 211 (num >= REGNO_PPC32_CTR && num <= REGNO_PPC32_SIGRETURN); 212 } 213 getRegister(int num) const214 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 setRegister(int num,uint64_t value)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 getIP() const245 uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; } 246 setIP(uint64_t value)247 void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; } 248 getSP() const249 uint64_t getSP() const { return reg[REGNO_PPC32_R1]; } 250 setSP(uint64_t value)251 void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; } 252 validFloatVectorRegister(int num) const253 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 copyFloatVectorRegister(int num,uint64_t addr_)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 268 private: 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 281 enum { 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 297 class Registers_aarch64 { 298 public: 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 dwarf2regno(int num)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 validRegister(int num) const320 bool validRegister(int num) const { 321 return (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_SP) || 322 num == DWARF_AARCH64_SIGRETURN; 323 } 324 getRegister(int num) const325 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 setRegister(int num,uint64_t value)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 getIP() const340 uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; } 341 setIP(uint64_t value)342 void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; } 343 getSP() const344 uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; } 345 setSP(uint64_t value)346 void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; } 347 validFloatVectorRegister(int num) const348 bool validFloatVectorRegister(int num) const { 349 return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31); 350 } 351 copyFloatVectorRegister(int num,uint64_t addr_)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 359 private: 360 uint64_t reg[REGNO_AARCH64_SP + 1]; 361 uint64_t vecreg[64]; 362 uint64_t sigreturn_reg; 363 }; 364 365 enum { 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 389 class Registers_arm32 { 390 public: 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 dwarf2regno(int num)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 validRegister(int num) const412 bool validRegister(int num) const { 413 return num >= 0 && num <= REGNO_ARM32_SPSR; 414 } 415 getRegister(int num) const416 uint64_t getRegister(int num) const { 417 assert(validRegister(num)); 418 return reg[num]; 419 } 420 setRegister(int num,uint64_t value)421 void setRegister(int num, uint64_t value) { 422 assert(validRegister(num)); 423 reg[num] = value; 424 } 425 getIP() const426 uint64_t getIP() const { return reg[REGNO_ARM32_R15]; } 427 setIP(uint64_t value)428 void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; } 429 getSP() const430 uint64_t getSP() const { return reg[REGNO_ARM32_SP]; } 431 setSP(uint64_t value)432 void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; } 433 validFloatVectorRegister(int num) const434 bool validFloatVectorRegister(int num) const { 435 return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31); 436 } 437 copyFloatVectorRegister(int num,uint64_t addr_)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 491 private: 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 502 enum { 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 513 class Registers_vax { 514 public: 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 dwarf2regno(int num)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 validRegister(int num) const532 bool validRegister(int num) const { 533 return num >= 0 && num <= LAST_RESTORE_REG; 534 } 535 getRegister(int num) const536 uint64_t getRegister(int num) const { 537 assert(validRegister(num)); 538 return reg[num]; 539 } 540 setRegister(int num,uint64_t value)541 void setRegister(int num, uint64_t value) { 542 assert(validRegister(num)); 543 reg[num] = value; 544 } 545 getIP() const546 uint64_t getIP() const { return reg[REGNO_VAX_R15]; } 547 setIP(uint64_t value)548 void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; } 549 getSP() const550 uint64_t getSP() const { return reg[REGNO_VAX_R14]; } 551 setSP(uint64_t value)552 void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; } 553 validFloatVectorRegister(int num) const554 bool validFloatVectorRegister(int num) const { 555 return false; 556 } 557 copyFloatVectorRegister(int num,uint64_t addr_)558 void copyFloatVectorRegister(int num, uint64_t addr_) { 559 } 560 561 __dso_hidden void jumpto() const __dead; 562 563 private: 564 uint32_t reg[REGNO_VAX_PSW + 1]; 565 }; 566 567 enum { 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 588 class Registers_M68K { 589 public: 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 dwarf2regno(int num)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 validRegister(int num) const611 bool validRegister(int num) const { 612 return num >= 0 && num <= REGNO_M68K_PC; 613 } 614 getRegister(int num) const615 uint64_t getRegister(int num) const { 616 assert(validRegister(num)); 617 return reg[num]; 618 } 619 setRegister(int num,uint64_t value)620 void setRegister(int num, uint64_t value) { 621 assert(validRegister(num)); 622 reg[num] = value; 623 } 624 getIP() const625 uint64_t getIP() const { return reg[REGNO_M68K_PC]; } 626 setIP(uint64_t value)627 void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; } 628 getSP() const629 uint64_t getSP() const { return reg[REGNO_M68K_A7]; } 630 setSP(uint64_t value)631 void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; } 632 validFloatVectorRegister(int num) const633 bool validFloatVectorRegister(int num) const { 634 return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7; 635 } 636 copyFloatVectorRegister(int num,uint64_t addr_)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 645 private: 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 653 enum { 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 673 class Registers_SH3 { 674 public: 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 dwarf2regno(int num)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 validRegister(int num) const705 bool validRegister(int num) const { 706 return (num >= 0 && num <= REGNO_SH3_GBR) || 707 (num >= REGNO_SH3_MACH && num <= REGNO_SH3_SR); 708 } 709 getRegister(int num) const710 uint64_t getRegister(int num) const { 711 assert(validRegister(num)); 712 return reg[num]; 713 } 714 setRegister(int num,uint64_t value)715 void setRegister(int num, uint64_t value) { 716 assert(validRegister(num)); 717 reg[num] = value; 718 } 719 getIP() const720 uint64_t getIP() const { return reg[REGNO_SH3_PC]; } 721 setIP(uint64_t value)722 void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; } 723 getSP() const724 uint64_t getSP() const { return reg[REGNO_SH3_R15]; } 725 setSP(uint64_t value)726 void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; } 727 validFloatVectorRegister(int num) const728 bool validFloatVectorRegister(int num) const { return false; } 729 copyFloatVectorRegister(int num,uint64_t addr_)730 void copyFloatVectorRegister(int num, uint64_t addr_) {} 731 732 __dso_hidden void jumpto() const __dead; 733 734 private: 735 uint32_t reg[REGNO_SH3_SR + 1]; 736 }; 737 738 enum { 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 750 class Registers_SPARC64 { 751 public: 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 dwarf2regno(int num)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 validRegister(int num) const770 bool validRegister(int num) const { 771 return num >= 0 && num <= REGNO_SPARC64_PC; 772 } 773 getRegister(int num) const774 uint64_t getRegister(int num) const { 775 assert(validRegister(num)); 776 return reg[num]; 777 } 778 setRegister(int num,uint64_t value)779 void setRegister(int num, uint64_t value) { 780 assert(validRegister(num)); 781 reg[num] = value; 782 } 783 getIP() const784 uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; } 785 setIP(uint64_t value)786 void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; } 787 getSP() const788 uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; } 789 setSP(uint64_t value)790 void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; } 791 validFloatVectorRegister(int num) const792 bool validFloatVectorRegister(int num) const { return false; } 793 copyFloatVectorRegister(int num,uint64_t addr_)794 void copyFloatVectorRegister(int num, uint64_t addr_) {} 795 796 __dso_hidden void jumpto() const __dead; 797 798 private: 799 uint64_t reg[REGNO_SPARC64_PC + 1]; 800 }; 801 802 enum { 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 814 class Registers_SPARC { 815 public: 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 dwarf2regno(int num)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 validRegister(int num) const834 bool validRegister(int num) const { 835 return num >= 0 && num <= REGNO_SPARC_PC; 836 } 837 getRegister(int num) const838 uint64_t getRegister(int num) const { 839 assert(validRegister(num)); 840 return reg[num]; 841 } 842 setRegister(int num,uint64_t value)843 void setRegister(int num, uint64_t value) { 844 assert(validRegister(num)); 845 reg[num] = value; 846 } 847 getIP() const848 uint64_t getIP() const { return reg[REGNO_SPARC_PC]; } 849 setIP(uint64_t value)850 void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; } 851 getSP() const852 uint64_t getSP() const { return reg[REGNO_SPARC_R14]; } 853 setSP(uint64_t value)854 void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; } 855 validFloatVectorRegister(int num) const856 bool validFloatVectorRegister(int num) const { return false; } 857 copyFloatVectorRegister(int num,uint64_t addr_)858 void copyFloatVectorRegister(int num, uint64_t addr_) {} 859 860 __dso_hidden void jumpto() const __dead; 861 862 private: 863 uint32_t reg[REGNO_SPARC_PC + 1]; 864 }; 865 866 enum { 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 882 class Registers_Alpha { 883 public: 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 dwarf2regno(int num)893 static int dwarf2regno(int num) { return num; } 894 validRegister(int num) const895 bool validRegister(int num) const { 896 return (num >= 0 && num <= REGNO_ALPHA_PC) || 897 num == REGNO_ALPHA_SIGRETURN; 898 } 899 getRegister(int num) const900 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 setRegister(int num,uint64_t value)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 getIP() const916 uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; } 917 setIP(uint64_t value)918 void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; } 919 getSP() const920 uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; } 921 setSP(uint64_t value)922 void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; } 923 validFloatVectorRegister(int num) const924 bool validFloatVectorRegister(int num) const { 925 return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30; 926 } 927 copyFloatVectorRegister(int num,uint64_t addr_)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 936 private: 937 uint64_t reg[REGNO_ALPHA_PC + 1]; 938 uint64_t fpreg[31]; 939 uint64_t sigreturn_reg; 940 }; 941 942 enum { 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 959 class Registers_HPPA { 960 public: 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 dwarf2regno(int num)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 validRegister(int num) const980 bool validRegister(int num) const { 981 return (num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31) || 982 num == REGNO_HPPA_SIGRETURN; 983 } 984 getRegister(int num) const985 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 setRegister(int num,uint64_t value)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 getIP() const1001 uint64_t getIP() const { return reg[REGNO_HPPA_PC]; } 1002 setIP(uint64_t value)1003 void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; } 1004 getSP() const1005 uint64_t getSP() const { return reg[REGNO_HPPA_R30]; } 1006 setSP(uint64_t value)1007 void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; } 1008 validFloatVectorRegister(int num) const1009 bool validFloatVectorRegister(int num) const { 1010 return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H; 1011 } 1012 copyFloatVectorRegister(int num,uint64_t addr_)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 1021 private: 1022 uint32_t reg[REGNO_HPPA_R31 + 1]; 1023 uint32_t fpreg[56]; 1024 uint32_t sigreturn_reg; 1025 }; 1026 1027 enum { 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 1050 class Registers_MIPS { 1051 public: 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 dwarf2regno(int num)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 validRegister(int num) const1071 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 getRegister(int num) const1076 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 setRegister(int num,uint64_t value)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 getIP() const1091 uint64_t getIP() const { return reg[REGNO_MIPS_PC]; } 1092 setIP(uint64_t value)1093 void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; } 1094 getSP() const1095 uint64_t getSP() const { return reg[REGNO_MIPS_R29]; } 1096 setSP(uint64_t value)1097 void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; } 1098 validFloatVectorRegister(int num) const1099 bool validFloatVectorRegister(int num) const { 1100 return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31; 1101 } 1102 copyFloatVectorRegister(int num,uint64_t addr_)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 1111 private: 1112 uint32_t reg[REGNO_MIPS_R31 + 1]; 1113 uint64_t fpreg[32]; 1114 uint32_t other_reg[3]; 1115 }; 1116 1117 enum { 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 1140 class Registers_MIPS64 { 1141 public: 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 dwarf2regno(int num)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 validRegister(int num) const1161 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 getRegister(int num) const1166 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 setRegister(int num,uint64_t value)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 getIP() const1181 uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; } 1182 setIP(uint64_t value)1183 void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; } 1184 getSP() const1185 uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; } 1186 setSP(uint64_t value)1187 void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; } 1188 validFloatVectorRegister(int num) const1189 bool validFloatVectorRegister(int num) const { 1190 return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31; 1191 } 1192 copyFloatVectorRegister(int num,uint64_t addr_)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 1201 private: 1202 uint64_t reg[REGNO_MIPS64_R31 + 1]; 1203 uint64_t fpreg[32]; 1204 uint64_t other_reg[3]; 1205 }; 1206 1207 enum { 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 1221 class Registers_or1k { 1222 public: 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 dwarf2regno(int num)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 validRegister(int num) const1240 bool validRegister(int num) const { 1241 return num >= 0 && num <= LAST_RESTORE_REG; 1242 } 1243 getRegister(int num) const1244 uint64_t getRegister(int num) const { 1245 assert(validRegister(num)); 1246 return reg[num]; 1247 } 1248 setRegister(int num,uint64_t value)1249 void setRegister(int num, uint64_t value) { 1250 assert(validRegister(num)); 1251 reg[num] = value; 1252 } 1253 getIP() const1254 uint64_t getIP() const { return reg[REGNO_OR1K_LR]; } 1255 setIP(uint64_t value)1256 void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; } 1257 getSP() const1258 uint64_t getSP() const { return reg[REGNO_OR1K_SP]; } 1259 setSP(uint64_t value)1260 void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; } 1261 validFloatVectorRegister(int num) const1262 bool validFloatVectorRegister(int num) const { 1263 return false; 1264 } 1265 copyFloatVectorRegister(int num,uint64_t addr_)1266 void copyFloatVectorRegister(int num, uint64_t addr_) { 1267 } 1268 1269 __dso_hidden void jumpto() const __dead; 1270 1271 private: 1272 uint32_t reg[REGNO_OR1K_FPCSR + 1]; 1273 }; 1274 1275 #if __i386__ 1276 typedef Registers_x86 NativeUnwindRegisters; 1277 #elif __x86_64__ 1278 typedef Registers_x86_64 NativeUnwindRegisters; 1279 #elif __powerpc__ 1280 typedef Registers_ppc32 NativeUnwindRegisters; 1281 #elif __aarch64__ 1282 typedef Registers_aarch64 NativeUnwindRegisters; 1283 #elif __arm__ 1284 typedef Registers_arm32 NativeUnwindRegisters; 1285 #elif __vax__ 1286 typedef Registers_vax NativeUnwindRegisters; 1287 #elif __m68k__ 1288 typedef Registers_M68K NativeUnwindRegisters; 1289 #elif __mips_n64 || __mips_n32 1290 typedef Registers_MIPS64 NativeUnwindRegisters; 1291 #elif __mips__ 1292 typedef Registers_MIPS NativeUnwindRegisters; 1293 #elif __sh3__ 1294 typedef Registers_SH3 NativeUnwindRegisters; 1295 #elif __sparc64__ 1296 typedef Registers_SPARC64 NativeUnwindRegisters; 1297 #elif __sparc__ 1298 typedef Registers_SPARC NativeUnwindRegisters; 1299 #elif __alpha__ 1300 typedef Registers_Alpha NativeUnwindRegisters; 1301 #elif __hppa__ 1302 typedef Registers_HPPA NativeUnwindRegisters; 1303 #elif __or1k__ 1304 typedef Registers_or1k NativeUnwindRegisters; 1305 #endif 1306 } // namespace _Unwind 1307 1308 #endif // __REGISTERS_HPP__ 1309