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 typedef uint32_t reg_t; 891 892 __dso_hidden Registers_Alpha(); 893 dwarf2regno(int num)894 static int dwarf2regno(int num) { return num; } 895 validRegister(int num) const896 bool validRegister(int num) const { 897 return (num >= 0 && num <= REGNO_ALPHA_PC) || 898 num == REGNO_ALPHA_SIGRETURN; 899 } 900 getRegister(int num) const901 uint64_t getRegister(int num) const { 902 assert(validRegister(num)); 903 if (num == REGNO_ALPHA_SIGRETURN) 904 return sigreturn_reg; 905 else 906 return reg[num]; 907 } 908 setRegister(int num,uint64_t value)909 void setRegister(int num, uint64_t value) { 910 assert(validRegister(num)); 911 if (num == REGNO_ALPHA_SIGRETURN) 912 sigreturn_reg = value; 913 else 914 reg[num] = value; 915 } 916 getIP() const917 uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; } 918 setIP(uint64_t value)919 void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; } 920 getSP() const921 uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; } 922 setSP(uint64_t value)923 void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; } 924 validFloatVectorRegister(int num) const925 bool validFloatVectorRegister(int num) const { 926 return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30; 927 } 928 copyFloatVectorRegister(int num,uint64_t addr_)929 void copyFloatVectorRegister(int num, uint64_t addr_) { 930 assert(validFloatVectorRegister(num)); 931 const void *addr = reinterpret_cast<const void *>(addr_); 932 memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0])); 933 } 934 935 __dso_hidden void jumpto() const __dead; 936 937 private: 938 uint64_t reg[REGNO_ALPHA_PC + 1]; 939 uint64_t fpreg[31]; 940 uint64_t sigreturn_reg; 941 }; 942 943 enum { 944 DWARF_HPPA_R1 = 1, 945 DWARF_HPPA_R31 = 31, 946 DWARF_HPPA_FR4L = 32, 947 DWARF_HPPA_FR31H = 87, 948 DWARF_HPPA_SIGRETURN = 89, 949 950 REGNO_HPPA_PC = 0, 951 REGNO_HPPA_R1 = 1, 952 REGNO_HPPA_R2 = 2, 953 REGNO_HPPA_R30 = 30, 954 REGNO_HPPA_R31 = 31, 955 REGNO_HPPA_FR4L = 32, 956 REGNO_HPPA_FR31H = 87, 957 REGNO_HPPA_SIGRETURN = 89, 958 }; 959 960 class Registers_HPPA { 961 public: 962 enum { 963 LAST_REGISTER = REGNO_HPPA_FR31H, 964 LAST_RESTORE_REG = REGNO_HPPA_SIGRETURN, 965 RETURN_OFFSET = 0, 966 RETURN_MASK = 3, 967 }; 968 969 __dso_hidden Registers_HPPA(); 970 dwarf2regno(int num)971 static int dwarf2regno(int num) { 972 if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31) 973 return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1); 974 if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H) 975 return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H); 976 if (num == DWARF_HPPA_SIGRETURN) 977 return REGNO_HPPA_SIGRETURN; 978 return LAST_REGISTER + 1; 979 } 980 validRegister(int num) const981 bool validRegister(int num) const { 982 return (num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31) || 983 num == REGNO_HPPA_SIGRETURN; 984 } 985 getRegister(int num) const986 uint64_t getRegister(int num) const { 987 assert(validRegister(num)); 988 if (num == REGNO_HPPA_SIGRETURN) 989 return sigreturn_reg; 990 else 991 return reg[num]; 992 } 993 setRegister(int num,uint64_t value)994 void setRegister(int num, uint64_t value) { 995 assert(validRegister(num)); 996 if (num == REGNO_HPPA_SIGRETURN) 997 sigreturn_reg = value; 998 else 999 reg[num] = value; 1000 } 1001 getIP() const1002 uint64_t getIP() const { return reg[REGNO_HPPA_PC]; } 1003 setIP(uint64_t value)1004 void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; } 1005 getSP() const1006 uint64_t getSP() const { return reg[REGNO_HPPA_R30]; } 1007 setSP(uint64_t value)1008 void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; } 1009 validFloatVectorRegister(int num) const1010 bool validFloatVectorRegister(int num) const { 1011 return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H; 1012 } 1013 copyFloatVectorRegister(int num,uint64_t addr_)1014 void copyFloatVectorRegister(int num, uint64_t addr_) { 1015 assert(validFloatVectorRegister(num)); 1016 const void *addr = reinterpret_cast<const void *>(addr_); 1017 memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0])); 1018 } 1019 1020 __dso_hidden void jumpto() const __dead; 1021 1022 private: 1023 uint32_t reg[REGNO_HPPA_R31 + 1]; 1024 uint32_t fpreg[56]; 1025 uint32_t sigreturn_reg; 1026 }; 1027 1028 enum { 1029 DWARF_MIPS_R1 = 0, 1030 DWARF_MIPS_R31 = 31, 1031 DWARF_MIPS_F0 = 32, 1032 DWARF_MIPS_F31 = 63, 1033 // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and 1034 // signal handler return address. 1035 DWARF_MIPS_MDHI = 64, 1036 DWARF_MIPS_MDLO = 65, 1037 DWARF_MIPS_SIGRETURN = 66, 1038 1039 REGNO_MIPS_PC = 0, 1040 REGNO_MIPS_R1 = 0, 1041 REGNO_MIPS_R29 = 29, 1042 REGNO_MIPS_R31 = 31, 1043 REGNO_MIPS_F0 = 33, 1044 REGNO_MIPS_F31 = 64, 1045 // these live in other_reg[] 1046 REGNO_MIPS_MDHI = 65, 1047 REGNO_MIPS_MDLO = 66, 1048 REGNO_MIPS_SIGRETURN = 67 1049 }; 1050 1051 class Registers_MIPS { 1052 public: 1053 enum { 1054 LAST_REGISTER = REGNO_MIPS_SIGRETURN, 1055 LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN, 1056 RETURN_OFFSET = 0, 1057 RETURN_MASK = 0, 1058 }; 1059 1060 __dso_hidden Registers_MIPS(); 1061 dwarf2regno(int num)1062 static int dwarf2regno(int num) { 1063 if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31) 1064 return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1); 1065 if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31) 1066 return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0); 1067 if (num >= DWARF_MIPS_MDHI && num <= DWARF_MIPS_SIGRETURN) 1068 return REGNO_MIPS_MDHI + (num - DWARF_MIPS_MDHI); 1069 return LAST_REGISTER + 1; 1070 } 1071 validRegister(int num) const1072 bool validRegister(int num) const { 1073 return (num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31) || 1074 (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN); 1075 } 1076 getRegister(int num) const1077 uint64_t getRegister(int num) const { 1078 assert(validRegister(num)); 1079 if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN) 1080 return other_reg[num - REGNO_MIPS_MDHI]; 1081 return reg[num]; 1082 } 1083 setRegister(int num,uint64_t value)1084 void setRegister(int num, uint64_t value) { 1085 assert(validRegister(num)); 1086 if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN) 1087 other_reg[num - REGNO_MIPS_MDHI] = value; 1088 else 1089 reg[num] = value; 1090 } 1091 getIP() const1092 uint64_t getIP() const { return reg[REGNO_MIPS_PC]; } 1093 setIP(uint64_t value)1094 void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; } 1095 getSP() const1096 uint64_t getSP() const { return reg[REGNO_MIPS_R29]; } 1097 setSP(uint64_t value)1098 void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; } 1099 validFloatVectorRegister(int num) const1100 bool validFloatVectorRegister(int num) const { 1101 return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31; 1102 } 1103 copyFloatVectorRegister(int num,uint64_t addr_)1104 void copyFloatVectorRegister(int num, uint64_t addr_) { 1105 assert(validFloatVectorRegister(num)); 1106 const void *addr = reinterpret_cast<const void *>(addr_); 1107 memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0])); 1108 } 1109 1110 __dso_hidden void jumpto() const __dead; 1111 1112 private: 1113 uint32_t reg[REGNO_MIPS_R31 + 1]; 1114 uint64_t fpreg[32]; 1115 uint32_t other_reg[3]; 1116 }; 1117 1118 enum { 1119 DWARF_MIPS64_R1 = 0, 1120 DWARF_MIPS64_R31 = 31, 1121 DWARF_MIPS64_F0 = 32, 1122 DWARF_MIPS64_F31 = 63, 1123 // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and 1124 // signal handler return address. 1125 DWARF_MIPS64_MDHI = 64, 1126 DWARF_MIPS64_MDLO = 65, 1127 DWARF_MIPS64_SIGRETURN = 66, 1128 1129 REGNO_MIPS64_PC = 0, 1130 REGNO_MIPS64_R1 = 0, 1131 REGNO_MIPS64_R29 = 29, 1132 REGNO_MIPS64_R31 = 31, 1133 REGNO_MIPS64_F0 = 33, 1134 REGNO_MIPS64_F31 = 64, 1135 // these live in other_reg[] 1136 REGNO_MIPS64_MDHI = 65, 1137 REGNO_MIPS64_MDLO = 66, 1138 REGNO_MIPS64_SIGRETURN = 67 1139 }; 1140 1141 class Registers_MIPS64 { 1142 public: 1143 enum { 1144 LAST_REGISTER = REGNO_MIPS_SIGRETURN, 1145 LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN, 1146 RETURN_OFFSET = 0, 1147 RETURN_MASK = 0, 1148 }; 1149 1150 __dso_hidden Registers_MIPS64(); 1151 dwarf2regno(int num)1152 static int dwarf2regno(int num) { 1153 if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31) 1154 return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1); 1155 if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31) 1156 return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0); 1157 if (num >= DWARF_MIPS64_MDHI && num <= DWARF_MIPS64_SIGRETURN) 1158 return REGNO_MIPS64_MDHI + (num - DWARF_MIPS64_MDHI); 1159 return LAST_REGISTER + 1; 1160 } 1161 validRegister(int num) const1162 bool validRegister(int num) const { 1163 return (num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31) || 1164 (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN); 1165 } 1166 getRegister(int num) const1167 uint64_t getRegister(int num) const { 1168 assert(validRegister(num)); 1169 if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN) 1170 return other_reg[num - REGNO_MIPS64_MDHI]; 1171 return reg[num]; 1172 } 1173 setRegister(int num,uint64_t value)1174 void setRegister(int num, uint64_t value) { 1175 assert(validRegister(num)); 1176 if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN) 1177 other_reg[num - REGNO_MIPS64_MDHI] = value; 1178 else 1179 reg[num] = value; 1180 } 1181 getIP() const1182 uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; } 1183 setIP(uint64_t value)1184 void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; } 1185 getSP() const1186 uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; } 1187 setSP(uint64_t value)1188 void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; } 1189 validFloatVectorRegister(int num) const1190 bool validFloatVectorRegister(int num) const { 1191 return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31; 1192 } 1193 copyFloatVectorRegister(int num,uint64_t addr_)1194 void copyFloatVectorRegister(int num, uint64_t addr_) { 1195 assert(validFloatVectorRegister(num)); 1196 const void *addr = reinterpret_cast<const void *>(addr_); 1197 memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0])); 1198 } 1199 1200 __dso_hidden void jumpto() const __dead; 1201 1202 private: 1203 uint64_t reg[REGNO_MIPS64_R31 + 1]; 1204 uint64_t fpreg[32]; 1205 uint64_t other_reg[3]; 1206 }; 1207 1208 enum { 1209 DWARF_OR1K_R0 = 0, 1210 DWARF_OR1K_SP = 1, 1211 DWARF_OR1K_LR = 9, 1212 DWARF_OR1K_R31 = 31, 1213 DWARF_OR1K_FPCSR = 32, 1214 1215 REGNO_OR1K_R0 = 0, 1216 REGNO_OR1K_SP = 1, 1217 REGNO_OR1K_LR = 9, 1218 REGNO_OR1K_R31 = 31, 1219 REGNO_OR1K_FPCSR = 32, 1220 }; 1221 1222 class Registers_or1k { 1223 public: 1224 enum { 1225 LAST_REGISTER = REGNO_OR1K_FPCSR, 1226 LAST_RESTORE_REG = REGNO_OR1K_FPCSR, 1227 RETURN_OFFSET = 0, 1228 RETURN_MASK = 0, 1229 }; 1230 1231 __dso_hidden Registers_or1k(); 1232 dwarf2regno(int num)1233 static int dwarf2regno(int num) { 1234 if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31) 1235 return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0); 1236 if (num == DWARF_OR1K_FPCSR) 1237 return REGNO_OR1K_FPCSR; 1238 return LAST_REGISTER + 1; 1239 } 1240 validRegister(int num) const1241 bool validRegister(int num) const { 1242 return num >= 0 && num <= LAST_RESTORE_REG; 1243 } 1244 getRegister(int num) const1245 uint64_t getRegister(int num) const { 1246 assert(validRegister(num)); 1247 return reg[num]; 1248 } 1249 setRegister(int num,uint64_t value)1250 void setRegister(int num, uint64_t value) { 1251 assert(validRegister(num)); 1252 reg[num] = value; 1253 } 1254 getIP() const1255 uint64_t getIP() const { return reg[REGNO_OR1K_LR]; } 1256 setIP(uint64_t value)1257 void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; } 1258 getSP() const1259 uint64_t getSP() const { return reg[REGNO_OR1K_SP]; } 1260 setSP(uint64_t value)1261 void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; } 1262 validFloatVectorRegister(int num) const1263 bool validFloatVectorRegister(int num) const { 1264 return false; 1265 } 1266 copyFloatVectorRegister(int num,uint64_t addr_)1267 void copyFloatVectorRegister(int num, uint64_t addr_) { 1268 } 1269 1270 __dso_hidden void jumpto() const __dead; 1271 1272 private: 1273 uint32_t reg[REGNO_OR1K_FPCSR + 1]; 1274 }; 1275 1276 #if __i386__ 1277 typedef Registers_x86 NativeUnwindRegisters; 1278 #elif __x86_64__ 1279 typedef Registers_x86_64 NativeUnwindRegisters; 1280 #elif __powerpc__ 1281 typedef Registers_ppc32 NativeUnwindRegisters; 1282 #elif __aarch64__ 1283 typedef Registers_aarch64 NativeUnwindRegisters; 1284 #elif __arm__ 1285 typedef Registers_arm32 NativeUnwindRegisters; 1286 #elif __vax__ 1287 typedef Registers_vax NativeUnwindRegisters; 1288 #elif __m68k__ 1289 typedef Registers_M68K NativeUnwindRegisters; 1290 #elif __mips_n64 || __mips_n32 1291 typedef Registers_MIPS64 NativeUnwindRegisters; 1292 #elif __mips__ 1293 typedef Registers_MIPS NativeUnwindRegisters; 1294 #elif __sh3__ 1295 typedef Registers_SH3 NativeUnwindRegisters; 1296 #elif __sparc64__ 1297 typedef Registers_SPARC64 NativeUnwindRegisters; 1298 #elif __sparc__ 1299 typedef Registers_SPARC NativeUnwindRegisters; 1300 #elif __alpha__ 1301 typedef Registers_Alpha NativeUnwindRegisters; 1302 #elif __hppa__ 1303 typedef Registers_HPPA NativeUnwindRegisters; 1304 #elif __or1k__ 1305 typedef Registers_or1k NativeUnwindRegisters; 1306 #endif 1307 } // namespace _Unwind 1308 1309 #endif // __REGISTERS_HPP__ 1310