1207340Sjkim//===----------------------------- Registers.hpp --------------------------===// 2207340Sjkim// 3207340Sjkim// The LLVM Compiler Infrastructure 4207340Sjkim// 5207340Sjkim// This file is dual licensed under the MIT and the University of Illinois Open 6207340Sjkim// Source Licenses. See LICENSE.TXT for details. 7207340Sjkim// 8217365Sjkim// 9217365Sjkim// Models register sets for supported processors. 10207340Sjkim// 11207340Sjkim//===----------------------------------------------------------------------===// 12217365Sjkim#ifndef __REGISTERS_HPP__ 13217365Sjkim#define __REGISTERS_HPP__ 14217365Sjkim 15217365Sjkim#include <sys/endian.h> 16217365Sjkim#include <cassert> 17217365Sjkim#include <cstdint> 18217365Sjkim 19217365Sjkimnamespace _Unwind { 20217365Sjkim 21217365Sjkimenum { 22217365Sjkim REGNO_X86_EAX = 0, 23217365Sjkim REGNO_X86_ECX = 1, 24217365Sjkim REGNO_X86_EDX = 2, 25217365Sjkim REGNO_X86_EBX = 3, 26207340Sjkim REGNO_X86_ESP = 4, 27217365Sjkim REGNO_X86_EBP = 5, 28217365Sjkim REGNO_X86_ESI = 6, 29217365Sjkim REGNO_X86_EDI = 7, 30207340Sjkim REGNO_X86_EIP = 8, 31217365Sjkim}; 32217365Sjkim 33217365Sjkimclass Registers_x86 { 34217365Sjkimpublic: 35217365Sjkim enum { 36217365Sjkim LAST_REGISTER = REGNO_X86_EIP, 37217365Sjkim LAST_RESTORE_REG = REGNO_X86_EIP, 38217365Sjkim RETURN_OFFSET = 0, 39217365Sjkim RETURN_MASK = 0, 40217365Sjkim }; 41217365Sjkim 42217365Sjkim __dso_hidden Registers_x86(); 43217365Sjkim 44207340Sjkim static int dwarf2regno(int num) { return num; } 45207340Sjkim 46207344Sjkim bool validRegister(int num) const { 47207340Sjkim return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI; 48207340Sjkim } 49207340Sjkim 50207340Sjkim uint32_t getRegister(int num) const { 51207340Sjkim assert(validRegister(num)); 52207340Sjkim return reg[num]; 53207340Sjkim } 54207340Sjkim 55207340Sjkim void setRegister(int num, uint32_t value) { 56207340Sjkim assert(validRegister(num)); 57207340Sjkim reg[num] = value; 58207340Sjkim } 59207340Sjkim 60207340Sjkim uint32_t getIP() const { return reg[REGNO_X86_EIP]; } 61207340Sjkim 62207340Sjkim void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; } 63207340Sjkim 64207340Sjkim uint32_t getSP() const { return reg[REGNO_X86_ESP]; } 65207340Sjkim 66207340Sjkim void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; } 67207340Sjkim 68207340Sjkim bool validFloatVectorRegister(int num) const { return false; } 69207340Sjkim 70207340Sjkim void copyFloatVectorRegister(int num, uint32_t addr) { 71207340Sjkim } 72207340Sjkim 73207340Sjkim __dso_hidden void jumpto() const __dead; 74207340Sjkim 75207340Sjkimprivate: 76207340Sjkim uint32_t reg[REGNO_X86_EIP + 1]; 77207340Sjkim}; 78207340Sjkim 79207340Sjkimenum { 80207340Sjkim REGNO_X86_64_RAX = 0, 81207340Sjkim REGNO_X86_64_RDX = 1, 82207340Sjkim REGNO_X86_64_RCX = 2, 83207340Sjkim REGNO_X86_64_RBX = 3, 84207340Sjkim REGNO_X86_64_RSI = 4, 85207340Sjkim REGNO_X86_64_RDI = 5, 86207340Sjkim REGNO_X86_64_RBP = 6, 87207340Sjkim REGNO_X86_64_RSP = 7, 88207340Sjkim REGNO_X86_64_R8 = 8, 89207340Sjkim REGNO_X86_64_R9 = 9, 90207340Sjkim REGNO_X86_64_R10 = 10, 91207340Sjkim REGNO_X86_64_R11 = 11, 92207340Sjkim REGNO_X86_64_R12 = 12, 93207340Sjkim REGNO_X86_64_R13 = 13, 94207340Sjkim REGNO_X86_64_R14 = 14, 95207340Sjkim REGNO_X86_64_R15 = 15, 96207340Sjkim REGNO_X86_64_RIP = 16, 97207340Sjkim}; 98207340Sjkim 99207340Sjkimclass Registers_x86_64 { 100207340Sjkimpublic: 101207340Sjkim enum { 102207340Sjkim LAST_REGISTER = REGNO_X86_64_RIP, 103207340Sjkim LAST_RESTORE_REG = REGNO_X86_64_RIP, 104207340Sjkim RETURN_OFFSET = 0, 105207340Sjkim RETURN_MASK = 0, 106207340Sjkim }; 107207340Sjkim 108207340Sjkim __dso_hidden Registers_x86_64(); 109207340Sjkim 110207340Sjkim static int dwarf2regno(int num) { return num; } 111207340Sjkim 112207340Sjkim bool validRegister(int num) const { 113207340Sjkim return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15; 114207340Sjkim } 115207340Sjkim 116207340Sjkim uint64_t getRegister(int num) const { 117207340Sjkim assert(validRegister(num)); 118207340Sjkim return reg[num]; 119207340Sjkim } 120207340Sjkim 121207340Sjkim void setRegister(int num, uint64_t value) { 122207340Sjkim assert(validRegister(num)); 123207340Sjkim reg[num] = value; 124207340Sjkim } 125207340Sjkim 126207340Sjkim uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; } 127207340Sjkim 128207340Sjkim void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; } 129207340Sjkim 130207340Sjkim uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; } 131207340Sjkim 132207340Sjkim void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; } 133207340Sjkim 134207340Sjkim bool validFloatVectorRegister(int num) const { return false; } 135207340Sjkim 136207340Sjkim void copyFloatVectorRegister(int num, uint64_t addr) { 137207340Sjkim } 138207340Sjkim 139207340Sjkim __dso_hidden void jumpto() const __dead; 140207340Sjkim 141207340Sjkimprivate: 142207340Sjkim uint64_t reg[REGNO_X86_64_RIP + 1]; 143207340Sjkim}; 144207340Sjkim 145207340Sjkimenum { 146207340Sjkim DWARF_PPC32_R0 = 0, 147207340Sjkim DWARF_PPC32_R31 = 31, 148207340Sjkim DWARF_PPC32_F0 = 32, 149207340Sjkim DWARF_PPC32_F31 = 63, 150207340Sjkim DWARF_PPC32_LR = 65, 151207340Sjkim DWARF_PPC32_CTR = 66, 152207340Sjkim DWARF_PPC32_CR = 70, 153207340Sjkim DWARF_PPC32_XER = 76, 154207340Sjkim DWARF_PPC32_V0 = 77, 155207340Sjkim DWARF_PPC32_SIGRETURN = 99, 156207340Sjkim DWARF_PPC32_V31 = 108, 157207340Sjkim 158207340Sjkim REGNO_PPC32_R0 = 0, 159207340Sjkim REGNO_PPC32_R1 = 1, 160207340Sjkim REGNO_PPC32_R31 = 31, 161207340Sjkim REGNO_PPC32_LR = 32, 162207340Sjkim REGNO_PPC32_CR = 33, 163207340Sjkim REGNO_PPC32_SRR0 = 34, 164207340Sjkim 165207340Sjkim REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1, 166207340Sjkim REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31, 167207340Sjkim REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1, 168207340Sjkim REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31, 169207340Sjkim 170207340Sjkim REGNO_PPC32_CTR = REGNO_PPC32_V31 + 1, 171207340Sjkim REGNO_PPC32_XER = REGNO_PPC32_CTR + 1, 172207340Sjkim REGNO_PPC32_SIGRETURN = REGNO_PPC32_XER + 1 173207340Sjkim}; 174207340Sjkim 175207340Sjkimclass Registers_ppc32 { 176207340Sjkimpublic: 177207340Sjkim enum { 178207340Sjkim LAST_REGISTER = REGNO_PPC32_SIGRETURN, 179207340Sjkim LAST_RESTORE_REG = REGNO_PPC32_SIGRETURN, 180207340Sjkim RETURN_OFFSET = 0, 181207340Sjkim RETURN_MASK = 0, 182207340Sjkim }; 183207340Sjkim 184207340Sjkim __dso_hidden Registers_ppc32(); 185207340Sjkim 186207340Sjkim static int dwarf2regno(int num) { 187207340Sjkim if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31) 188207340Sjkim return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0); 189207340Sjkim if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31) 190207340Sjkim return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0); 191207340Sjkim if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31) 192207340Sjkim return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0); 193207340Sjkim switch (num) { 194207340Sjkim case DWARF_PPC32_LR: 195207340Sjkim return REGNO_PPC32_LR; 196207340Sjkim case DWARF_PPC32_CR: 197207340Sjkim return REGNO_PPC32_CR; 198207340Sjkim case DWARF_PPC32_CTR: 199207340Sjkim return REGNO_PPC32_CTR; 200207340Sjkim case DWARF_PPC32_XER: 201207340Sjkim return REGNO_PPC32_XER; 202207340Sjkim case DWARF_PPC32_SIGRETURN: 203207340Sjkim return REGNO_PPC32_SIGRETURN; 204207340Sjkim default: 205207340Sjkim return LAST_REGISTER + 1; 206207340Sjkim } 207207340Sjkim } 208207340Sjkim 209207340Sjkim bool validRegister(int num) const { 210207340Sjkim return (num >= 0 && num <= REGNO_PPC32_SRR0) || 211207340Sjkim (num >= REGNO_PPC32_CTR && num <= REGNO_PPC32_SIGRETURN); 212207340Sjkim } 213207340Sjkim 214207340Sjkim uint64_t getRegister(int num) const { 215207340Sjkim assert(validRegister(num)); 216207340Sjkim switch (num) { 217207340Sjkim case REGNO_PPC32_CTR: 218207340Sjkim return ctr_reg; 219207340Sjkim case REGNO_PPC32_XER: 220207340Sjkim return xer_reg; 221207340Sjkim case REGNO_PPC32_SIGRETURN: 222207340Sjkim return sigreturn_reg; 223207340Sjkim default: 224207340Sjkim return reg[num]; 225213806Sjkim } 226207340Sjkim } 227207340Sjkim 228207340Sjkim void setRegister(int num, uint64_t value) { 229207340Sjkim assert(validRegister(num)); 230207340Sjkim switch (num) { 231207340Sjkim case REGNO_PPC32_CTR: 232207340Sjkim ctr_reg = value; 233207340Sjkim break; 234207340Sjkim case REGNO_PPC32_XER: 235207340Sjkim xer_reg = value; 236207340Sjkim break; 237207340Sjkim case REGNO_PPC32_SIGRETURN: 238207340Sjkim sigreturn_reg = value; 239207340Sjkim break; 240207340Sjkim default: 241207340Sjkim reg[num] = value; 242207340Sjkim } 243207340Sjkim } 244207340Sjkim 245207340Sjkim uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; } 246207340Sjkim 247207340Sjkim void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; } 248207340Sjkim 249207340Sjkim uint64_t getSP() const { return reg[REGNO_PPC32_R1]; } 250207340Sjkim 251207340Sjkim void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; } 252207340Sjkim 253207340Sjkim bool validFloatVectorRegister(int num) const { 254207340Sjkim return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) || 255207340Sjkim (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31); 256207340Sjkim } 257207340Sjkim 258207340Sjkim void copyFloatVectorRegister(int num, uint64_t addr_) { 259207340Sjkim const void *addr = reinterpret_cast<const void *>(addr_); 260207340Sjkim if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) 261207340Sjkim memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0])); 262207340Sjkim else 263207340Sjkim memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0])); 264207340Sjkim } 265207340Sjkim 266207340Sjkim __dso_hidden void jumpto() const __dead; 267207340Sjkim 268207340Sjkimprivate: 269207340Sjkim struct vecreg_t { 270207340Sjkim uint64_t low, high; 271207340Sjkim }; 272207340Sjkim uint32_t reg[REGNO_PPC32_SRR0 + 1]; 273207340Sjkim uint32_t dummy; 274207340Sjkim uint64_t fpreg[32]; 275207340Sjkim vecreg_t vecreg[64]; 276207340Sjkim uint32_t ctr_reg; 277207340Sjkim uint32_t xer_reg; 278207340Sjkim uint32_t sigreturn_reg; 279207340Sjkim}; 280207340Sjkim 281207340Sjkimenum { 282207340Sjkim DWARF_AARCH64_X0 = 0, 283207340Sjkim DWARF_AARCH64_X30 = 30, 284207340Sjkim DWARF_AARCH64_SP = 31, 285207340Sjkim DWARF_AARCH64_V0 = 64, 286207340Sjkim DWARF_AARCH64_V31 = 95, 287207340Sjkim DWARF_AARCH64_SIGRETURN = 96, 288207340Sjkim 289207340Sjkim REGNO_AARCH64_X0 = 0, 290207340Sjkim REGNO_AARCH64_X30 = 30, 291207340Sjkim REGNO_AARCH64_SP = 31, 292207340Sjkim REGNO_AARCH64_V0 = 32, 293207340Sjkim REGNO_AARCH64_V31 = 63, 294207340Sjkim REGNO_AARCH64_SIGRETURN = 64, 295207340Sjkim}; 296207340Sjkim 297207340Sjkimclass Registers_aarch64 { 298207340Sjkimpublic: 299207340Sjkim enum { 300207340Sjkim LAST_RESTORE_REG = REGNO_AARCH64_SIGRETURN, 301207340Sjkim LAST_REGISTER = REGNO_AARCH64_SIGRETURN, 302207340Sjkim RETURN_OFFSET = 0, 303207340Sjkim RETURN_MASK = 0, 304207340Sjkim }; 305207340Sjkim 306207340Sjkim __dso_hidden Registers_aarch64(); 307207340Sjkim 308207340Sjkim static int dwarf2regno(int num) { 309207340Sjkim if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30) 310207340Sjkim return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0); 311207340Sjkim if (num == DWARF_AARCH64_SP) 312207340Sjkim return REGNO_AARCH64_SP; 313207340Sjkim if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31) 314207340Sjkim return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0); 315207340Sjkim if (num == DWARF_AARCH64_SIGRETURN) 316207340Sjkim return REGNO_AARCH64_SIGRETURN; 317207340Sjkim return LAST_REGISTER + 1; 318207340Sjkim } 319207340Sjkim 320207340Sjkim bool validRegister(int num) const { 321207340Sjkim return (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_SP) || 322207340Sjkim num == DWARF_AARCH64_SIGRETURN; 323207340Sjkim } 324207340Sjkim 325207340Sjkim uint64_t getRegister(int num) const { 326207340Sjkim assert(validRegister(num)); 327207340Sjkim if (num == REGNO_AARCH64_SIGRETURN) 328207340Sjkim return sigreturn_reg; 329207340Sjkim return reg[num]; 330207340Sjkim } 331207340Sjkim 332207340Sjkim void setRegister(int num, uint64_t value) { 333207340Sjkim assert(validRegister(num)); 334207340Sjkim if (num == REGNO_AARCH64_SIGRETURN) 335207340Sjkim sigreturn_reg = value; 336207340Sjkim else 337207340Sjkim reg[num] = value; 338207340Sjkim } 339207340Sjkim 340207340Sjkim uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; } 341207340Sjkim 342207340Sjkim void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; } 343207340Sjkim 344207340Sjkim uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; } 345207340Sjkim 346207340Sjkim void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; } 347207340Sjkim 348207340Sjkim bool validFloatVectorRegister(int num) const { 349207340Sjkim return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31); 350207340Sjkim } 351207340Sjkim 352207340Sjkim void copyFloatVectorRegister(int num, uint64_t addr_) { 353207340Sjkim const void *addr = reinterpret_cast<const void *>(addr_); 354207340Sjkim memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, 16); 355207340Sjkim } 356207340Sjkim 357207340Sjkim __dso_hidden void jumpto() const __dead; 358207340Sjkim 359207340Sjkimprivate: 360207340Sjkim uint64_t reg[REGNO_AARCH64_SP + 1]; 361207340Sjkim uint64_t vecreg[64]; 362207340Sjkim uint64_t sigreturn_reg; 363207340Sjkim}; 364207340Sjkim 365207340Sjkimenum { 366207340Sjkim DWARF_ARM32_R0 = 0, 367207340Sjkim DWARF_ARM32_R15 = 15, 368207340Sjkim DWARF_ARM32_SPSR = 128, 369207340Sjkim DWARF_ARM32_S0 = 64, 370207340Sjkim DWARF_ARM32_S31 = 95, 371207340Sjkim DWARF_ARM32_D0 = 256, 372207340Sjkim DWARF_ARM32_D31 = 287, 373207340Sjkim REGNO_ARM32_R0 = 0, 374207340Sjkim REGNO_ARM32_SP = 13, 375207340Sjkim REGNO_ARM32_R15 = 15, 376207340Sjkim REGNO_ARM32_SPSR = 16, 377207340Sjkim REGNO_ARM32_D0 = 17, 378207340Sjkim REGNO_ARM32_D15 = 32, 379207340Sjkim REGNO_ARM32_D31 = 48, 380207340Sjkim REGNO_ARM32_S0 = 49, 381207340Sjkim REGNO_ARM32_S31 = 80, 382207340Sjkim}; 383207340Sjkim 384207340Sjkim#define FLAGS_VFPV2_USED 0x1 385207340Sjkim#define FLAGS_VFPV3_USED 0x2 386207340Sjkim#define FLAGS_LEGACY_VFPV2_REGNO 0x4 387207340Sjkim#define FLAGS_EXTENDED_VFPV2_REGNO 0x8 388207340Sjkim 389207340Sjkimclass Registers_arm32 { 390207340Sjkimpublic: 391207340Sjkim enum { 392207340Sjkim LAST_REGISTER = REGNO_ARM32_S31, 393207340Sjkim LAST_RESTORE_REG = REGNO_ARM32_S31, 394207340Sjkim RETURN_OFFSET = 0, 395207340Sjkim RETURN_MASK = 0, 396207340Sjkim }; 397207340Sjkim 398207340Sjkim __dso_hidden Registers_arm32(); 399207340Sjkim 400207340Sjkim static int dwarf2regno(int num) { 401207340Sjkim if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15) 402207340Sjkim return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0); 403207340Sjkim if (num == DWARF_ARM32_SPSR) 404207340Sjkim return REGNO_ARM32_SPSR; 405207340Sjkim if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31) 406213806Sjkim return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0); 407207340Sjkim if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31) 408207340Sjkim return REGNO_ARM32_S0 + (num - DWARF_ARM32_S0); 409207340Sjkim return LAST_REGISTER + 1; 410207340Sjkim } 411207340Sjkim 412207340Sjkim bool validRegister(int num) const { 413207340Sjkim return num >= 0 && num <= REGNO_ARM32_SPSR; 414207340Sjkim } 415207340Sjkim 416207340Sjkim uint64_t getRegister(int num) const { 417207340Sjkim assert(validRegister(num)); 418207340Sjkim return reg[num]; 419207340Sjkim } 420207340Sjkim 421207340Sjkim void setRegister(int num, uint64_t value) { 422207340Sjkim assert(validRegister(num)); 423207340Sjkim reg[num] = value; 424207340Sjkim } 425207340Sjkim 426207340Sjkim uint64_t getIP() const { return reg[REGNO_ARM32_R15]; } 427207340Sjkim 428207340Sjkim void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; } 429207340Sjkim 430207340Sjkim uint64_t getSP() const { return reg[REGNO_ARM32_SP]; } 431207340Sjkim 432207340Sjkim void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; } 433207340Sjkim 434207340Sjkim bool validFloatVectorRegister(int num) const { 435207340Sjkim return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31); 436207340Sjkim } 437207340Sjkim 438207340Sjkim void copyFloatVectorRegister(int num, uint64_t addr_) { 439207340Sjkim assert(validFloatVectorRegister(num)); 440207340Sjkim const void *addr = reinterpret_cast<const void *>(addr_); 441207340Sjkim if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) { 442207340Sjkim /* 443207340Sjkim * XXX 444207340Sjkim * There are two numbering schemes for VFPv2 registers: s0-s31 445207340Sjkim * (used by GCC) and d0-d15 (used by LLVM). We won't support both 446207340Sjkim * schemes simultaneously in a same frame. 447207340Sjkim */ 448207340Sjkim assert((flags & FLAGS_EXTENDED_VFPV2_REGNO) == 0); 449207340Sjkim flags |= FLAGS_LEGACY_VFPV2_REGNO; 450207340Sjkim if ((flags & FLAGS_VFPV2_USED) == 0) { 451207340Sjkim lazyVFPv2(); 452207340Sjkim flags |= FLAGS_VFPV2_USED; 453207340Sjkim } 454207340Sjkim /* 455207340Sjkim * Emulate single precision register as half of the 456207340Sjkim * corresponding double register. 457207340Sjkim */ 458207340Sjkim int dnum = (num - REGNO_ARM32_S0) / 2; 459207340Sjkim int part = (num - REGNO_ARM32_S0) % 2; 460207340Sjkim#if _BYTE_ORDER == _BIG_ENDIAN 461207340Sjkim part = 1 - part; 462207340Sjkim#endif 463207340Sjkim memcpy((uint8_t *)(fpreg + dnum) + part * sizeof(fpreg[0]) / 2, 464207340Sjkim addr, sizeof(fpreg[0]) / 2); 465207340Sjkim } else { 466207340Sjkim if (num <= REGNO_ARM32_D15) { 467207340Sjkim /* 468207340Sjkim * XXX 469207340Sjkim * See XXX comment above. 470207340Sjkim */ 471207340Sjkim assert((flags & FLAGS_LEGACY_VFPV2_REGNO) == 0); 472207340Sjkim flags |= FLAGS_EXTENDED_VFPV2_REGNO; 473207340Sjkim if ((flags & FLAGS_VFPV2_USED) == 0) { 474207340Sjkim lazyVFPv2(); 475207340Sjkim flags |= FLAGS_VFPV2_USED; 476207340Sjkim } 477207340Sjkim } else { 478207340Sjkim if ((flags & FLAGS_VFPV3_USED) == 0) { 479207340Sjkim lazyVFPv3(); 480207340Sjkim flags |= FLAGS_VFPV3_USED; 481207340Sjkim } 482207340Sjkim } 483207340Sjkim memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0])); 484207340Sjkim } 485207340Sjkim } 486207340Sjkim 487207340Sjkim __dso_hidden void lazyVFPv2(); 488207340Sjkim __dso_hidden void lazyVFPv3(); 489207340Sjkim __dso_hidden void jumpto() const __dead; 490207340Sjkim 491207340Sjkimprivate: 492207340Sjkim uint32_t reg[REGNO_ARM32_SPSR + 1]; 493207340Sjkim uint32_t flags; 494207340Sjkim uint64_t fpreg[32]; 495207340Sjkim}; 496207340Sjkim 497207340Sjkim#undef FLAGS_VFPV2_USED 498207340Sjkim#undef FLAGS_VFPV3_USED 499207340Sjkim#undef FLAGS_LEGACY_VFPV2_REGNO 500207340Sjkim#undef FLAGS_EXTENDED_VFPV2_REGNO 501207340Sjkim 502207340Sjkimenum { 503207340Sjkim DWARF_VAX_R0 = 0, 504207340Sjkim DWARF_VAX_R15 = 15, 505207340Sjkim DWARF_VAX_PSW = 16, 506207340Sjkim 507207340Sjkim REGNO_VAX_R0 = 0, 508207340Sjkim REGNO_VAX_R14 = 14, 509207340Sjkim REGNO_VAX_R15 = 15, 510207340Sjkim REGNO_VAX_PSW = 16, 511207340Sjkim}; 512207340Sjkim 513207340Sjkimclass Registers_vax { 514207340Sjkimpublic: 515207340Sjkim enum { 516207340Sjkim LAST_REGISTER = REGNO_VAX_PSW, 517207340Sjkim LAST_RESTORE_REG = REGNO_VAX_PSW, 518207340Sjkim RETURN_OFFSET = 0, 519207340Sjkim RETURN_MASK = 0, 520207340Sjkim }; 521207340Sjkim 522207340Sjkim __dso_hidden Registers_vax(); 523207340Sjkim 524207340Sjkim static int dwarf2regno(int num) { 525207340Sjkim if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15) 526207340Sjkim return REGNO_VAX_R0 + (num - DWARF_VAX_R0); 527207340Sjkim if (num == DWARF_VAX_PSW) 528207340Sjkim return REGNO_VAX_PSW; 529207340Sjkim return LAST_REGISTER + 1; 530207340Sjkim } 531207340Sjkim 532207340Sjkim bool validRegister(int num) const { 533207340Sjkim return num >= 0 && num <= LAST_RESTORE_REG; 534207340Sjkim } 535207340Sjkim 536207340Sjkim uint64_t getRegister(int num) const { 537207340Sjkim assert(validRegister(num)); 538207340Sjkim return reg[num]; 539207340Sjkim } 540207340Sjkim 541207340Sjkim void setRegister(int num, uint64_t value) { 542207340Sjkim assert(validRegister(num)); 543207340Sjkim reg[num] = value; 544207340Sjkim } 545207340Sjkim 546207340Sjkim uint64_t getIP() const { return reg[REGNO_VAX_R15]; } 547207340Sjkim 548207340Sjkim void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; } 549207340Sjkim 550207340Sjkim uint64_t getSP() const { return reg[REGNO_VAX_R14]; } 551207340Sjkim 552207340Sjkim void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; } 553207340Sjkim 554207340Sjkim bool validFloatVectorRegister(int num) const { 555207340Sjkim return false; 556207340Sjkim } 557207340Sjkim 558207340Sjkim void copyFloatVectorRegister(int num, uint64_t addr_) { 559207340Sjkim } 560207340Sjkim 561207340Sjkim __dso_hidden void jumpto() const __dead; 562207340Sjkim 563207340Sjkimprivate: 564207340Sjkim uint32_t reg[REGNO_VAX_PSW + 1]; 565207340Sjkim}; 566207340Sjkim 567207340Sjkimenum { 568207340Sjkim DWARF_M68K_A0 = 0, 569213806Sjkim DWARF_M68K_A7 = 7, 570207340Sjkim DWARF_M68K_D0 = 8, 571207340Sjkim DWARF_M68K_D7 = 15, 572207340Sjkim DWARF_M68K_FP0 = 16, 573207340Sjkim DWARF_M68K_FP7 = 23, 574 DWARF_M68K_PC = 24, 575 // DWARF pseudo-register that is an alternate that may be used 576 // for the return address. 577 DWARF_M68K_ALT_PC = 25, 578 579 REGNO_M68K_A0 = 0, 580 REGNO_M68K_A7 = 7, 581 REGNO_M68K_D0 = 8, 582 REGNO_M68K_D7 = 15, 583 REGNO_M68K_PC = 16, 584 REGNO_M68K_FP0 = 17, 585 REGNO_M68K_FP7 = 24, 586}; 587 588class Registers_M68K { 589public: 590 enum { 591 LAST_REGISTER = REGNO_M68K_FP7, 592 LAST_RESTORE_REG = REGNO_M68K_FP7, 593 RETURN_OFFSET = 0, 594 RETURN_MASK = 0, 595 }; 596 597 __dso_hidden Registers_M68K(); 598 599 static int dwarf2regno(int num) { 600 if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7) 601 return REGNO_M68K_A0 + (num - DWARF_M68K_A0); 602 if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7) 603 return REGNO_M68K_D0 + (num - DWARF_M68K_D0); 604 if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7) 605 return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0); 606 if (num == DWARF_M68K_PC || num == DWARF_M68K_ALT_PC) 607 return REGNO_M68K_PC; 608 return LAST_REGISTER + 1; 609 } 610 611 bool validRegister(int num) const { 612 return num >= 0 && num <= REGNO_M68K_PC; 613 } 614 615 uint64_t getRegister(int num) const { 616 assert(validRegister(num)); 617 return reg[num]; 618 } 619 620 void setRegister(int num, uint64_t value) { 621 assert(validRegister(num)); 622 reg[num] = value; 623 } 624 625 uint64_t getIP() const { return reg[REGNO_M68K_PC]; } 626 627 void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; } 628 629 uint64_t getSP() const { return reg[REGNO_M68K_A7]; } 630 631 void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; } 632 633 bool validFloatVectorRegister(int num) const { 634 return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7; 635 } 636 637 void copyFloatVectorRegister(int num, uint64_t addr_) { 638 assert(validFloatVectorRegister(num)); 639 const void *addr = reinterpret_cast<const void *>(addr_); 640 memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0])); 641 } 642 643 __dso_hidden void jumpto() const __dead; 644 645private: 646 typedef uint32_t fpreg_t[3]; 647 648 uint32_t reg[REGNO_M68K_PC + 1]; 649 uint32_t dummy; 650 fpreg_t fpreg[8]; 651}; 652 653enum { 654 DWARF_SH3_R0 = 0, 655 DWARF_SH3_R15 = 15, 656 DWARF_SH3_PC = 16, 657 DWARF_SH3_PR = 17, 658 DWARF_SH3_GBR = 18, 659 DWARF_SH3_MACH = 20, 660 DWARF_SH3_MACL = 21, 661 DWARF_SH3_SR = 22, 662 663 REGNO_SH3_R0 = 0, 664 REGNO_SH3_R15 = 15, 665 REGNO_SH3_PC = 16, 666 REGNO_SH3_PR = 17, 667 REGNO_SH3_GBR = 18, 668 REGNO_SH3_MACH = 20, 669 REGNO_SH3_MACL = 21, 670 REGNO_SH3_SR = 22, 671}; 672 673class Registers_SH3 { 674public: 675 enum { 676 LAST_REGISTER = REGNO_SH3_SR, 677 LAST_RESTORE_REG = REGNO_SH3_SR, 678 RETURN_OFFSET = 0, 679 RETURN_MASK = 0, 680 }; 681 682 __dso_hidden Registers_SH3(); 683 684 static int dwarf2regno(int num) { 685 if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15) 686 return REGNO_SH3_R0 + (num - DWARF_SH3_R0); 687 switch (num) { 688 case DWARF_SH3_PC: 689 return REGNO_SH3_PC; 690 case DWARF_SH3_PR: 691 return REGNO_SH3_PR; 692 case DWARF_SH3_GBR: 693 return REGNO_SH3_GBR; 694 case DWARF_SH3_MACH: 695 return REGNO_SH3_MACH; 696 case DWARF_SH3_MACL: 697 return REGNO_SH3_MACL; 698 case DWARF_SH3_SR: 699 return REGNO_SH3_SR; 700 default: 701 return LAST_REGISTER + 1; 702 } 703 } 704 705 bool validRegister(int num) const { 706 return (num >= 0 && num <= REGNO_SH3_GBR) || 707 (num >= REGNO_SH3_MACH && num <= REGNO_SH3_SR); 708 } 709 710 uint64_t getRegister(int num) const { 711 assert(validRegister(num)); 712 return reg[num]; 713 } 714 715 void setRegister(int num, uint64_t value) { 716 assert(validRegister(num)); 717 reg[num] = value; 718 } 719 720 uint64_t getIP() const { return reg[REGNO_SH3_PC]; } 721 722 void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; } 723 724 uint64_t getSP() const { return reg[REGNO_SH3_R15]; } 725 726 void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; } 727 728 bool validFloatVectorRegister(int num) const { return false; } 729 730 void copyFloatVectorRegister(int num, uint64_t addr_) {} 731 732 __dso_hidden void jumpto() const __dead; 733 734private: 735 uint32_t reg[REGNO_SH3_SR + 1]; 736}; 737 738enum { 739 DWARF_SPARC64_R0 = 0, 740 DWARF_SPARC64_R31 = 31, 741 DWARF_SPARC64_PC = 32, 742 743 REGNO_SPARC64_R0 = 0, 744 REGNO_SPARC64_R14 = 14, 745 REGNO_SPARC64_R15 = 15, 746 REGNO_SPARC64_R31 = 31, 747 REGNO_SPARC64_PC = 32, 748}; 749 750class Registers_SPARC64 { 751public: 752 enum { 753 LAST_REGISTER = REGNO_SPARC64_PC, 754 LAST_RESTORE_REG = REGNO_SPARC64_PC, 755 RETURN_OFFSET = 8, 756 RETURN_MASK = 0, 757 }; 758 typedef uint64_t reg_t; 759 760 __dso_hidden Registers_SPARC64(); 761 762 static int dwarf2regno(int num) { 763 if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31) 764 return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0); 765 if (num == DWARF_SPARC64_PC) 766 return REGNO_SPARC64_PC; 767 return LAST_REGISTER + 1; 768 } 769 770 bool validRegister(int num) const { 771 return num >= 0 && num <= REGNO_SPARC64_PC; 772 } 773 774 uint64_t getRegister(int num) const { 775 assert(validRegister(num)); 776 return reg[num]; 777 } 778 779 void setRegister(int num, uint64_t value) { 780 assert(validRegister(num)); 781 reg[num] = value; 782 } 783 784 uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; } 785 786 void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; } 787 788 uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; } 789 790 void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; } 791 792 bool validFloatVectorRegister(int num) const { return false; } 793 794 void copyFloatVectorRegister(int num, uint64_t addr_) {} 795 796 __dso_hidden void jumpto() const __dead; 797 798private: 799 uint64_t reg[REGNO_SPARC64_PC + 1]; 800}; 801 802enum { 803 DWARF_SPARC_R0 = 0, 804 DWARF_SPARC_R31 = 31, 805 DWARF_SPARC_PC = 32, 806 807 REGNO_SPARC_R0 = 0, 808 REGNO_SPARC_R14 = 14, 809 REGNO_SPARC_R15 = 15, 810 REGNO_SPARC_R31 = 31, 811 REGNO_SPARC_PC = 32, 812}; 813 814class Registers_SPARC { 815public: 816 enum { 817 LAST_REGISTER = REGNO_SPARC_PC, 818 LAST_RESTORE_REG = REGNO_SPARC_PC, 819 RETURN_OFFSET = 8, 820 RETURN_MASK = 0, 821 }; 822 typedef uint32_t reg_t; 823 824 __dso_hidden Registers_SPARC(); 825 826 static int dwarf2regno(int num) { 827 if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31) 828 return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0); 829 if (num == DWARF_SPARC_PC) 830 return REGNO_SPARC_PC; 831 return LAST_REGISTER + 1; 832 } 833 834 bool validRegister(int num) const { 835 return num >= 0 && num <= REGNO_SPARC_PC; 836 } 837 838 uint64_t getRegister(int num) const { 839 assert(validRegister(num)); 840 return reg[num]; 841 } 842 843 void setRegister(int num, uint64_t value) { 844 assert(validRegister(num)); 845 reg[num] = value; 846 } 847 848 uint64_t getIP() const { return reg[REGNO_SPARC_PC]; } 849 850 void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; } 851 852 uint64_t getSP() const { return reg[REGNO_SPARC_R14]; } 853 854 void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; } 855 856 bool validFloatVectorRegister(int num) const { return false; } 857 858 void copyFloatVectorRegister(int num, uint64_t addr_) {} 859 860 __dso_hidden void jumpto() const __dead; 861 862private: 863 uint32_t reg[REGNO_SPARC_PC + 1]; 864}; 865 866enum { 867 DWARF_ALPHA_R0 = 0, 868 DWARF_ALPHA_R30 = 30, 869 DWARF_ALPHA_F0 = 32, 870 DWARF_ALPHA_F30 = 62, 871 DWARF_ALPHA_SIGRETURN = 64, 872 873 REGNO_ALPHA_R0 = 0, 874 REGNO_ALPHA_R26 = 26, 875 REGNO_ALPHA_R30 = 30, 876 REGNO_ALPHA_PC = 31, 877 REGNO_ALPHA_F0 = 32, 878 REGNO_ALPHA_F30 = 62, 879 REGNO_ALPHA_SIGRETURN = 64, 880}; 881 882class Registers_Alpha { 883public: 884 enum { 885 LAST_REGISTER = REGNO_ALPHA_SIGRETURN, 886 LAST_RESTORE_REG = REGNO_ALPHA_SIGRETURN, 887 RETURN_OFFSET = 0, 888 RETURN_MASK = 0, 889 }; 890 891 __dso_hidden Registers_Alpha(); 892 893 static int dwarf2regno(int num) { return num; } 894 895 bool validRegister(int num) const { 896 return (num >= 0 && num <= REGNO_ALPHA_PC) || 897 num == REGNO_ALPHA_SIGRETURN; 898 } 899 900 uint64_t getRegister(int num) const { 901 assert(validRegister(num)); 902 if (num == REGNO_ALPHA_SIGRETURN) 903 return sigreturn_reg; 904 else 905 return reg[num]; 906 } 907 908 void setRegister(int num, uint64_t value) { 909 assert(validRegister(num)); 910 if (num == REGNO_ALPHA_SIGRETURN) 911 sigreturn_reg = value; 912 else 913 reg[num] = value; 914 } 915 916 uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; } 917 918 void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; } 919 920 uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; } 921 922 void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; } 923 924 bool validFloatVectorRegister(int num) const { 925 return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30; 926 } 927 928 void copyFloatVectorRegister(int num, uint64_t addr_) { 929 assert(validFloatVectorRegister(num)); 930 const void *addr = reinterpret_cast<const void *>(addr_); 931 memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0])); 932 } 933 934 __dso_hidden void jumpto() const __dead; 935 936private: 937 uint64_t reg[REGNO_ALPHA_PC + 1]; 938 uint64_t fpreg[31]; 939 uint64_t sigreturn_reg; 940}; 941 942enum { 943 DWARF_HPPA_R1 = 1, 944 DWARF_HPPA_R31 = 31, 945 DWARF_HPPA_FR4L = 32, 946 DWARF_HPPA_FR31H = 87, 947 DWARF_HPPA_SIGRETURN = 89, 948 949 REGNO_HPPA_PC = 0, 950 REGNO_HPPA_R1 = 1, 951 REGNO_HPPA_R2 = 2, 952 REGNO_HPPA_R30 = 30, 953 REGNO_HPPA_R31 = 31, 954 REGNO_HPPA_FR4L = 32, 955 REGNO_HPPA_FR31H = 87, 956 REGNO_HPPA_SIGRETURN = 89, 957}; 958 959class Registers_HPPA { 960public: 961 enum { 962 LAST_REGISTER = REGNO_HPPA_FR31H, 963 LAST_RESTORE_REG = REGNO_HPPA_SIGRETURN, 964 RETURN_OFFSET = 0, 965 RETURN_MASK = 3, 966 }; 967 968 __dso_hidden Registers_HPPA(); 969 970 static int dwarf2regno(int num) { 971 if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31) 972 return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1); 973 if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H) 974 return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H); 975 if (num == DWARF_HPPA_SIGRETURN) 976 return REGNO_HPPA_SIGRETURN; 977 return LAST_REGISTER + 1; 978 } 979 980 bool validRegister(int num) const { 981 return (num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31) || 982 num == REGNO_HPPA_SIGRETURN; 983 } 984 985 uint64_t getRegister(int num) const { 986 assert(validRegister(num)); 987 if (num == REGNO_HPPA_SIGRETURN) 988 return sigreturn_reg; 989 else 990 return reg[num]; 991 } 992 993 void setRegister(int num, uint64_t value) { 994 assert(validRegister(num)); 995 if (num == REGNO_HPPA_SIGRETURN) 996 sigreturn_reg = value; 997 else 998 reg[num] = value; 999 } 1000 1001 uint64_t getIP() const { return reg[REGNO_HPPA_PC]; } 1002 1003 void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; } 1004 1005 uint64_t getSP() const { return reg[REGNO_HPPA_R30]; } 1006 1007 void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; } 1008 1009 bool validFloatVectorRegister(int num) const { 1010 return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H; 1011 } 1012 1013 void copyFloatVectorRegister(int num, uint64_t addr_) { 1014 assert(validFloatVectorRegister(num)); 1015 const void *addr = reinterpret_cast<const void *>(addr_); 1016 memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0])); 1017 } 1018 1019 __dso_hidden void jumpto() const __dead; 1020 1021private: 1022 uint32_t reg[REGNO_HPPA_R31 + 1]; 1023 uint32_t fpreg[56]; 1024 uint32_t sigreturn_reg; 1025}; 1026 1027enum { 1028 DWARF_MIPS_R1 = 0, 1029 DWARF_MIPS_R31 = 31, 1030 DWARF_MIPS_F0 = 32, 1031 DWARF_MIPS_F31 = 63, 1032 // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and 1033 // signal handler return address. 1034 DWARF_MIPS_MDHI = 64, 1035 DWARF_MIPS_MDLO = 65, 1036 DWARF_MIPS_SIGRETURN = 66, 1037 1038 REGNO_MIPS_PC = 0, 1039 REGNO_MIPS_R1 = 0, 1040 REGNO_MIPS_R29 = 29, 1041 REGNO_MIPS_R31 = 31, 1042 REGNO_MIPS_F0 = 33, 1043 REGNO_MIPS_F31 = 64, 1044 // these live in other_reg[] 1045 REGNO_MIPS_MDHI = 65, 1046 REGNO_MIPS_MDLO = 66, 1047 REGNO_MIPS_SIGRETURN = 67 1048}; 1049 1050class Registers_MIPS { 1051public: 1052 enum { 1053 LAST_REGISTER = REGNO_MIPS_SIGRETURN, 1054 LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN, 1055 RETURN_OFFSET = 0, 1056 RETURN_MASK = 0, 1057 }; 1058 1059 __dso_hidden Registers_MIPS(); 1060 1061 static int dwarf2regno(int num) { 1062 if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31) 1063 return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1); 1064 if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31) 1065 return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0); 1066 if (num >= DWARF_MIPS_MDHI && num <= DWARF_MIPS_SIGRETURN) 1067 return REGNO_MIPS_MDHI + (num - DWARF_MIPS_MDHI); 1068 return LAST_REGISTER + 1; 1069 } 1070 1071 bool validRegister(int num) const { 1072 return (num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31) || 1073 (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN); 1074 } 1075 1076 uint64_t getRegister(int num) const { 1077 assert(validRegister(num)); 1078 if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN) 1079 return other_reg[num - REGNO_MIPS_MDHI]; 1080 return reg[num]; 1081 } 1082 1083 void setRegister(int num, uint64_t value) { 1084 assert(validRegister(num)); 1085 if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN) 1086 other_reg[num - REGNO_MIPS_MDHI] = value; 1087 else 1088 reg[num] = value; 1089 } 1090 1091 uint64_t getIP() const { return reg[REGNO_MIPS_PC]; } 1092 1093 void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; } 1094 1095 uint64_t getSP() const { return reg[REGNO_MIPS_R29]; } 1096 1097 void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; } 1098 1099 bool validFloatVectorRegister(int num) const { 1100 return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31; 1101 } 1102 1103 void copyFloatVectorRegister(int num, uint64_t addr_) { 1104 assert(validFloatVectorRegister(num)); 1105 const void *addr = reinterpret_cast<const void *>(addr_); 1106 memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0])); 1107 } 1108 1109 __dso_hidden void jumpto() const __dead; 1110 1111private: 1112 uint32_t reg[REGNO_MIPS_R31 + 1]; 1113 uint64_t fpreg[32]; 1114 uint32_t other_reg[3]; 1115}; 1116 1117enum { 1118 DWARF_MIPS64_R1 = 0, 1119 DWARF_MIPS64_R31 = 31, 1120 DWARF_MIPS64_F0 = 32, 1121 DWARF_MIPS64_F31 = 63, 1122 // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and 1123 // signal handler return address. 1124 DWARF_MIPS64_MDHI = 64, 1125 DWARF_MIPS64_MDLO = 65, 1126 DWARF_MIPS64_SIGRETURN = 66, 1127 1128 REGNO_MIPS64_PC = 0, 1129 REGNO_MIPS64_R1 = 0, 1130 REGNO_MIPS64_R29 = 29, 1131 REGNO_MIPS64_R31 = 31, 1132 REGNO_MIPS64_F0 = 33, 1133 REGNO_MIPS64_F31 = 64, 1134 // these live in other_reg[] 1135 REGNO_MIPS64_MDHI = 65, 1136 REGNO_MIPS64_MDLO = 66, 1137 REGNO_MIPS64_SIGRETURN = 67 1138}; 1139 1140class Registers_MIPS64 { 1141public: 1142 enum { 1143 LAST_REGISTER = REGNO_MIPS_SIGRETURN, 1144 LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN, 1145 RETURN_OFFSET = 0, 1146 RETURN_MASK = 0, 1147 }; 1148 1149 __dso_hidden Registers_MIPS64(); 1150 1151 static int dwarf2regno(int num) { 1152 if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31) 1153 return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1); 1154 if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31) 1155 return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0); 1156 if (num >= DWARF_MIPS64_MDHI && num <= DWARF_MIPS64_SIGRETURN) 1157 return REGNO_MIPS64_MDHI + (num - DWARF_MIPS64_MDHI); 1158 return LAST_REGISTER + 1; 1159 } 1160 1161 bool validRegister(int num) const { 1162 return (num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31) || 1163 (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN); 1164 } 1165 1166 uint64_t getRegister(int num) const { 1167 assert(validRegister(num)); 1168 if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN) 1169 return other_reg[num - REGNO_MIPS64_MDHI]; 1170 return reg[num]; 1171 } 1172 1173 void setRegister(int num, uint64_t value) { 1174 assert(validRegister(num)); 1175 if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN) 1176 other_reg[num - REGNO_MIPS64_MDHI] = value; 1177 else 1178 reg[num] = value; 1179 } 1180 1181 uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; } 1182 1183 void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; } 1184 1185 uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; } 1186 1187 void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; } 1188 1189 bool validFloatVectorRegister(int num) const { 1190 return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31; 1191 } 1192 1193 void copyFloatVectorRegister(int num, uint64_t addr_) { 1194 assert(validFloatVectorRegister(num)); 1195 const void *addr = reinterpret_cast<const void *>(addr_); 1196 memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0])); 1197 } 1198 1199 __dso_hidden void jumpto() const __dead; 1200 1201private: 1202 uint64_t reg[REGNO_MIPS64_R31 + 1]; 1203 uint64_t fpreg[32]; 1204 uint64_t other_reg[3]; 1205}; 1206 1207enum { 1208 DWARF_OR1K_R0 = 0, 1209 DWARF_OR1K_SP = 1, 1210 DWARF_OR1K_LR = 9, 1211 DWARF_OR1K_R31 = 31, 1212 DWARF_OR1K_FPCSR = 32, 1213 1214 REGNO_OR1K_R0 = 0, 1215 REGNO_OR1K_SP = 1, 1216 REGNO_OR1K_LR = 9, 1217 REGNO_OR1K_R31 = 31, 1218 REGNO_OR1K_FPCSR = 32, 1219}; 1220 1221class Registers_or1k { 1222public: 1223 enum { 1224 LAST_REGISTER = REGNO_OR1K_FPCSR, 1225 LAST_RESTORE_REG = REGNO_OR1K_FPCSR, 1226 RETURN_OFFSET = 0, 1227 RETURN_MASK = 0, 1228 }; 1229 1230 __dso_hidden Registers_or1k(); 1231 1232 static int dwarf2regno(int num) { 1233 if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31) 1234 return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0); 1235 if (num == DWARF_OR1K_FPCSR) 1236 return REGNO_OR1K_FPCSR; 1237 return LAST_REGISTER + 1; 1238 } 1239 1240 bool validRegister(int num) const { 1241 return num >= 0 && num <= LAST_RESTORE_REG; 1242 } 1243 1244 uint64_t getRegister(int num) const { 1245 assert(validRegister(num)); 1246 return reg[num]; 1247 } 1248 1249 void setRegister(int num, uint64_t value) { 1250 assert(validRegister(num)); 1251 reg[num] = value; 1252 } 1253 1254 uint64_t getIP() const { return reg[REGNO_OR1K_LR]; } 1255 1256 void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; } 1257 1258 uint64_t getSP() const { return reg[REGNO_OR1K_SP]; } 1259 1260 void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; } 1261 1262 bool validFloatVectorRegister(int num) const { 1263 return false; 1264 } 1265 1266 void copyFloatVectorRegister(int num, uint64_t addr_) { 1267 } 1268 1269 __dso_hidden void jumpto() const __dead; 1270 1271private: 1272 uint32_t reg[REGNO_OR1K_FPCSR + 1]; 1273}; 1274 1275#if __i386__ 1276typedef Registers_x86 NativeUnwindRegisters; 1277#elif __x86_64__ 1278typedef Registers_x86_64 NativeUnwindRegisters; 1279#elif __powerpc__ 1280typedef Registers_ppc32 NativeUnwindRegisters; 1281#elif __aarch64__ 1282typedef Registers_aarch64 NativeUnwindRegisters; 1283#elif __arm__ 1284typedef Registers_arm32 NativeUnwindRegisters; 1285#elif __vax__ 1286typedef Registers_vax NativeUnwindRegisters; 1287#elif __m68k__ 1288typedef Registers_M68K NativeUnwindRegisters; 1289#elif __mips_n64 || __mips_n32 1290typedef Registers_MIPS64 NativeUnwindRegisters; 1291#elif __mips__ 1292typedef Registers_MIPS NativeUnwindRegisters; 1293#elif __sh3__ 1294typedef Registers_SH3 NativeUnwindRegisters; 1295#elif __sparc64__ 1296typedef Registers_SPARC64 NativeUnwindRegisters; 1297#elif __sparc__ 1298typedef Registers_SPARC NativeUnwindRegisters; 1299#elif __alpha__ 1300typedef Registers_Alpha NativeUnwindRegisters; 1301#elif __hppa__ 1302typedef Registers_HPPA NativeUnwindRegisters; 1303#elif __or1k__ 1304typedef Registers_or1k NativeUnwindRegisters; 1305#endif 1306} // namespace _Unwind 1307 1308#endif // __REGISTERS_HPP__ 1309