1aa0b96d0Sjoerg //===----------------------------- Registers.hpp --------------------------===// 2aa0b96d0Sjoerg // 3aa0b96d0Sjoerg // The LLVM Compiler Infrastructure 4aa0b96d0Sjoerg // 5aa0b96d0Sjoerg // This file is dual licensed under the MIT and the University of Illinois Open 6aa0b96d0Sjoerg // Source Licenses. See LICENSE.TXT for details. 7aa0b96d0Sjoerg // 8aa0b96d0Sjoerg // 9aa0b96d0Sjoerg // Models register sets for supported processors. 10aa0b96d0Sjoerg // 11aa0b96d0Sjoerg //===----------------------------------------------------------------------===// 12aa0b96d0Sjoerg #ifndef __REGISTERS_HPP__ 13aa0b96d0Sjoerg #define __REGISTERS_HPP__ 14aa0b96d0Sjoerg 15155a9ee6Sjoerg #include <sys/endian.h> 16aa0b96d0Sjoerg #include <cassert> 17aa0b96d0Sjoerg #include <cstdint> 18aa0b96d0Sjoerg 19aa0b96d0Sjoerg namespace _Unwind { 20aa0b96d0Sjoerg 21aa0b96d0Sjoerg enum { 22aa0b96d0Sjoerg REGNO_X86_EAX = 0, 23aa0b96d0Sjoerg REGNO_X86_ECX = 1, 24aa0b96d0Sjoerg REGNO_X86_EDX = 2, 25aa0b96d0Sjoerg REGNO_X86_EBX = 3, 26aa0b96d0Sjoerg REGNO_X86_ESP = 4, 27aa0b96d0Sjoerg REGNO_X86_EBP = 5, 28aa0b96d0Sjoerg REGNO_X86_ESI = 6, 29aa0b96d0Sjoerg REGNO_X86_EDI = 7, 30aa0b96d0Sjoerg REGNO_X86_EIP = 8, 31aa0b96d0Sjoerg }; 32aa0b96d0Sjoerg 33aa0b96d0Sjoerg class Registers_x86 { 34aa0b96d0Sjoerg public: 35aa0b96d0Sjoerg enum { 36aa0b96d0Sjoerg LAST_REGISTER = REGNO_X86_EIP, 37916de6d0Sjoerg LAST_RESTORE_REG = REGNO_X86_EIP, 389788222aSjoerg RETURN_OFFSET = 0, 390282220bSjoerg RETURN_MASK = 0, 40aa0b96d0Sjoerg }; 41aa0b96d0Sjoerg 42aa0b96d0Sjoerg __dso_hidden Registers_x86(); 43aa0b96d0Sjoerg 44aa0b96d0Sjoerg static int dwarf2regno(int num) { return num; } 45aa0b96d0Sjoerg 46aa0b96d0Sjoerg bool validRegister(int num) const { 47aa0b96d0Sjoerg return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI; 48aa0b96d0Sjoerg } 49aa0b96d0Sjoerg 50aa0b96d0Sjoerg uint32_t getRegister(int num) const { 51aa0b96d0Sjoerg assert(validRegister(num)); 52aa0b96d0Sjoerg return reg[num]; 53aa0b96d0Sjoerg } 54aa0b96d0Sjoerg 55aa0b96d0Sjoerg void setRegister(int num, uint32_t value) { 56aa0b96d0Sjoerg assert(validRegister(num)); 57aa0b96d0Sjoerg reg[num] = value; 58aa0b96d0Sjoerg } 59aa0b96d0Sjoerg 60aa0b96d0Sjoerg uint32_t getIP() const { return reg[REGNO_X86_EIP]; } 61aa0b96d0Sjoerg 62aa0b96d0Sjoerg void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; } 63aa0b96d0Sjoerg 64aa0b96d0Sjoerg uint32_t getSP() const { return reg[REGNO_X86_ESP]; } 65aa0b96d0Sjoerg 66aa0b96d0Sjoerg void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; } 67aa0b96d0Sjoerg 68aa0b96d0Sjoerg bool validFloatVectorRegister(int num) const { return false; } 69aa0b96d0Sjoerg 70aa0b96d0Sjoerg void copyFloatVectorRegister(int num, uint32_t addr) { 71aa0b96d0Sjoerg } 72aa0b96d0Sjoerg 73aa0b96d0Sjoerg __dso_hidden void jumpto() const __dead; 74aa0b96d0Sjoerg 75aa0b96d0Sjoerg private: 76aa0b96d0Sjoerg uint32_t reg[REGNO_X86_EIP + 1]; 77aa0b96d0Sjoerg }; 78aa0b96d0Sjoerg 79aa0b96d0Sjoerg enum { 80aa0b96d0Sjoerg REGNO_X86_64_RAX = 0, 81aa0b96d0Sjoerg REGNO_X86_64_RDX = 1, 82aa0b96d0Sjoerg REGNO_X86_64_RCX = 2, 83aa0b96d0Sjoerg REGNO_X86_64_RBX = 3, 84aa0b96d0Sjoerg REGNO_X86_64_RSI = 4, 85aa0b96d0Sjoerg REGNO_X86_64_RDI = 5, 86aa0b96d0Sjoerg REGNO_X86_64_RBP = 6, 87aa0b96d0Sjoerg REGNO_X86_64_RSP = 7, 88aa0b96d0Sjoerg REGNO_X86_64_R8 = 8, 89aa0b96d0Sjoerg REGNO_X86_64_R9 = 9, 90aa0b96d0Sjoerg REGNO_X86_64_R10 = 10, 91aa0b96d0Sjoerg REGNO_X86_64_R11 = 11, 92aa0b96d0Sjoerg REGNO_X86_64_R12 = 12, 93aa0b96d0Sjoerg REGNO_X86_64_R13 = 13, 94aa0b96d0Sjoerg REGNO_X86_64_R14 = 14, 95aa0b96d0Sjoerg REGNO_X86_64_R15 = 15, 96aa0b96d0Sjoerg REGNO_X86_64_RIP = 16, 97aa0b96d0Sjoerg }; 98aa0b96d0Sjoerg 99aa0b96d0Sjoerg class Registers_x86_64 { 100aa0b96d0Sjoerg public: 101aa0b96d0Sjoerg enum { 102aa0b96d0Sjoerg LAST_REGISTER = REGNO_X86_64_RIP, 103916de6d0Sjoerg LAST_RESTORE_REG = REGNO_X86_64_RIP, 1049788222aSjoerg RETURN_OFFSET = 0, 1050282220bSjoerg RETURN_MASK = 0, 106aa0b96d0Sjoerg }; 107aa0b96d0Sjoerg 108aa0b96d0Sjoerg __dso_hidden Registers_x86_64(); 109aa0b96d0Sjoerg 110aa0b96d0Sjoerg static int dwarf2regno(int num) { return num; } 111aa0b96d0Sjoerg 112aa0b96d0Sjoerg bool validRegister(int num) const { 113aa0b96d0Sjoerg return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15; 114aa0b96d0Sjoerg } 115aa0b96d0Sjoerg 116aa0b96d0Sjoerg uint64_t getRegister(int num) const { 117aa0b96d0Sjoerg assert(validRegister(num)); 118aa0b96d0Sjoerg return reg[num]; 119aa0b96d0Sjoerg } 120aa0b96d0Sjoerg 121aa0b96d0Sjoerg void setRegister(int num, uint64_t value) { 122aa0b96d0Sjoerg assert(validRegister(num)); 123aa0b96d0Sjoerg reg[num] = value; 124aa0b96d0Sjoerg } 125aa0b96d0Sjoerg 126aa0b96d0Sjoerg uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; } 127aa0b96d0Sjoerg 128aa0b96d0Sjoerg void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; } 129aa0b96d0Sjoerg 130aa0b96d0Sjoerg uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; } 131aa0b96d0Sjoerg 132aa0b96d0Sjoerg void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; } 133aa0b96d0Sjoerg 134aa0b96d0Sjoerg bool validFloatVectorRegister(int num) const { return false; } 135aa0b96d0Sjoerg 136aa0b96d0Sjoerg void copyFloatVectorRegister(int num, uint64_t addr) { 137aa0b96d0Sjoerg } 138aa0b96d0Sjoerg 139aa0b96d0Sjoerg __dso_hidden void jumpto() const __dead; 140aa0b96d0Sjoerg 141aa0b96d0Sjoerg private: 142aa0b96d0Sjoerg uint64_t reg[REGNO_X86_64_RIP + 1]; 143aa0b96d0Sjoerg }; 144aa0b96d0Sjoerg 145aa0b96d0Sjoerg enum { 146aa0b96d0Sjoerg DWARF_PPC32_R0 = 0, 147aa0b96d0Sjoerg DWARF_PPC32_R31 = 31, 148aa0b96d0Sjoerg DWARF_PPC32_F0 = 32, 149aa0b96d0Sjoerg DWARF_PPC32_F31 = 63, 150aa0b96d0Sjoerg DWARF_PPC32_LR = 65, 1512524c512Sthorpej DWARF_PPC32_CTR = 66, 152b238bfcaSjoerg DWARF_PPC32_CR = 70, 1532524c512Sthorpej DWARF_PPC32_XER = 76, 154b238bfcaSjoerg DWARF_PPC32_V0 = 77, 1552524c512Sthorpej DWARF_PPC32_SIGRETURN = 99, 156b238bfcaSjoerg DWARF_PPC32_V31 = 108, 157b238bfcaSjoerg 158aa0b96d0Sjoerg REGNO_PPC32_R0 = 0, 159b238bfcaSjoerg REGNO_PPC32_R1 = 1, 160aa0b96d0Sjoerg REGNO_PPC32_R31 = 31, 161b238bfcaSjoerg REGNO_PPC32_LR = 32, 162b238bfcaSjoerg REGNO_PPC32_CR = 33, 163b238bfcaSjoerg REGNO_PPC32_SRR0 = 34, 164b238bfcaSjoerg 165aa0b96d0Sjoerg REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1, 166aa0b96d0Sjoerg REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31, 167aa0b96d0Sjoerg REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1, 168aa0b96d0Sjoerg REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31, 1692524c512Sthorpej 1702524c512Sthorpej REGNO_PPC32_CTR = REGNO_PPC32_V31 + 1, 1712524c512Sthorpej REGNO_PPC32_XER = REGNO_PPC32_CTR + 1, 1722524c512Sthorpej REGNO_PPC32_SIGRETURN = REGNO_PPC32_XER + 1 173aa0b96d0Sjoerg }; 174aa0b96d0Sjoerg 175aa0b96d0Sjoerg class Registers_ppc32 { 176aa0b96d0Sjoerg public: 177aa0b96d0Sjoerg enum { 1782524c512Sthorpej LAST_REGISTER = REGNO_PPC32_SIGRETURN, 1792524c512Sthorpej LAST_RESTORE_REG = REGNO_PPC32_SIGRETURN, 1809788222aSjoerg RETURN_OFFSET = 0, 1810282220bSjoerg RETURN_MASK = 0, 182aa0b96d0Sjoerg }; 183aa0b96d0Sjoerg 184aa0b96d0Sjoerg __dso_hidden Registers_ppc32(); 185aa0b96d0Sjoerg 186aa0b96d0Sjoerg static int dwarf2regno(int num) { 187aa0b96d0Sjoerg if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31) 188aa0b96d0Sjoerg return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0); 189aa0b96d0Sjoerg if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31) 190aa0b96d0Sjoerg return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0); 191aa0b96d0Sjoerg if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31) 192aa0b96d0Sjoerg return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0); 193b238bfcaSjoerg switch (num) { 194b238bfcaSjoerg case DWARF_PPC32_LR: 195b238bfcaSjoerg return REGNO_PPC32_LR; 196b238bfcaSjoerg case DWARF_PPC32_CR: 197b238bfcaSjoerg return REGNO_PPC32_CR; 1982524c512Sthorpej case DWARF_PPC32_CTR: 1992524c512Sthorpej return REGNO_PPC32_CTR; 2002524c512Sthorpej case DWARF_PPC32_XER: 2012524c512Sthorpej return REGNO_PPC32_XER; 2022524c512Sthorpej case DWARF_PPC32_SIGRETURN: 2032524c512Sthorpej return REGNO_PPC32_SIGRETURN; 204b238bfcaSjoerg default: 205aa0b96d0Sjoerg return LAST_REGISTER + 1; 206aa0b96d0Sjoerg } 207b238bfcaSjoerg } 208aa0b96d0Sjoerg 209aa0b96d0Sjoerg bool validRegister(int num) const { 2102524c512Sthorpej return (num >= 0 && num <= REGNO_PPC32_SRR0) || 2112524c512Sthorpej (num >= REGNO_PPC32_CTR && num <= REGNO_PPC32_SIGRETURN); 212aa0b96d0Sjoerg } 213aa0b96d0Sjoerg 214aa0b96d0Sjoerg uint64_t getRegister(int num) const { 215aa0b96d0Sjoerg assert(validRegister(num)); 2162524c512Sthorpej switch (num) { 2172524c512Sthorpej case REGNO_PPC32_CTR: 2182524c512Sthorpej return ctr_reg; 2192524c512Sthorpej case REGNO_PPC32_XER: 2202524c512Sthorpej return xer_reg; 2212524c512Sthorpej case REGNO_PPC32_SIGRETURN: 2222524c512Sthorpej return sigreturn_reg; 2232524c512Sthorpej default: 224aa0b96d0Sjoerg return reg[num]; 225aa0b96d0Sjoerg } 2262524c512Sthorpej } 227aa0b96d0Sjoerg 228aa0b96d0Sjoerg void setRegister(int num, uint64_t value) { 229aa0b96d0Sjoerg assert(validRegister(num)); 2302524c512Sthorpej switch (num) { 2312524c512Sthorpej case REGNO_PPC32_CTR: 2322524c512Sthorpej ctr_reg = value; 2332524c512Sthorpej break; 2342524c512Sthorpej case REGNO_PPC32_XER: 2352524c512Sthorpej xer_reg = value; 2362524c512Sthorpej break; 2372524c512Sthorpej case REGNO_PPC32_SIGRETURN: 2382524c512Sthorpej sigreturn_reg = value; 2392524c512Sthorpej break; 2402524c512Sthorpej default: 241aa0b96d0Sjoerg reg[num] = value; 242aa0b96d0Sjoerg } 2432524c512Sthorpej } 244aa0b96d0Sjoerg 245aa0b96d0Sjoerg uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; } 246aa0b96d0Sjoerg 247aa0b96d0Sjoerg void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; } 248aa0b96d0Sjoerg 249aa0b96d0Sjoerg uint64_t getSP() const { return reg[REGNO_PPC32_R1]; } 250aa0b96d0Sjoerg 251aa0b96d0Sjoerg void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; } 252aa0b96d0Sjoerg 253aa0b96d0Sjoerg bool validFloatVectorRegister(int num) const { 254aa0b96d0Sjoerg return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) || 255aa0b96d0Sjoerg (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31); 256aa0b96d0Sjoerg } 257aa0b96d0Sjoerg 258aa0b96d0Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 259aa0b96d0Sjoerg const void *addr = reinterpret_cast<const void *>(addr_); 260aa0b96d0Sjoerg if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) 261aa0b96d0Sjoerg memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0])); 262aa0b96d0Sjoerg else 263aa0b96d0Sjoerg memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0])); 264aa0b96d0Sjoerg } 265aa0b96d0Sjoerg 266aa0b96d0Sjoerg __dso_hidden void jumpto() const __dead; 267aa0b96d0Sjoerg 268aa0b96d0Sjoerg private: 269aa0b96d0Sjoerg struct vecreg_t { 270aa0b96d0Sjoerg uint64_t low, high; 271aa0b96d0Sjoerg }; 272aa0b96d0Sjoerg uint32_t reg[REGNO_PPC32_SRR0 + 1]; 273b238bfcaSjoerg uint32_t dummy; 274aa0b96d0Sjoerg uint64_t fpreg[32]; 275aa0b96d0Sjoerg vecreg_t vecreg[64]; 2762524c512Sthorpej uint32_t ctr_reg; 2772524c512Sthorpej uint32_t xer_reg; 2782524c512Sthorpej uint32_t sigreturn_reg; 279aa0b96d0Sjoerg }; 280aa0b96d0Sjoerg 281eb98b3ccSmatt enum { 282aa37019dSmatt DWARF_AARCH64_X0 = 0, 283aa37019dSmatt DWARF_AARCH64_X30 = 30, 284aa37019dSmatt DWARF_AARCH64_SP = 31, 285aa37019dSmatt DWARF_AARCH64_V0 = 64, 286aa37019dSmatt DWARF_AARCH64_V31 = 95, 287*ba371b84Sthorpej DWARF_AARCH64_SIGRETURN = 96, 288aa37019dSmatt 289aa37019dSmatt REGNO_AARCH64_X0 = 0, 290aa37019dSmatt REGNO_AARCH64_X30 = 30, 291aa37019dSmatt REGNO_AARCH64_SP = 31, 29228f5faf2Sjoerg REGNO_AARCH64_V0 = 32, 29328f5faf2Sjoerg REGNO_AARCH64_V31 = 63, 294*ba371b84Sthorpej REGNO_AARCH64_SIGRETURN = 64, 295aa37019dSmatt }; 296aa37019dSmatt 297aa37019dSmatt class Registers_aarch64 { 298aa37019dSmatt public: 299aa37019dSmatt enum { 300*ba371b84Sthorpej LAST_RESTORE_REG = REGNO_AARCH64_SIGRETURN, 301*ba371b84Sthorpej LAST_REGISTER = REGNO_AARCH64_SIGRETURN, 302aa37019dSmatt RETURN_OFFSET = 0, 3030282220bSjoerg RETURN_MASK = 0, 304aa37019dSmatt }; 305aa37019dSmatt 306aa37019dSmatt __dso_hidden Registers_aarch64(); 307aa37019dSmatt 308aa37019dSmatt static int dwarf2regno(int num) { 309aa37019dSmatt if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30) 310aa37019dSmatt return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0); 311aa37019dSmatt if (num == DWARF_AARCH64_SP) 312aa37019dSmatt return REGNO_AARCH64_SP; 313aa37019dSmatt if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31) 314aa37019dSmatt return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0); 315*ba371b84Sthorpej if (num == DWARF_AARCH64_SIGRETURN) 316*ba371b84Sthorpej return REGNO_AARCH64_SIGRETURN; 317aa37019dSmatt return LAST_REGISTER + 1; 318aa37019dSmatt } 319aa37019dSmatt 320aa37019dSmatt bool validRegister(int num) const { 321*ba371b84Sthorpej return (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_SP) || 322*ba371b84Sthorpej num == DWARF_AARCH64_SIGRETURN; 323aa37019dSmatt } 324aa37019dSmatt 325aa37019dSmatt uint64_t getRegister(int num) const { 326aa37019dSmatt assert(validRegister(num)); 327*ba371b84Sthorpej if (reg == REGNO_AARCH64_SIGRETURN) 328*ba371b84Sthorpej return sigreturn_reg; 329aa37019dSmatt return reg[num]; 330aa37019dSmatt } 331aa37019dSmatt 332aa37019dSmatt void setRegister(int num, uint64_t value) { 333aa37019dSmatt assert(validRegister(num)); 334*ba371b84Sthorpej if (reg == REGNO_AARCH64_SIGRETURN) 335*ba371b84Sthorpej sigreturn_reg = value; 336*ba371b84Sthorpej else 337aa37019dSmatt reg[num] = value; 338aa37019dSmatt } 339aa37019dSmatt 340aa37019dSmatt uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; } 341aa37019dSmatt 342aa37019dSmatt void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; } 343aa37019dSmatt 344aa37019dSmatt uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; } 345aa37019dSmatt 346aa37019dSmatt void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; } 347aa37019dSmatt 348aa37019dSmatt bool validFloatVectorRegister(int num) const { 349aa37019dSmatt return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31); 350aa37019dSmatt } 351aa37019dSmatt 352aa37019dSmatt void copyFloatVectorRegister(int num, uint64_t addr_) { 353aa37019dSmatt const void *addr = reinterpret_cast<const void *>(addr_); 35428f5faf2Sjoerg memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, 16); 355aa37019dSmatt } 356aa37019dSmatt 357aa37019dSmatt __dso_hidden void jumpto() const __dead; 358aa37019dSmatt 359aa37019dSmatt private: 36028f5faf2Sjoerg uint64_t reg[REGNO_AARCH64_SP + 1]; 36128f5faf2Sjoerg uint64_t vecreg[64]; 362*ba371b84Sthorpej uint64_t sigreturn_reg; 363aa37019dSmatt }; 364aa37019dSmatt 365aa37019dSmatt enum { 366eb98b3ccSmatt DWARF_ARM32_R0 = 0, 367eb98b3ccSmatt DWARF_ARM32_R15 = 15, 368eb98b3ccSmatt DWARF_ARM32_SPSR = 128, 369155a9ee6Sjoerg DWARF_ARM32_S0 = 64, 3708026a450Srin DWARF_ARM32_S31 = 95, 371bdd3372bSjoerg DWARF_ARM32_D0 = 256, 372eb98b3ccSmatt DWARF_ARM32_D31 = 287, 373eb98b3ccSmatt REGNO_ARM32_R0 = 0, 374eb98b3ccSmatt REGNO_ARM32_SP = 13, 375eb98b3ccSmatt REGNO_ARM32_R15 = 15, 376eb98b3ccSmatt REGNO_ARM32_SPSR = 16, 377bdd3372bSjoerg REGNO_ARM32_D0 = 17, 378bdd3372bSjoerg REGNO_ARM32_D15 = 32, 379bdd3372bSjoerg REGNO_ARM32_D31 = 48, 380155a9ee6Sjoerg REGNO_ARM32_S0 = 49, 3818026a450Srin REGNO_ARM32_S31 = 80, 382eb98b3ccSmatt }; 383eb98b3ccSmatt 3841a44aed1Srin #define FLAGS_VFPV2_USED 0x1 3851a44aed1Srin #define FLAGS_VFPV3_USED 0x2 3861a44aed1Srin #define FLAGS_LEGACY_VFPV2_REGNO 0x4 3871a44aed1Srin #define FLAGS_EXTENDED_VFPV2_REGNO 0x8 3881a44aed1Srin 389eb98b3ccSmatt class Registers_arm32 { 390eb98b3ccSmatt public: 391eb98b3ccSmatt enum { 3921b5786f9Srin LAST_REGISTER = REGNO_ARM32_S31, 3931b5786f9Srin LAST_RESTORE_REG = REGNO_ARM32_S31, 3949788222aSjoerg RETURN_OFFSET = 0, 3950282220bSjoerg RETURN_MASK = 0, 396eb98b3ccSmatt }; 397eb98b3ccSmatt 398eb98b3ccSmatt __dso_hidden Registers_arm32(); 399eb98b3ccSmatt 400eb98b3ccSmatt static int dwarf2regno(int num) { 401eb98b3ccSmatt if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15) 402eb98b3ccSmatt return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0); 403eb98b3ccSmatt if (num == DWARF_ARM32_SPSR) 404eb98b3ccSmatt return REGNO_ARM32_SPSR; 405bdd3372bSjoerg if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31) 406bdd3372bSjoerg return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0); 40785f18f75Srin if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31) 408155a9ee6Sjoerg return REGNO_ARM32_S0 + (num - DWARF_ARM32_S0); 409eb98b3ccSmatt return LAST_REGISTER + 1; 410eb98b3ccSmatt } 411eb98b3ccSmatt 412eb98b3ccSmatt bool validRegister(int num) const { 413bdd3372bSjoerg return num >= 0 && num <= REGNO_ARM32_SPSR; 414eb98b3ccSmatt } 415eb98b3ccSmatt 416eb98b3ccSmatt uint64_t getRegister(int num) const { 417eb98b3ccSmatt assert(validRegister(num)); 418eb98b3ccSmatt return reg[num]; 419eb98b3ccSmatt } 420eb98b3ccSmatt 421eb98b3ccSmatt void setRegister(int num, uint64_t value) { 422eb98b3ccSmatt assert(validRegister(num)); 423eb98b3ccSmatt reg[num] = value; 424eb98b3ccSmatt } 425eb98b3ccSmatt 426eb98b3ccSmatt uint64_t getIP() const { return reg[REGNO_ARM32_R15]; } 427eb98b3ccSmatt 428eb98b3ccSmatt void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; } 429eb98b3ccSmatt 430eb98b3ccSmatt uint64_t getSP() const { return reg[REGNO_ARM32_SP]; } 431eb98b3ccSmatt 432eb98b3ccSmatt void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; } 433eb98b3ccSmatt 434eb98b3ccSmatt bool validFloatVectorRegister(int num) const { 435155a9ee6Sjoerg return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31); 436eb98b3ccSmatt } 437eb98b3ccSmatt 438eb98b3ccSmatt void copyFloatVectorRegister(int num, uint64_t addr_) { 439d03fef5bSrin assert(validFloatVectorRegister(num)); 440155a9ee6Sjoerg const void *addr = reinterpret_cast<const void *>(addr_); 441155a9ee6Sjoerg if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) { 4421b5786f9Srin /* 4431b5786f9Srin * XXX 4441b5786f9Srin * There are two numbering schemes for VFPv2 registers: s0-s31 4451b5786f9Srin * (used by GCC) and d0-d15 (used by LLVM). We won't support both 4461b5786f9Srin * schemes simultaneously in a same frame. 4471b5786f9Srin */ 4481b5786f9Srin assert((flags & FLAGS_EXTENDED_VFPV2_REGNO) == 0); 4491b5786f9Srin flags |= FLAGS_LEGACY_VFPV2_REGNO; 45085f18f75Srin if ((flags & FLAGS_VFPV2_USED) == 0) { 45185f18f75Srin lazyVFPv2(); 45285f18f75Srin flags |= FLAGS_VFPV2_USED; 453155a9ee6Sjoerg } 454155a9ee6Sjoerg /* 455155a9ee6Sjoerg * Emulate single precision register as half of the 456155a9ee6Sjoerg * corresponding double register. 457155a9ee6Sjoerg */ 458155a9ee6Sjoerg int dnum = (num - REGNO_ARM32_S0) / 2; 459155a9ee6Sjoerg int part = (num - REGNO_ARM32_S0) % 2; 460155a9ee6Sjoerg #if _BYTE_ORDER == _BIG_ENDIAN 461155a9ee6Sjoerg part = 1 - part; 462155a9ee6Sjoerg #endif 463c2f619e8Srin memcpy((uint8_t *)(fpreg + dnum) + part * sizeof(fpreg[0]) / 2, 464155a9ee6Sjoerg addr, sizeof(fpreg[0]) / 2); 465994a5fb3Srin } else { 466bdd3372bSjoerg if (num <= REGNO_ARM32_D15) { 4671b5786f9Srin /* 4681b5786f9Srin * XXX 4691b5786f9Srin * See XXX comment above. 4701b5786f9Srin */ 4711b5786f9Srin assert((flags & FLAGS_LEGACY_VFPV2_REGNO) == 0); 4721b5786f9Srin flags |= FLAGS_EXTENDED_VFPV2_REGNO; 47385f18f75Srin if ((flags & FLAGS_VFPV2_USED) == 0) { 47485f18f75Srin lazyVFPv2(); 47585f18f75Srin flags |= FLAGS_VFPV2_USED; 476bdd3372bSjoerg } 477bdd3372bSjoerg } else { 47885f18f75Srin if ((flags & FLAGS_VFPV3_USED) == 0) { 47985f18f75Srin lazyVFPv3(); 48085f18f75Srin flags |= FLAGS_VFPV3_USED; 481bdd3372bSjoerg } 482bdd3372bSjoerg } 483eb98b3ccSmatt memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0])); 484eb98b3ccSmatt } 485994a5fb3Srin } 486eb98b3ccSmatt 48785f18f75Srin __dso_hidden void lazyVFPv2(); 48885f18f75Srin __dso_hidden void lazyVFPv3(); 489eb98b3ccSmatt __dso_hidden void jumpto() const __dead; 490eb98b3ccSmatt 491eb98b3ccSmatt private: 492eb98b3ccSmatt uint32_t reg[REGNO_ARM32_SPSR + 1]; 493bdd3372bSjoerg uint32_t flags; 494eb98b3ccSmatt uint64_t fpreg[32]; 4951a44aed1Srin }; 49685f18f75Srin 4971a44aed1Srin #undef FLAGS_VFPV2_USED 4981a44aed1Srin #undef FLAGS_VFPV3_USED 4991a44aed1Srin #undef FLAGS_LEGACY_VFPV2_REGNO 5001a44aed1Srin #undef FLAGS_EXTENDED_VFPV2_REGNO 501eb98b3ccSmatt 502396ee378Sjoerg enum { 503396ee378Sjoerg DWARF_VAX_R0 = 0, 504396ee378Sjoerg DWARF_VAX_R15 = 15, 505396ee378Sjoerg DWARF_VAX_PSW = 16, 506396ee378Sjoerg 507396ee378Sjoerg REGNO_VAX_R0 = 0, 508396ee378Sjoerg REGNO_VAX_R14 = 14, 509396ee378Sjoerg REGNO_VAX_R15 = 15, 510396ee378Sjoerg REGNO_VAX_PSW = 16, 511396ee378Sjoerg }; 512396ee378Sjoerg 513396ee378Sjoerg class Registers_vax { 514396ee378Sjoerg public: 515396ee378Sjoerg enum { 516396ee378Sjoerg LAST_REGISTER = REGNO_VAX_PSW, 517396ee378Sjoerg LAST_RESTORE_REG = REGNO_VAX_PSW, 5189788222aSjoerg RETURN_OFFSET = 0, 5190282220bSjoerg RETURN_MASK = 0, 520396ee378Sjoerg }; 521396ee378Sjoerg 522396ee378Sjoerg __dso_hidden Registers_vax(); 523396ee378Sjoerg 524396ee378Sjoerg static int dwarf2regno(int num) { 525396ee378Sjoerg if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15) 526396ee378Sjoerg return REGNO_VAX_R0 + (num - DWARF_VAX_R0); 527396ee378Sjoerg if (num == DWARF_VAX_PSW) 528396ee378Sjoerg return REGNO_VAX_PSW; 529396ee378Sjoerg return LAST_REGISTER + 1; 530396ee378Sjoerg } 531396ee378Sjoerg 532396ee378Sjoerg bool validRegister(int num) const { 533396ee378Sjoerg return num >= 0 && num <= LAST_RESTORE_REG; 534396ee378Sjoerg } 535396ee378Sjoerg 536396ee378Sjoerg uint64_t getRegister(int num) const { 537396ee378Sjoerg assert(validRegister(num)); 538396ee378Sjoerg return reg[num]; 539396ee378Sjoerg } 540396ee378Sjoerg 541396ee378Sjoerg void setRegister(int num, uint64_t value) { 542396ee378Sjoerg assert(validRegister(num)); 543396ee378Sjoerg reg[num] = value; 544396ee378Sjoerg } 545396ee378Sjoerg 546396ee378Sjoerg uint64_t getIP() const { return reg[REGNO_VAX_R15]; } 547396ee378Sjoerg 548396ee378Sjoerg void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; } 549396ee378Sjoerg 550396ee378Sjoerg uint64_t getSP() const { return reg[REGNO_VAX_R14]; } 551396ee378Sjoerg 552396ee378Sjoerg void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; } 553396ee378Sjoerg 554396ee378Sjoerg bool validFloatVectorRegister(int num) const { 555396ee378Sjoerg return false; 556396ee378Sjoerg } 557396ee378Sjoerg 558396ee378Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 559396ee378Sjoerg } 560396ee378Sjoerg 561396ee378Sjoerg __dso_hidden void jumpto() const __dead; 562396ee378Sjoerg 563396ee378Sjoerg private: 564396ee378Sjoerg uint32_t reg[REGNO_VAX_PSW + 1]; 565396ee378Sjoerg }; 566396ee378Sjoerg 567a55c6bd8Sjoerg enum { 568a55c6bd8Sjoerg DWARF_M68K_A0 = 0, 569a55c6bd8Sjoerg DWARF_M68K_A7 = 7, 570a55c6bd8Sjoerg DWARF_M68K_D0 = 8, 571a55c6bd8Sjoerg DWARF_M68K_D7 = 15, 572c05d688cSjoerg DWARF_M68K_FP0 = 16, 573c05d688cSjoerg DWARF_M68K_FP7 = 23, 574a55c6bd8Sjoerg DWARF_M68K_PC = 24, 57535a0f472Sthorpej // DWARF pseudo-register that is an alternate that may be used 57635a0f472Sthorpej // for the return address. 57735a0f472Sthorpej DWARF_M68K_ALT_PC = 25, 578a55c6bd8Sjoerg 579a55c6bd8Sjoerg REGNO_M68K_A0 = 0, 580a55c6bd8Sjoerg REGNO_M68K_A7 = 7, 581a55c6bd8Sjoerg REGNO_M68K_D0 = 8, 582a55c6bd8Sjoerg REGNO_M68K_D7 = 15, 583a55c6bd8Sjoerg REGNO_M68K_PC = 16, 584c05d688cSjoerg REGNO_M68K_FP0 = 17, 585c05d688cSjoerg REGNO_M68K_FP7 = 24, 586a55c6bd8Sjoerg }; 587a55c6bd8Sjoerg 588a55c6bd8Sjoerg class Registers_M68K { 589a55c6bd8Sjoerg public: 590a55c6bd8Sjoerg enum { 591c05d688cSjoerg LAST_REGISTER = REGNO_M68K_FP7, 592c05d688cSjoerg LAST_RESTORE_REG = REGNO_M68K_FP7, 5939788222aSjoerg RETURN_OFFSET = 0, 5940282220bSjoerg RETURN_MASK = 0, 595a55c6bd8Sjoerg }; 596a55c6bd8Sjoerg 597a55c6bd8Sjoerg __dso_hidden Registers_M68K(); 598a55c6bd8Sjoerg 599a55c6bd8Sjoerg static int dwarf2regno(int num) { 600a55c6bd8Sjoerg if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7) 601a55c6bd8Sjoerg return REGNO_M68K_A0 + (num - DWARF_M68K_A0); 602a55c6bd8Sjoerg if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7) 603a55c6bd8Sjoerg return REGNO_M68K_D0 + (num - DWARF_M68K_D0); 604c05d688cSjoerg if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7) 605c05d688cSjoerg return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0); 60635a0f472Sthorpej if (num == DWARF_M68K_PC || num == DWARF_M68K_ALT_PC) 607a55c6bd8Sjoerg return REGNO_M68K_PC; 608a55c6bd8Sjoerg return LAST_REGISTER + 1; 609a55c6bd8Sjoerg } 610a55c6bd8Sjoerg 611a55c6bd8Sjoerg bool validRegister(int num) const { 612c05d688cSjoerg return num >= 0 && num <= REGNO_M68K_PC; 613a55c6bd8Sjoerg } 614a55c6bd8Sjoerg 615a55c6bd8Sjoerg uint64_t getRegister(int num) const { 616a55c6bd8Sjoerg assert(validRegister(num)); 617a55c6bd8Sjoerg return reg[num]; 618a55c6bd8Sjoerg } 619a55c6bd8Sjoerg 620a55c6bd8Sjoerg void setRegister(int num, uint64_t value) { 621a55c6bd8Sjoerg assert(validRegister(num)); 622a55c6bd8Sjoerg reg[num] = value; 623a55c6bd8Sjoerg } 624a55c6bd8Sjoerg 625a55c6bd8Sjoerg uint64_t getIP() const { return reg[REGNO_M68K_PC]; } 626a55c6bd8Sjoerg 627a55c6bd8Sjoerg void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; } 628a55c6bd8Sjoerg 629a55c6bd8Sjoerg uint64_t getSP() const { return reg[REGNO_M68K_A7]; } 630a55c6bd8Sjoerg 631a55c6bd8Sjoerg void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; } 632a55c6bd8Sjoerg 633a55c6bd8Sjoerg bool validFloatVectorRegister(int num) const { 634c05d688cSjoerg return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7; 635a55c6bd8Sjoerg } 636a55c6bd8Sjoerg 637a55c6bd8Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 638c05d688cSjoerg assert(validFloatVectorRegister(num)); 639c05d688cSjoerg const void *addr = reinterpret_cast<const void *>(addr_); 640c05d688cSjoerg memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0])); 641a55c6bd8Sjoerg } 642a55c6bd8Sjoerg 643a55c6bd8Sjoerg __dso_hidden void jumpto() const __dead; 644a55c6bd8Sjoerg 645a55c6bd8Sjoerg private: 646c05d688cSjoerg typedef uint32_t fpreg_t[3]; 647c05d688cSjoerg 648a55c6bd8Sjoerg uint32_t reg[REGNO_M68K_PC + 1]; 649c05d688cSjoerg uint32_t dummy; 650c05d688cSjoerg fpreg_t fpreg[8]; 651a55c6bd8Sjoerg }; 652a55c6bd8Sjoerg 653a280fb92Sjoerg enum { 654a280fb92Sjoerg DWARF_SH3_R0 = 0, 655a280fb92Sjoerg DWARF_SH3_R15 = 15, 656a280fb92Sjoerg DWARF_SH3_PC = 16, 657a280fb92Sjoerg DWARF_SH3_PR = 17, 658a280fb92Sjoerg 659a280fb92Sjoerg REGNO_SH3_R0 = 0, 660a280fb92Sjoerg REGNO_SH3_R15 = 15, 661a280fb92Sjoerg REGNO_SH3_PC = 16, 662a280fb92Sjoerg REGNO_SH3_PR = 17, 663a280fb92Sjoerg }; 664a280fb92Sjoerg 665a280fb92Sjoerg class Registers_SH3 { 666a280fb92Sjoerg public: 667a280fb92Sjoerg enum { 668a280fb92Sjoerg LAST_REGISTER = REGNO_SH3_PR, 669a280fb92Sjoerg LAST_RESTORE_REG = REGNO_SH3_PR, 6709788222aSjoerg RETURN_OFFSET = 0, 6710282220bSjoerg RETURN_MASK = 0, 672a280fb92Sjoerg }; 673a280fb92Sjoerg 674a280fb92Sjoerg __dso_hidden Registers_SH3(); 675a280fb92Sjoerg 676a280fb92Sjoerg static int dwarf2regno(int num) { 677a280fb92Sjoerg if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15) 678a280fb92Sjoerg return REGNO_SH3_R0 + (num - DWARF_SH3_R0); 679a280fb92Sjoerg if (num == DWARF_SH3_PC) 680a280fb92Sjoerg return REGNO_SH3_PC; 681a280fb92Sjoerg if (num == DWARF_SH3_PR) 682a280fb92Sjoerg return REGNO_SH3_PR; 683a280fb92Sjoerg return LAST_REGISTER + 1; 684a280fb92Sjoerg } 685a280fb92Sjoerg 686a280fb92Sjoerg bool validRegister(int num) const { 687a280fb92Sjoerg return num >= 0 && num <= REGNO_SH3_PR; 688a280fb92Sjoerg } 689a280fb92Sjoerg 690a280fb92Sjoerg uint64_t getRegister(int num) const { 691a280fb92Sjoerg assert(validRegister(num)); 692a280fb92Sjoerg return reg[num]; 693a280fb92Sjoerg } 694a280fb92Sjoerg 695a280fb92Sjoerg void setRegister(int num, uint64_t value) { 696a280fb92Sjoerg assert(validRegister(num)); 697a280fb92Sjoerg reg[num] = value; 698a280fb92Sjoerg } 699a280fb92Sjoerg 700a280fb92Sjoerg uint64_t getIP() const { return reg[REGNO_SH3_PC]; } 701a280fb92Sjoerg 702a280fb92Sjoerg void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; } 703a280fb92Sjoerg 704a280fb92Sjoerg uint64_t getSP() const { return reg[REGNO_SH3_R15]; } 705a280fb92Sjoerg 706a280fb92Sjoerg void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; } 707a280fb92Sjoerg 708a280fb92Sjoerg bool validFloatVectorRegister(int num) const { return false; } 709a280fb92Sjoerg 710a280fb92Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) {} 711a280fb92Sjoerg 712a280fb92Sjoerg __dso_hidden void jumpto() const __dead; 713a280fb92Sjoerg 714a280fb92Sjoerg private: 715a280fb92Sjoerg uint32_t reg[REGNO_SH3_PR + 1]; 716a280fb92Sjoerg }; 717a280fb92Sjoerg 718f5cf7457Sjoerg enum { 719f5cf7457Sjoerg DWARF_SPARC64_R0 = 0, 720f5cf7457Sjoerg DWARF_SPARC64_R31 = 31, 721f5cf7457Sjoerg DWARF_SPARC64_PC = 32, 722f5cf7457Sjoerg 723f5cf7457Sjoerg REGNO_SPARC64_R0 = 0, 724f5cf7457Sjoerg REGNO_SPARC64_R14 = 14, 725f5cf7457Sjoerg REGNO_SPARC64_R15 = 15, 726f5cf7457Sjoerg REGNO_SPARC64_R31 = 31, 727f5cf7457Sjoerg REGNO_SPARC64_PC = 32, 728f5cf7457Sjoerg }; 729f5cf7457Sjoerg 730f5cf7457Sjoerg class Registers_SPARC64 { 731f5cf7457Sjoerg public: 732f5cf7457Sjoerg enum { 733f5cf7457Sjoerg LAST_REGISTER = REGNO_SPARC64_PC, 734f5cf7457Sjoerg LAST_RESTORE_REG = REGNO_SPARC64_PC, 735f5cf7457Sjoerg RETURN_OFFSET = 8, 7360282220bSjoerg RETURN_MASK = 0, 737f5cf7457Sjoerg }; 738f5cf7457Sjoerg typedef uint64_t reg_t; 739f5cf7457Sjoerg 740f5cf7457Sjoerg __dso_hidden Registers_SPARC64(); 741f5cf7457Sjoerg 742f5cf7457Sjoerg static int dwarf2regno(int num) { 743f5cf7457Sjoerg if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31) 744f5cf7457Sjoerg return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0); 745f5cf7457Sjoerg if (num == DWARF_SPARC64_PC) 746f5cf7457Sjoerg return REGNO_SPARC64_PC; 747f5cf7457Sjoerg return LAST_REGISTER + 1; 748f5cf7457Sjoerg } 749f5cf7457Sjoerg 750f5cf7457Sjoerg bool validRegister(int num) const { 751f5cf7457Sjoerg return num >= 0 && num <= REGNO_SPARC64_PC; 752f5cf7457Sjoerg } 753f5cf7457Sjoerg 754f5cf7457Sjoerg uint64_t getRegister(int num) const { 755f5cf7457Sjoerg assert(validRegister(num)); 756f5cf7457Sjoerg return reg[num]; 757f5cf7457Sjoerg } 758f5cf7457Sjoerg 759f5cf7457Sjoerg void setRegister(int num, uint64_t value) { 760f5cf7457Sjoerg assert(validRegister(num)); 761f5cf7457Sjoerg reg[num] = value; 762f5cf7457Sjoerg } 763f5cf7457Sjoerg 764f5cf7457Sjoerg uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; } 765f5cf7457Sjoerg 766f5cf7457Sjoerg void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; } 767f5cf7457Sjoerg 768f5cf7457Sjoerg uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; } 769f5cf7457Sjoerg 770f5cf7457Sjoerg void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; } 771f5cf7457Sjoerg 772f5cf7457Sjoerg bool validFloatVectorRegister(int num) const { return false; } 773f5cf7457Sjoerg 774f5cf7457Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) {} 775f5cf7457Sjoerg 776f5cf7457Sjoerg __dso_hidden void jumpto() const __dead; 777f5cf7457Sjoerg 778f5cf7457Sjoerg private: 779f5cf7457Sjoerg uint64_t reg[REGNO_SPARC64_PC + 1]; 780f5cf7457Sjoerg }; 781f5cf7457Sjoerg 782f5cf7457Sjoerg enum { 783f5cf7457Sjoerg DWARF_SPARC_R0 = 0, 784f5cf7457Sjoerg DWARF_SPARC_R31 = 31, 785f5cf7457Sjoerg DWARF_SPARC_PC = 32, 786f5cf7457Sjoerg 787f5cf7457Sjoerg REGNO_SPARC_R0 = 0, 788f5cf7457Sjoerg REGNO_SPARC_R14 = 14, 789f5cf7457Sjoerg REGNO_SPARC_R15 = 15, 790f5cf7457Sjoerg REGNO_SPARC_R31 = 31, 791f5cf7457Sjoerg REGNO_SPARC_PC = 32, 792f5cf7457Sjoerg }; 793f5cf7457Sjoerg 794f5cf7457Sjoerg class Registers_SPARC { 795f5cf7457Sjoerg public: 796f5cf7457Sjoerg enum { 797f5cf7457Sjoerg LAST_REGISTER = REGNO_SPARC_PC, 798f5cf7457Sjoerg LAST_RESTORE_REG = REGNO_SPARC_PC, 799f5cf7457Sjoerg RETURN_OFFSET = 8, 8000282220bSjoerg RETURN_MASK = 0, 801f5cf7457Sjoerg }; 802f5cf7457Sjoerg typedef uint32_t reg_t; 803f5cf7457Sjoerg 804f5cf7457Sjoerg __dso_hidden Registers_SPARC(); 805f5cf7457Sjoerg 806f5cf7457Sjoerg static int dwarf2regno(int num) { 807f5cf7457Sjoerg if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31) 808f5cf7457Sjoerg return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0); 809f5cf7457Sjoerg if (num == DWARF_SPARC_PC) 810f5cf7457Sjoerg return REGNO_SPARC_PC; 811f5cf7457Sjoerg return LAST_REGISTER + 1; 812f5cf7457Sjoerg } 813f5cf7457Sjoerg 814f5cf7457Sjoerg bool validRegister(int num) const { 815f5cf7457Sjoerg return num >= 0 && num <= REGNO_SPARC_PC; 816f5cf7457Sjoerg } 817f5cf7457Sjoerg 818f5cf7457Sjoerg uint64_t getRegister(int num) const { 819f5cf7457Sjoerg assert(validRegister(num)); 820f5cf7457Sjoerg return reg[num]; 821f5cf7457Sjoerg } 822f5cf7457Sjoerg 823f5cf7457Sjoerg void setRegister(int num, uint64_t value) { 824f5cf7457Sjoerg assert(validRegister(num)); 825f5cf7457Sjoerg reg[num] = value; 826f5cf7457Sjoerg } 827f5cf7457Sjoerg 828f5cf7457Sjoerg uint64_t getIP() const { return reg[REGNO_SPARC_PC]; } 829f5cf7457Sjoerg 830f5cf7457Sjoerg void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; } 831f5cf7457Sjoerg 832f5cf7457Sjoerg uint64_t getSP() const { return reg[REGNO_SPARC_R14]; } 833f5cf7457Sjoerg 834f5cf7457Sjoerg void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; } 835f5cf7457Sjoerg 836f5cf7457Sjoerg bool validFloatVectorRegister(int num) const { return false; } 837f5cf7457Sjoerg 838f5cf7457Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) {} 839f5cf7457Sjoerg 840f5cf7457Sjoerg __dso_hidden void jumpto() const __dead; 841f5cf7457Sjoerg 842f5cf7457Sjoerg private: 843f5cf7457Sjoerg uint32_t reg[REGNO_SPARC_PC + 1]; 844f5cf7457Sjoerg }; 845f5cf7457Sjoerg 846e3d4269aSjoerg enum { 847e3d4269aSjoerg DWARF_ALPHA_R0 = 0, 848e3d4269aSjoerg DWARF_ALPHA_R30 = 30, 849e3d4269aSjoerg DWARF_ALPHA_F0 = 32, 850e3d4269aSjoerg DWARF_ALPHA_F30 = 62, 851aa2e0e12Sthorpej DWARF_ALPHA_SIGRETURN = 64, 852e3d4269aSjoerg 853e3d4269aSjoerg REGNO_ALPHA_R0 = 0, 854e3d4269aSjoerg REGNO_ALPHA_R26 = 26, 855e3d4269aSjoerg REGNO_ALPHA_R30 = 30, 856e3d4269aSjoerg REGNO_ALPHA_PC = 31, 857e3d4269aSjoerg REGNO_ALPHA_F0 = 32, 858e3d4269aSjoerg REGNO_ALPHA_F30 = 62, 859aa2e0e12Sthorpej REGNO_ALPHA_SIGRETURN = 64, 860e3d4269aSjoerg }; 861e3d4269aSjoerg 862e3d4269aSjoerg class Registers_Alpha { 863e3d4269aSjoerg public: 864e3d4269aSjoerg enum { 865aa2e0e12Sthorpej LAST_REGISTER = REGNO_ALPHA_SIGRETURN, 866aa2e0e12Sthorpej LAST_RESTORE_REG = REGNO_ALPHA_SIGRETURN, 867e3d4269aSjoerg RETURN_OFFSET = 0, 8680282220bSjoerg RETURN_MASK = 0, 869e3d4269aSjoerg }; 870e3d4269aSjoerg typedef uint32_t reg_t; 871e3d4269aSjoerg 872e3d4269aSjoerg __dso_hidden Registers_Alpha(); 873e3d4269aSjoerg 874e3d4269aSjoerg static int dwarf2regno(int num) { return num; } 875e3d4269aSjoerg 876e3d4269aSjoerg bool validRegister(int num) const { 877aa2e0e12Sthorpej return (num >= 0 && num <= REGNO_ALPHA_PC) || 878aa2e0e12Sthorpej num == REGNO_ALPHA_SIGRETURN; 879e3d4269aSjoerg } 880e3d4269aSjoerg 881e3d4269aSjoerg uint64_t getRegister(int num) const { 882e3d4269aSjoerg assert(validRegister(num)); 883aa2e0e12Sthorpej if (num == REGNO_ALPHA_SIGRETURN) 884aa2e0e12Sthorpej return sigreturn_reg; 885aa2e0e12Sthorpej else 886e3d4269aSjoerg return reg[num]; 887e3d4269aSjoerg } 888e3d4269aSjoerg 889e3d4269aSjoerg void setRegister(int num, uint64_t value) { 890e3d4269aSjoerg assert(validRegister(num)); 891aa2e0e12Sthorpej if (num == REGNO_ALPHA_SIGRETURN) 892aa2e0e12Sthorpej sigreturn_reg = value; 893aa2e0e12Sthorpej else 894e3d4269aSjoerg reg[num] = value; 895e3d4269aSjoerg } 896e3d4269aSjoerg 897e3d4269aSjoerg uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; } 898e3d4269aSjoerg 899e3d4269aSjoerg void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; } 900e3d4269aSjoerg 901e3d4269aSjoerg uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; } 902e3d4269aSjoerg 903e3d4269aSjoerg void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; } 904e3d4269aSjoerg 905e3d4269aSjoerg bool validFloatVectorRegister(int num) const { 906e3d4269aSjoerg return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30; 907e3d4269aSjoerg } 908e3d4269aSjoerg 909e3d4269aSjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 910e3d4269aSjoerg assert(validFloatVectorRegister(num)); 911e3d4269aSjoerg const void *addr = reinterpret_cast<const void *>(addr_); 912e3d4269aSjoerg memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0])); 913e3d4269aSjoerg } 914e3d4269aSjoerg 915e3d4269aSjoerg __dso_hidden void jumpto() const __dead; 916e3d4269aSjoerg 917e3d4269aSjoerg private: 918e3d4269aSjoerg uint64_t reg[REGNO_ALPHA_PC + 1]; 919e3d4269aSjoerg uint64_t fpreg[31]; 920aa2e0e12Sthorpej uint64_t sigreturn_reg; 921e3d4269aSjoerg }; 922e3d4269aSjoerg 923a78e9b23Sjoerg enum { 924a78e9b23Sjoerg DWARF_HPPA_R1 = 1, 925a78e9b23Sjoerg DWARF_HPPA_R31 = 31, 926a78e9b23Sjoerg DWARF_HPPA_FR4L = 32, 927a78e9b23Sjoerg DWARF_HPPA_FR31H = 87, 928a78e9b23Sjoerg 929a78e9b23Sjoerg REGNO_HPPA_PC = 0, 930a78e9b23Sjoerg REGNO_HPPA_R1 = 1, 931a78e9b23Sjoerg REGNO_HPPA_R2 = 2, 932a78e9b23Sjoerg REGNO_HPPA_R30 = 30, 933a78e9b23Sjoerg REGNO_HPPA_R31 = 31, 934a78e9b23Sjoerg REGNO_HPPA_FR4L = 32, 935a78e9b23Sjoerg REGNO_HPPA_FR31H = 87, 936a78e9b23Sjoerg }; 937a78e9b23Sjoerg 938a78e9b23Sjoerg class Registers_HPPA { 939a78e9b23Sjoerg public: 940a78e9b23Sjoerg enum { 941a78e9b23Sjoerg LAST_REGISTER = REGNO_HPPA_FR31H, 942a78e9b23Sjoerg LAST_RESTORE_REG = REGNO_HPPA_FR31H, 9430282220bSjoerg RETURN_OFFSET = 0, 9440282220bSjoerg RETURN_MASK = 3, 945a78e9b23Sjoerg }; 946a78e9b23Sjoerg 947a78e9b23Sjoerg __dso_hidden Registers_HPPA(); 948a78e9b23Sjoerg 949a78e9b23Sjoerg static int dwarf2regno(int num) { 950a78e9b23Sjoerg if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31) 951a78e9b23Sjoerg return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1); 952a78e9b23Sjoerg if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H) 953a78e9b23Sjoerg return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H); 954a78e9b23Sjoerg return LAST_REGISTER + 1; 955a78e9b23Sjoerg } 956a78e9b23Sjoerg 957a78e9b23Sjoerg bool validRegister(int num) const { 958a78e9b23Sjoerg return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31; 959a78e9b23Sjoerg } 960a78e9b23Sjoerg 961a78e9b23Sjoerg uint64_t getRegister(int num) const { 962a78e9b23Sjoerg assert(validRegister(num)); 963a78e9b23Sjoerg return reg[num]; 964a78e9b23Sjoerg } 965a78e9b23Sjoerg 966a78e9b23Sjoerg void setRegister(int num, uint64_t value) { 967a78e9b23Sjoerg assert(validRegister(num)); 968a78e9b23Sjoerg reg[num] = value; 969a78e9b23Sjoerg } 970a78e9b23Sjoerg 971a78e9b23Sjoerg uint64_t getIP() const { return reg[REGNO_HPPA_PC]; } 972a78e9b23Sjoerg 973a78e9b23Sjoerg void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; } 974a78e9b23Sjoerg 975a78e9b23Sjoerg uint64_t getSP() const { return reg[REGNO_HPPA_R30]; } 976a78e9b23Sjoerg 977a78e9b23Sjoerg void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; } 978a78e9b23Sjoerg 979a78e9b23Sjoerg bool validFloatVectorRegister(int num) const { 980a78e9b23Sjoerg return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H; 981a78e9b23Sjoerg } 982a78e9b23Sjoerg 983a78e9b23Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 984a78e9b23Sjoerg assert(validFloatVectorRegister(num)); 985a78e9b23Sjoerg const void *addr = reinterpret_cast<const void *>(addr_); 986a78e9b23Sjoerg memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0])); 987a78e9b23Sjoerg } 988a78e9b23Sjoerg 989a78e9b23Sjoerg __dso_hidden void jumpto() const __dead; 990a78e9b23Sjoerg 991a78e9b23Sjoerg private: 992a78e9b23Sjoerg uint32_t reg[REGNO_HPPA_R31 + 1]; 993a78e9b23Sjoerg uint32_t fpreg[56]; 994a78e9b23Sjoerg }; 995a78e9b23Sjoerg 996ed444622Sjoerg enum { 997ed444622Sjoerg DWARF_MIPS_R1 = 0, 998ed444622Sjoerg DWARF_MIPS_R31 = 31, 999ed444622Sjoerg DWARF_MIPS_F0 = 32, 1000ed444622Sjoerg DWARF_MIPS_F31 = 63, 100192db81e4Sthorpej // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and 100292db81e4Sthorpej // signal handler return address. 100392db81e4Sthorpej DWARF_MIPS_MDHI = 64, 100492db81e4Sthorpej DWARF_MIPS_MDLO = 65, 100592db81e4Sthorpej DWARF_MIPS_SIGRETURN = 66, 1006ed444622Sjoerg 1007ed444622Sjoerg REGNO_MIPS_PC = 0, 1008ed444622Sjoerg REGNO_MIPS_R1 = 0, 1009ed444622Sjoerg REGNO_MIPS_R29 = 29, 1010ed444622Sjoerg REGNO_MIPS_R31 = 31, 1011ed444622Sjoerg REGNO_MIPS_F0 = 33, 101292db81e4Sthorpej REGNO_MIPS_F31 = 64, 101392db81e4Sthorpej // these live in other_reg[] 101492db81e4Sthorpej REGNO_MIPS_MDHI = 65, 101592db81e4Sthorpej REGNO_MIPS_MDLO = 66, 101692db81e4Sthorpej REGNO_MIPS_SIGRETURN = 67 1017ed444622Sjoerg }; 1018ed444622Sjoerg 1019ed444622Sjoerg class Registers_MIPS { 1020ed444622Sjoerg public: 1021ed444622Sjoerg enum { 102292db81e4Sthorpej LAST_REGISTER = REGNO_MIPS_SIGRETURN, 102392db81e4Sthorpej LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN, 1024ed444622Sjoerg RETURN_OFFSET = 0, 10250282220bSjoerg RETURN_MASK = 0, 1026ed444622Sjoerg }; 1027ed444622Sjoerg 1028ed444622Sjoerg __dso_hidden Registers_MIPS(); 1029ed444622Sjoerg 1030ed444622Sjoerg static int dwarf2regno(int num) { 1031ed444622Sjoerg if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31) 1032ed444622Sjoerg return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1); 1033ed444622Sjoerg if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31) 1034ed444622Sjoerg return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0); 103592db81e4Sthorpej if (num >= DWARF_MIPS_MDHI && num <= DWARF_MIPS_SIGRETURN) 103692db81e4Sthorpej return REGNO_MIPS_MDHI + (num - DWARF_MIPS_MDHI); 1037ed444622Sjoerg return LAST_REGISTER + 1; 1038ed444622Sjoerg } 1039ed444622Sjoerg 1040ed444622Sjoerg bool validRegister(int num) const { 104192db81e4Sthorpej return (num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31) || 104292db81e4Sthorpej (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN); 1043ed444622Sjoerg } 1044ed444622Sjoerg 1045ed444622Sjoerg uint64_t getRegister(int num) const { 1046ed444622Sjoerg assert(validRegister(num)); 104792db81e4Sthorpej if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN) 104892db81e4Sthorpej return other_reg[num - REGNO_MIPS_MDHI]; 1049ed444622Sjoerg return reg[num]; 1050ed444622Sjoerg } 1051ed444622Sjoerg 1052ed444622Sjoerg void setRegister(int num, uint64_t value) { 1053ed444622Sjoerg assert(validRegister(num)); 105492db81e4Sthorpej if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN) 105592db81e4Sthorpej other_reg[num - REGNO_MIPS_MDHI] = value; 105692db81e4Sthorpej else 1057ed444622Sjoerg reg[num] = value; 1058ed444622Sjoerg } 1059ed444622Sjoerg 1060ed444622Sjoerg uint64_t getIP() const { return reg[REGNO_MIPS_PC]; } 1061ed444622Sjoerg 1062ed444622Sjoerg void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; } 1063ed444622Sjoerg 1064ed444622Sjoerg uint64_t getSP() const { return reg[REGNO_MIPS_R29]; } 1065ed444622Sjoerg 1066ed444622Sjoerg void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; } 1067ed444622Sjoerg 1068ed444622Sjoerg bool validFloatVectorRegister(int num) const { 106992db81e4Sthorpej return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31; 1070ed444622Sjoerg } 1071ed444622Sjoerg 1072ed444622Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 1073ed444622Sjoerg assert(validFloatVectorRegister(num)); 1074ed444622Sjoerg const void *addr = reinterpret_cast<const void *>(addr_); 1075ed444622Sjoerg memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0])); 1076ed444622Sjoerg } 1077ed444622Sjoerg 1078ed444622Sjoerg __dso_hidden void jumpto() const __dead; 1079ed444622Sjoerg 1080ed444622Sjoerg private: 1081ed444622Sjoerg uint32_t reg[REGNO_MIPS_R31 + 1]; 1082ed444622Sjoerg uint64_t fpreg[32]; 108392db81e4Sthorpej uint32_t other_reg[3]; 1084ed444622Sjoerg }; 1085ed444622Sjoerg 1086ed444622Sjoerg enum { 1087ed444622Sjoerg DWARF_MIPS64_R1 = 0, 1088ed444622Sjoerg DWARF_MIPS64_R31 = 31, 1089ed444622Sjoerg DWARF_MIPS64_F0 = 32, 1090ed444622Sjoerg DWARF_MIPS64_F31 = 63, 1091b751d63aSthorpej // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and 1092b751d63aSthorpej // signal handler return address. 1093b751d63aSthorpej DWARF_MIPS64_MDHI = 64, 1094b751d63aSthorpej DWARF_MIPS64_MDLO = 65, 1095b751d63aSthorpej DWARF_MIPS64_SIGRETURN = 66, 1096ed444622Sjoerg 1097ed444622Sjoerg REGNO_MIPS64_PC = 0, 1098ed444622Sjoerg REGNO_MIPS64_R1 = 0, 1099ed444622Sjoerg REGNO_MIPS64_R29 = 29, 1100ed444622Sjoerg REGNO_MIPS64_R31 = 31, 1101ed444622Sjoerg REGNO_MIPS64_F0 = 33, 1102b751d63aSthorpej REGNO_MIPS64_F31 = 64, 1103b751d63aSthorpej // these live in other_reg[] 1104b751d63aSthorpej REGNO_MIPS64_MDHI = 65, 1105b751d63aSthorpej REGNO_MIPS64_MDLO = 66, 1106b751d63aSthorpej REGNO_MIPS64_SIGRETURN = 67 1107ed444622Sjoerg }; 1108ed444622Sjoerg 1109ed444622Sjoerg class Registers_MIPS64 { 1110ed444622Sjoerg public: 1111ed444622Sjoerg enum { 1112b751d63aSthorpej LAST_REGISTER = REGNO_MIPS_SIGRETURN, 1113b751d63aSthorpej LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN, 1114ed444622Sjoerg RETURN_OFFSET = 0, 11150282220bSjoerg RETURN_MASK = 0, 1116ed444622Sjoerg }; 1117ed444622Sjoerg 1118ed444622Sjoerg __dso_hidden Registers_MIPS64(); 1119ed444622Sjoerg 1120ed444622Sjoerg static int dwarf2regno(int num) { 1121ed444622Sjoerg if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31) 1122ed444622Sjoerg return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1); 1123ed444622Sjoerg if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31) 1124ed444622Sjoerg return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0); 1125b751d63aSthorpej if (num >= DWARF_MIPS64_MDHI && num <= DWARF_MIPS64_SIGRETURN) 1126b751d63aSthorpej return REGNO_MIPS64_MDHI + (num - DWARF_MIPS64_MDHI); 1127ed444622Sjoerg return LAST_REGISTER + 1; 1128ed444622Sjoerg } 1129ed444622Sjoerg 1130ed444622Sjoerg bool validRegister(int num) const { 1131b7465dafSskrll return (num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31) || 1132b751d63aSthorpej (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN); 1133ed444622Sjoerg } 1134ed444622Sjoerg 1135ed444622Sjoerg uint64_t getRegister(int num) const { 1136ed444622Sjoerg assert(validRegister(num)); 1137b751d63aSthorpej if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN) 1138b751d63aSthorpej return other_reg[num - REGNO_MIPS64_MDHI]; 1139ed444622Sjoerg return reg[num]; 1140ed444622Sjoerg } 1141ed444622Sjoerg 1142ed444622Sjoerg void setRegister(int num, uint64_t value) { 1143ed444622Sjoerg assert(validRegister(num)); 1144b751d63aSthorpej if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN) 1145b751d63aSthorpej other_reg[num - REGNO_MIPS64_MDHI] = value; 1146b751d63aSthorpej else 1147ed444622Sjoerg reg[num] = value; 1148ed444622Sjoerg } 1149ed444622Sjoerg 1150ed444622Sjoerg uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; } 1151ed444622Sjoerg 1152ed444622Sjoerg void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; } 1153ed444622Sjoerg 1154ed444622Sjoerg uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; } 1155ed444622Sjoerg 1156ed444622Sjoerg void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; } 1157ed444622Sjoerg 1158ed444622Sjoerg bool validFloatVectorRegister(int num) const { 1159b751d63aSthorpej return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31; 1160ed444622Sjoerg } 1161ed444622Sjoerg 1162ed444622Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 1163ed444622Sjoerg assert(validFloatVectorRegister(num)); 1164ed444622Sjoerg const void *addr = reinterpret_cast<const void *>(addr_); 1165ed444622Sjoerg memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0])); 1166ed444622Sjoerg } 1167ed444622Sjoerg 1168ed444622Sjoerg __dso_hidden void jumpto() const __dead; 1169ed444622Sjoerg 1170ed444622Sjoerg private: 1171ed444622Sjoerg uint64_t reg[REGNO_MIPS64_R31 + 1]; 1172ed444622Sjoerg uint64_t fpreg[32]; 1173b751d63aSthorpej uint64_t other_reg[3]; 1174ed444622Sjoerg }; 1175ed444622Sjoerg 1176938bf86eSmatt enum { 1177938bf86eSmatt DWARF_OR1K_R0 = 0, 1178938bf86eSmatt DWARF_OR1K_SP = 1, 1179938bf86eSmatt DWARF_OR1K_LR = 9, 1180938bf86eSmatt DWARF_OR1K_R31 = 31, 1181938bf86eSmatt DWARF_OR1K_FPCSR = 32, 1182938bf86eSmatt 1183938bf86eSmatt REGNO_OR1K_R0 = 0, 1184938bf86eSmatt REGNO_OR1K_SP = 1, 1185938bf86eSmatt REGNO_OR1K_LR = 9, 1186938bf86eSmatt REGNO_OR1K_R31 = 31, 1187938bf86eSmatt REGNO_OR1K_FPCSR = 32, 1188938bf86eSmatt }; 1189938bf86eSmatt 1190938bf86eSmatt class Registers_or1k { 1191938bf86eSmatt public: 1192938bf86eSmatt enum { 1193938bf86eSmatt LAST_REGISTER = REGNO_OR1K_FPCSR, 1194938bf86eSmatt LAST_RESTORE_REG = REGNO_OR1K_FPCSR, 1195938bf86eSmatt RETURN_OFFSET = 0, 11960282220bSjoerg RETURN_MASK = 0, 1197938bf86eSmatt }; 1198938bf86eSmatt 1199938bf86eSmatt __dso_hidden Registers_or1k(); 1200938bf86eSmatt 1201938bf86eSmatt static int dwarf2regno(int num) { 1202938bf86eSmatt if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31) 1203938bf86eSmatt return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0); 1204938bf86eSmatt if (num == DWARF_OR1K_FPCSR) 1205938bf86eSmatt return REGNO_OR1K_FPCSR; 1206938bf86eSmatt return LAST_REGISTER + 1; 1207938bf86eSmatt } 1208938bf86eSmatt 1209938bf86eSmatt bool validRegister(int num) const { 1210938bf86eSmatt return num >= 0 && num <= LAST_RESTORE_REG; 1211938bf86eSmatt } 1212938bf86eSmatt 1213938bf86eSmatt uint64_t getRegister(int num) const { 1214938bf86eSmatt assert(validRegister(num)); 1215938bf86eSmatt return reg[num]; 1216938bf86eSmatt } 1217938bf86eSmatt 1218938bf86eSmatt void setRegister(int num, uint64_t value) { 1219938bf86eSmatt assert(validRegister(num)); 1220938bf86eSmatt reg[num] = value; 1221938bf86eSmatt } 1222938bf86eSmatt 1223938bf86eSmatt uint64_t getIP() const { return reg[REGNO_OR1K_LR]; } 1224938bf86eSmatt 1225938bf86eSmatt void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; } 1226938bf86eSmatt 1227938bf86eSmatt uint64_t getSP() const { return reg[REGNO_OR1K_SP]; } 1228938bf86eSmatt 1229938bf86eSmatt void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; } 1230938bf86eSmatt 1231938bf86eSmatt bool validFloatVectorRegister(int num) const { 1232938bf86eSmatt return false; 1233938bf86eSmatt } 1234938bf86eSmatt 1235938bf86eSmatt void copyFloatVectorRegister(int num, uint64_t addr_) { 1236938bf86eSmatt } 1237938bf86eSmatt 1238938bf86eSmatt __dso_hidden void jumpto() const __dead; 1239938bf86eSmatt 1240938bf86eSmatt private: 1241938bf86eSmatt uint32_t reg[REGNO_OR1K_FPCSR + 1]; 1242938bf86eSmatt }; 1243938bf86eSmatt 1244a6ecde39Sjoerg #if __i386__ 1245a6ecde39Sjoerg typedef Registers_x86 NativeUnwindRegisters; 1246a6ecde39Sjoerg #elif __x86_64__ 1247a6ecde39Sjoerg typedef Registers_x86_64 NativeUnwindRegisters; 1248a6ecde39Sjoerg #elif __powerpc__ 1249a6ecde39Sjoerg typedef Registers_ppc32 NativeUnwindRegisters; 1250aa37019dSmatt #elif __aarch64__ 1251aa37019dSmatt typedef Registers_aarch64 NativeUnwindRegisters; 1252bdd3372bSjoerg #elif __arm__ 1253a6ecde39Sjoerg typedef Registers_arm32 NativeUnwindRegisters; 1254a6ecde39Sjoerg #elif __vax__ 1255a6ecde39Sjoerg typedef Registers_vax NativeUnwindRegisters; 1256a6ecde39Sjoerg #elif __m68k__ 1257a6ecde39Sjoerg typedef Registers_M68K NativeUnwindRegisters; 1258ed444622Sjoerg #elif __mips_n64 || __mips_n32 1259ed444622Sjoerg typedef Registers_MIPS64 NativeUnwindRegisters; 1260ed444622Sjoerg #elif __mips__ 1261ed444622Sjoerg typedef Registers_MIPS NativeUnwindRegisters; 1262a6ecde39Sjoerg #elif __sh3__ 1263a6ecde39Sjoerg typedef Registers_SH3 NativeUnwindRegisters; 1264f5cf7457Sjoerg #elif __sparc64__ 1265f5cf7457Sjoerg typedef Registers_SPARC64 NativeUnwindRegisters; 1266f5cf7457Sjoerg #elif __sparc__ 1267f5cf7457Sjoerg typedef Registers_SPARC NativeUnwindRegisters; 1268e3d4269aSjoerg #elif __alpha__ 1269e3d4269aSjoerg typedef Registers_Alpha NativeUnwindRegisters; 1270a78e9b23Sjoerg #elif __hppa__ 1271a78e9b23Sjoerg typedef Registers_HPPA NativeUnwindRegisters; 1272938bf86eSmatt #elif __or1k__ 1273938bf86eSmatt typedef Registers_or1k NativeUnwindRegisters; 1274a6ecde39Sjoerg #endif 1275aa0b96d0Sjoerg } // namespace _Unwind 1276aa0b96d0Sjoerg 1277aa0b96d0Sjoerg #endif // __REGISTERS_HPP__ 1278