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, 151b238bfcaSjoerg DWARF_PPC32_CR = 70, 152b238bfcaSjoerg DWARF_PPC32_V0 = 77, 153b238bfcaSjoerg DWARF_PPC32_V31 = 108, 154b238bfcaSjoerg 155aa0b96d0Sjoerg REGNO_PPC32_R0 = 0, 156b238bfcaSjoerg REGNO_PPC32_R1 = 1, 157aa0b96d0Sjoerg REGNO_PPC32_R31 = 31, 158b238bfcaSjoerg REGNO_PPC32_LR = 32, 159b238bfcaSjoerg REGNO_PPC32_CR = 33, 160b238bfcaSjoerg REGNO_PPC32_SRR0 = 34, 161b238bfcaSjoerg 162aa0b96d0Sjoerg REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1, 163aa0b96d0Sjoerg REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31, 164aa0b96d0Sjoerg REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1, 165aa0b96d0Sjoerg REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31, 166aa0b96d0Sjoerg }; 167aa0b96d0Sjoerg 168aa0b96d0Sjoerg class Registers_ppc32 { 169aa0b96d0Sjoerg public: 170aa0b96d0Sjoerg enum { 171aa0b96d0Sjoerg LAST_REGISTER = REGNO_PPC32_V31, 172916de6d0Sjoerg LAST_RESTORE_REG = REGNO_PPC32_V31, 1739788222aSjoerg RETURN_OFFSET = 0, 1740282220bSjoerg RETURN_MASK = 0, 175aa0b96d0Sjoerg }; 176aa0b96d0Sjoerg 177aa0b96d0Sjoerg __dso_hidden Registers_ppc32(); 178aa0b96d0Sjoerg 179aa0b96d0Sjoerg static int dwarf2regno(int num) { 180aa0b96d0Sjoerg if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31) 181aa0b96d0Sjoerg return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0); 182aa0b96d0Sjoerg if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31) 183aa0b96d0Sjoerg return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0); 184aa0b96d0Sjoerg if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31) 185aa0b96d0Sjoerg return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0); 186b238bfcaSjoerg switch (num) { 187b238bfcaSjoerg case DWARF_PPC32_LR: 188b238bfcaSjoerg return REGNO_PPC32_LR; 189b238bfcaSjoerg case DWARF_PPC32_CR: 190b238bfcaSjoerg return REGNO_PPC32_CR; 191b238bfcaSjoerg default: 192aa0b96d0Sjoerg return LAST_REGISTER + 1; 193aa0b96d0Sjoerg } 194b238bfcaSjoerg } 195aa0b96d0Sjoerg 196aa0b96d0Sjoerg bool validRegister(int num) const { 197aa0b96d0Sjoerg return num >= 0 && num <= LAST_RESTORE_REG; 198aa0b96d0Sjoerg } 199aa0b96d0Sjoerg 200aa0b96d0Sjoerg uint64_t getRegister(int num) const { 201aa0b96d0Sjoerg assert(validRegister(num)); 202aa0b96d0Sjoerg return reg[num]; 203aa0b96d0Sjoerg } 204aa0b96d0Sjoerg 205aa0b96d0Sjoerg void setRegister(int num, uint64_t value) { 206aa0b96d0Sjoerg assert(validRegister(num)); 207aa0b96d0Sjoerg reg[num] = value; 208aa0b96d0Sjoerg } 209aa0b96d0Sjoerg 210aa0b96d0Sjoerg uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; } 211aa0b96d0Sjoerg 212aa0b96d0Sjoerg void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; } 213aa0b96d0Sjoerg 214aa0b96d0Sjoerg uint64_t getSP() const { return reg[REGNO_PPC32_R1]; } 215aa0b96d0Sjoerg 216aa0b96d0Sjoerg void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; } 217aa0b96d0Sjoerg 218aa0b96d0Sjoerg bool validFloatVectorRegister(int num) const { 219aa0b96d0Sjoerg return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) || 220aa0b96d0Sjoerg (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31); 221aa0b96d0Sjoerg } 222aa0b96d0Sjoerg 223aa0b96d0Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 224aa0b96d0Sjoerg const void *addr = reinterpret_cast<const void *>(addr_); 225aa0b96d0Sjoerg if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) 226aa0b96d0Sjoerg memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0])); 227aa0b96d0Sjoerg else 228aa0b96d0Sjoerg memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0])); 229aa0b96d0Sjoerg } 230aa0b96d0Sjoerg 231aa0b96d0Sjoerg __dso_hidden void jumpto() const __dead; 232aa0b96d0Sjoerg 233aa0b96d0Sjoerg private: 234aa0b96d0Sjoerg struct vecreg_t { 235aa0b96d0Sjoerg uint64_t low, high; 236aa0b96d0Sjoerg }; 237aa0b96d0Sjoerg uint32_t reg[REGNO_PPC32_SRR0 + 1]; 238b238bfcaSjoerg uint32_t dummy; 239aa0b96d0Sjoerg uint64_t fpreg[32]; 240aa0b96d0Sjoerg vecreg_t vecreg[64]; 241aa0b96d0Sjoerg }; 242aa0b96d0Sjoerg 243eb98b3ccSmatt enum { 244aa37019dSmatt DWARF_AARCH64_X0 = 0, 245aa37019dSmatt DWARF_AARCH64_X30 = 30, 246aa37019dSmatt DWARF_AARCH64_SP = 31, 247aa37019dSmatt DWARF_AARCH64_V0 = 64, 248aa37019dSmatt DWARF_AARCH64_V31 = 95, 249aa37019dSmatt 250aa37019dSmatt REGNO_AARCH64_X0 = 0, 251aa37019dSmatt REGNO_AARCH64_X30 = 30, 252aa37019dSmatt REGNO_AARCH64_SP = 31, 25328f5faf2Sjoerg REGNO_AARCH64_V0 = 32, 25428f5faf2Sjoerg REGNO_AARCH64_V31 = 63, 255aa37019dSmatt }; 256aa37019dSmatt 257aa37019dSmatt class Registers_aarch64 { 258aa37019dSmatt public: 259aa37019dSmatt enum { 260aa37019dSmatt LAST_RESTORE_REG = REGNO_AARCH64_V31, 261aa37019dSmatt LAST_REGISTER = REGNO_AARCH64_V31, 262aa37019dSmatt RETURN_OFFSET = 0, 2630282220bSjoerg RETURN_MASK = 0, 264aa37019dSmatt }; 265aa37019dSmatt 266aa37019dSmatt __dso_hidden Registers_aarch64(); 267aa37019dSmatt 268aa37019dSmatt static int dwarf2regno(int num) { 269aa37019dSmatt if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30) 270aa37019dSmatt return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0); 271aa37019dSmatt if (num == DWARF_AARCH64_SP) 272aa37019dSmatt return REGNO_AARCH64_SP; 273aa37019dSmatt if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31) 274aa37019dSmatt return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0); 275aa37019dSmatt return LAST_REGISTER + 1; 276aa37019dSmatt } 277aa37019dSmatt 278aa37019dSmatt bool validRegister(int num) const { 279aa37019dSmatt return num >= 0 && num <= LAST_RESTORE_REG; 280aa37019dSmatt } 281aa37019dSmatt 282aa37019dSmatt uint64_t getRegister(int num) const { 283aa37019dSmatt assert(validRegister(num)); 284aa37019dSmatt return reg[num]; 285aa37019dSmatt } 286aa37019dSmatt 287aa37019dSmatt void setRegister(int num, uint64_t value) { 288aa37019dSmatt assert(validRegister(num)); 289aa37019dSmatt reg[num] = value; 290aa37019dSmatt } 291aa37019dSmatt 292aa37019dSmatt uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; } 293aa37019dSmatt 294aa37019dSmatt void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; } 295aa37019dSmatt 296aa37019dSmatt uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; } 297aa37019dSmatt 298aa37019dSmatt void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; } 299aa37019dSmatt 300aa37019dSmatt bool validFloatVectorRegister(int num) const { 301aa37019dSmatt return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31); 302aa37019dSmatt } 303aa37019dSmatt 304aa37019dSmatt void copyFloatVectorRegister(int num, uint64_t addr_) { 305aa37019dSmatt const void *addr = reinterpret_cast<const void *>(addr_); 30628f5faf2Sjoerg memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, 16); 307aa37019dSmatt } 308aa37019dSmatt 309aa37019dSmatt __dso_hidden void jumpto() const __dead; 310aa37019dSmatt 311aa37019dSmatt private: 31228f5faf2Sjoerg uint64_t reg[REGNO_AARCH64_SP + 1]; 31328f5faf2Sjoerg uint64_t vecreg[64]; 314aa37019dSmatt }; 315aa37019dSmatt 316aa37019dSmatt enum { 317eb98b3ccSmatt DWARF_ARM32_R0 = 0, 318eb98b3ccSmatt DWARF_ARM32_R15 = 15, 319eb98b3ccSmatt DWARF_ARM32_SPSR = 128, 320155a9ee6Sjoerg DWARF_ARM32_S0 = 64, 321*8026a450Srin DWARF_ARM32_S31 = 95, 322bdd3372bSjoerg DWARF_ARM32_D0 = 256, 323eb98b3ccSmatt DWARF_ARM32_D31 = 287, 324eb98b3ccSmatt REGNO_ARM32_R0 = 0, 325eb98b3ccSmatt REGNO_ARM32_SP = 13, 326eb98b3ccSmatt REGNO_ARM32_R15 = 15, 327eb98b3ccSmatt REGNO_ARM32_SPSR = 16, 328bdd3372bSjoerg REGNO_ARM32_D0 = 17, 329bdd3372bSjoerg REGNO_ARM32_D15 = 32, 330bdd3372bSjoerg REGNO_ARM32_D31 = 48, 331155a9ee6Sjoerg REGNO_ARM32_S0 = 49, 332*8026a450Srin REGNO_ARM32_S31 = 80, 333eb98b3ccSmatt }; 334eb98b3ccSmatt 335eb98b3ccSmatt class Registers_arm32 { 336eb98b3ccSmatt public: 337eb98b3ccSmatt enum { 338eb98b3ccSmatt LAST_REGISTER = REGNO_ARM32_D31, 339bdd3372bSjoerg LAST_RESTORE_REG = REGNO_ARM32_D31, 3409788222aSjoerg RETURN_OFFSET = 0, 3410282220bSjoerg RETURN_MASK = 0, 342eb98b3ccSmatt }; 343eb98b3ccSmatt 344eb98b3ccSmatt __dso_hidden Registers_arm32(); 345eb98b3ccSmatt 346eb98b3ccSmatt static int dwarf2regno(int num) { 347eb98b3ccSmatt if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15) 348eb98b3ccSmatt return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0); 349eb98b3ccSmatt if (num == DWARF_ARM32_SPSR) 350eb98b3ccSmatt return REGNO_ARM32_SPSR; 351bdd3372bSjoerg if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31) 352bdd3372bSjoerg return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0); 35385f18f75Srin if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31) 354155a9ee6Sjoerg return REGNO_ARM32_S0 + (num - DWARF_ARM32_S0); 355eb98b3ccSmatt return LAST_REGISTER + 1; 356eb98b3ccSmatt } 357eb98b3ccSmatt 358eb98b3ccSmatt bool validRegister(int num) const { 359bdd3372bSjoerg return num >= 0 && num <= REGNO_ARM32_SPSR; 360eb98b3ccSmatt } 361eb98b3ccSmatt 362eb98b3ccSmatt uint64_t getRegister(int num) const { 363eb98b3ccSmatt assert(validRegister(num)); 364eb98b3ccSmatt return reg[num]; 365eb98b3ccSmatt } 366eb98b3ccSmatt 367eb98b3ccSmatt void setRegister(int num, uint64_t value) { 368eb98b3ccSmatt assert(validRegister(num)); 369eb98b3ccSmatt reg[num] = value; 370eb98b3ccSmatt } 371eb98b3ccSmatt 372eb98b3ccSmatt uint64_t getIP() const { return reg[REGNO_ARM32_R15]; } 373eb98b3ccSmatt 374eb98b3ccSmatt void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; } 375eb98b3ccSmatt 376eb98b3ccSmatt uint64_t getSP() const { return reg[REGNO_ARM32_SP]; } 377eb98b3ccSmatt 378eb98b3ccSmatt void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; } 379eb98b3ccSmatt 380eb98b3ccSmatt bool validFloatVectorRegister(int num) const { 381155a9ee6Sjoerg return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31); 382eb98b3ccSmatt } 383eb98b3ccSmatt 384eb98b3ccSmatt void copyFloatVectorRegister(int num, uint64_t addr_) { 385d03fef5bSrin assert(validFloatVectorRegister(num)); 386155a9ee6Sjoerg const void *addr = reinterpret_cast<const void *>(addr_); 387155a9ee6Sjoerg if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) { 38885f18f75Srin if ((flags & FLAGS_VFPV2_USED) == 0) { 38985f18f75Srin lazyVFPv2(); 39085f18f75Srin flags |= FLAGS_VFPV2_USED; 391155a9ee6Sjoerg } 392155a9ee6Sjoerg /* 393155a9ee6Sjoerg * Emulate single precision register as half of the 394155a9ee6Sjoerg * corresponding double register. 395155a9ee6Sjoerg */ 396155a9ee6Sjoerg int dnum = (num - REGNO_ARM32_S0) / 2; 397155a9ee6Sjoerg int part = (num - REGNO_ARM32_S0) % 2; 398155a9ee6Sjoerg #if _BYTE_ORDER == _BIG_ENDIAN 399155a9ee6Sjoerg part = 1 - part; 400155a9ee6Sjoerg #endif 401155a9ee6Sjoerg memcpy(fpreg + dnum + part * sizeof(fpreg[0]) / 2, 402155a9ee6Sjoerg addr, sizeof(fpreg[0]) / 2); 403155a9ee6Sjoerg } 404bdd3372bSjoerg if (num <= REGNO_ARM32_D15) { 40585f18f75Srin if ((flags & FLAGS_VFPV2_USED) == 0) { 40685f18f75Srin lazyVFPv2(); 40785f18f75Srin flags |= FLAGS_VFPV2_USED; 408bdd3372bSjoerg } 409bdd3372bSjoerg } else { 41085f18f75Srin if ((flags & FLAGS_VFPV3_USED) == 0) { 41185f18f75Srin lazyVFPv3(); 41285f18f75Srin flags |= FLAGS_VFPV3_USED; 413bdd3372bSjoerg } 414bdd3372bSjoerg } 415eb98b3ccSmatt memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0])); 416eb98b3ccSmatt } 417eb98b3ccSmatt 41885f18f75Srin __dso_hidden void lazyVFPv2(); 41985f18f75Srin __dso_hidden void lazyVFPv3(); 420eb98b3ccSmatt __dso_hidden void jumpto() const __dead; 421eb98b3ccSmatt 422eb98b3ccSmatt private: 423eb98b3ccSmatt uint32_t reg[REGNO_ARM32_SPSR + 1]; 424bdd3372bSjoerg uint32_t flags; 425eb98b3ccSmatt uint64_t fpreg[32]; 42685f18f75Srin 42785f18f75Srin enum { 42885f18f75Srin FLAGS_VFPV2_USED = 0x1, 42985f18f75Srin FLAGS_VFPV3_USED = 0x2, 43085f18f75Srin }; 431eb98b3ccSmatt }; 432eb98b3ccSmatt 433396ee378Sjoerg enum { 434396ee378Sjoerg DWARF_VAX_R0 = 0, 435396ee378Sjoerg DWARF_VAX_R15 = 15, 436396ee378Sjoerg DWARF_VAX_PSW = 16, 437396ee378Sjoerg 438396ee378Sjoerg REGNO_VAX_R0 = 0, 439396ee378Sjoerg REGNO_VAX_R14 = 14, 440396ee378Sjoerg REGNO_VAX_R15 = 15, 441396ee378Sjoerg REGNO_VAX_PSW = 16, 442396ee378Sjoerg }; 443396ee378Sjoerg 444396ee378Sjoerg class Registers_vax { 445396ee378Sjoerg public: 446396ee378Sjoerg enum { 447396ee378Sjoerg LAST_REGISTER = REGNO_VAX_PSW, 448396ee378Sjoerg LAST_RESTORE_REG = REGNO_VAX_PSW, 4499788222aSjoerg RETURN_OFFSET = 0, 4500282220bSjoerg RETURN_MASK = 0, 451396ee378Sjoerg }; 452396ee378Sjoerg 453396ee378Sjoerg __dso_hidden Registers_vax(); 454396ee378Sjoerg 455396ee378Sjoerg static int dwarf2regno(int num) { 456396ee378Sjoerg if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15) 457396ee378Sjoerg return REGNO_VAX_R0 + (num - DWARF_VAX_R0); 458396ee378Sjoerg if (num == DWARF_VAX_PSW) 459396ee378Sjoerg return REGNO_VAX_PSW; 460396ee378Sjoerg return LAST_REGISTER + 1; 461396ee378Sjoerg } 462396ee378Sjoerg 463396ee378Sjoerg bool validRegister(int num) const { 464396ee378Sjoerg return num >= 0 && num <= LAST_RESTORE_REG; 465396ee378Sjoerg } 466396ee378Sjoerg 467396ee378Sjoerg uint64_t getRegister(int num) const { 468396ee378Sjoerg assert(validRegister(num)); 469396ee378Sjoerg return reg[num]; 470396ee378Sjoerg } 471396ee378Sjoerg 472396ee378Sjoerg void setRegister(int num, uint64_t value) { 473396ee378Sjoerg assert(validRegister(num)); 474396ee378Sjoerg reg[num] = value; 475396ee378Sjoerg } 476396ee378Sjoerg 477396ee378Sjoerg uint64_t getIP() const { return reg[REGNO_VAX_R15]; } 478396ee378Sjoerg 479396ee378Sjoerg void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; } 480396ee378Sjoerg 481396ee378Sjoerg uint64_t getSP() const { return reg[REGNO_VAX_R14]; } 482396ee378Sjoerg 483396ee378Sjoerg void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; } 484396ee378Sjoerg 485396ee378Sjoerg bool validFloatVectorRegister(int num) const { 486396ee378Sjoerg return false; 487396ee378Sjoerg } 488396ee378Sjoerg 489396ee378Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 490396ee378Sjoerg } 491396ee378Sjoerg 492396ee378Sjoerg __dso_hidden void jumpto() const __dead; 493396ee378Sjoerg 494396ee378Sjoerg private: 495396ee378Sjoerg uint32_t reg[REGNO_VAX_PSW + 1]; 496396ee378Sjoerg }; 497396ee378Sjoerg 498a55c6bd8Sjoerg enum { 499a55c6bd8Sjoerg DWARF_M68K_A0 = 0, 500a55c6bd8Sjoerg DWARF_M68K_A7 = 7, 501a55c6bd8Sjoerg DWARF_M68K_D0 = 8, 502a55c6bd8Sjoerg DWARF_M68K_D7 = 15, 503c05d688cSjoerg DWARF_M68K_FP0 = 16, 504c05d688cSjoerg DWARF_M68K_FP7 = 23, 505a55c6bd8Sjoerg DWARF_M68K_PC = 24, 506a55c6bd8Sjoerg 507a55c6bd8Sjoerg REGNO_M68K_A0 = 0, 508a55c6bd8Sjoerg REGNO_M68K_A7 = 7, 509a55c6bd8Sjoerg REGNO_M68K_D0 = 8, 510a55c6bd8Sjoerg REGNO_M68K_D7 = 15, 511a55c6bd8Sjoerg REGNO_M68K_PC = 16, 512c05d688cSjoerg REGNO_M68K_FP0 = 17, 513c05d688cSjoerg REGNO_M68K_FP7 = 24, 514a55c6bd8Sjoerg }; 515a55c6bd8Sjoerg 516a55c6bd8Sjoerg class Registers_M68K { 517a55c6bd8Sjoerg public: 518a55c6bd8Sjoerg enum { 519c05d688cSjoerg LAST_REGISTER = REGNO_M68K_FP7, 520c05d688cSjoerg LAST_RESTORE_REG = REGNO_M68K_FP7, 5219788222aSjoerg RETURN_OFFSET = 0, 5220282220bSjoerg RETURN_MASK = 0, 523a55c6bd8Sjoerg }; 524a55c6bd8Sjoerg 525a55c6bd8Sjoerg __dso_hidden Registers_M68K(); 526a55c6bd8Sjoerg 527a55c6bd8Sjoerg static int dwarf2regno(int num) { 528a55c6bd8Sjoerg if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7) 529a55c6bd8Sjoerg return REGNO_M68K_A0 + (num - DWARF_M68K_A0); 530a55c6bd8Sjoerg if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7) 531a55c6bd8Sjoerg return REGNO_M68K_D0 + (num - DWARF_M68K_D0); 532c05d688cSjoerg if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7) 533c05d688cSjoerg return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0); 534a55c6bd8Sjoerg if (num == DWARF_M68K_PC) 535a55c6bd8Sjoerg return REGNO_M68K_PC; 536a55c6bd8Sjoerg return LAST_REGISTER + 1; 537a55c6bd8Sjoerg } 538a55c6bd8Sjoerg 539a55c6bd8Sjoerg bool validRegister(int num) const { 540c05d688cSjoerg return num >= 0 && num <= REGNO_M68K_PC; 541a55c6bd8Sjoerg } 542a55c6bd8Sjoerg 543a55c6bd8Sjoerg uint64_t getRegister(int num) const { 544a55c6bd8Sjoerg assert(validRegister(num)); 545a55c6bd8Sjoerg return reg[num]; 546a55c6bd8Sjoerg } 547a55c6bd8Sjoerg 548a55c6bd8Sjoerg void setRegister(int num, uint64_t value) { 549a55c6bd8Sjoerg assert(validRegister(num)); 550a55c6bd8Sjoerg reg[num] = value; 551a55c6bd8Sjoerg } 552a55c6bd8Sjoerg 553a55c6bd8Sjoerg uint64_t getIP() const { return reg[REGNO_M68K_PC]; } 554a55c6bd8Sjoerg 555a55c6bd8Sjoerg void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; } 556a55c6bd8Sjoerg 557a55c6bd8Sjoerg uint64_t getSP() const { return reg[REGNO_M68K_A7]; } 558a55c6bd8Sjoerg 559a55c6bd8Sjoerg void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; } 560a55c6bd8Sjoerg 561a55c6bd8Sjoerg bool validFloatVectorRegister(int num) const { 562c05d688cSjoerg return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7; 563a55c6bd8Sjoerg } 564a55c6bd8Sjoerg 565a55c6bd8Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 566c05d688cSjoerg assert(validFloatVectorRegister(num)); 567c05d688cSjoerg const void *addr = reinterpret_cast<const void *>(addr_); 568c05d688cSjoerg memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0])); 569a55c6bd8Sjoerg } 570a55c6bd8Sjoerg 571a55c6bd8Sjoerg __dso_hidden void jumpto() const __dead; 572a55c6bd8Sjoerg 573a55c6bd8Sjoerg private: 574c05d688cSjoerg typedef uint32_t fpreg_t[3]; 575c05d688cSjoerg 576a55c6bd8Sjoerg uint32_t reg[REGNO_M68K_PC + 1]; 577c05d688cSjoerg uint32_t dummy; 578c05d688cSjoerg fpreg_t fpreg[8]; 579a55c6bd8Sjoerg }; 580a55c6bd8Sjoerg 581a280fb92Sjoerg enum { 582a280fb92Sjoerg DWARF_SH3_R0 = 0, 583a280fb92Sjoerg DWARF_SH3_R15 = 15, 584a280fb92Sjoerg DWARF_SH3_PC = 16, 585a280fb92Sjoerg DWARF_SH3_PR = 17, 586a280fb92Sjoerg 587a280fb92Sjoerg REGNO_SH3_R0 = 0, 588a280fb92Sjoerg REGNO_SH3_R15 = 15, 589a280fb92Sjoerg REGNO_SH3_PC = 16, 590a280fb92Sjoerg REGNO_SH3_PR = 17, 591a280fb92Sjoerg }; 592a280fb92Sjoerg 593a280fb92Sjoerg class Registers_SH3 { 594a280fb92Sjoerg public: 595a280fb92Sjoerg enum { 596a280fb92Sjoerg LAST_REGISTER = REGNO_SH3_PR, 597a280fb92Sjoerg LAST_RESTORE_REG = REGNO_SH3_PR, 5989788222aSjoerg RETURN_OFFSET = 0, 5990282220bSjoerg RETURN_MASK = 0, 600a280fb92Sjoerg }; 601a280fb92Sjoerg 602a280fb92Sjoerg __dso_hidden Registers_SH3(); 603a280fb92Sjoerg 604a280fb92Sjoerg static int dwarf2regno(int num) { 605a280fb92Sjoerg if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15) 606a280fb92Sjoerg return REGNO_SH3_R0 + (num - DWARF_SH3_R0); 607a280fb92Sjoerg if (num == DWARF_SH3_PC) 608a280fb92Sjoerg return REGNO_SH3_PC; 609a280fb92Sjoerg if (num == DWARF_SH3_PR) 610a280fb92Sjoerg return REGNO_SH3_PR; 611a280fb92Sjoerg return LAST_REGISTER + 1; 612a280fb92Sjoerg } 613a280fb92Sjoerg 614a280fb92Sjoerg bool validRegister(int num) const { 615a280fb92Sjoerg return num >= 0 && num <= REGNO_SH3_PR; 616a280fb92Sjoerg } 617a280fb92Sjoerg 618a280fb92Sjoerg uint64_t getRegister(int num) const { 619a280fb92Sjoerg assert(validRegister(num)); 620a280fb92Sjoerg return reg[num]; 621a280fb92Sjoerg } 622a280fb92Sjoerg 623a280fb92Sjoerg void setRegister(int num, uint64_t value) { 624a280fb92Sjoerg assert(validRegister(num)); 625a280fb92Sjoerg reg[num] = value; 626a280fb92Sjoerg } 627a280fb92Sjoerg 628a280fb92Sjoerg uint64_t getIP() const { return reg[REGNO_SH3_PC]; } 629a280fb92Sjoerg 630a280fb92Sjoerg void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; } 631a280fb92Sjoerg 632a280fb92Sjoerg uint64_t getSP() const { return reg[REGNO_SH3_R15]; } 633a280fb92Sjoerg 634a280fb92Sjoerg void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; } 635a280fb92Sjoerg 636a280fb92Sjoerg bool validFloatVectorRegister(int num) const { return false; } 637a280fb92Sjoerg 638a280fb92Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) {} 639a280fb92Sjoerg 640a280fb92Sjoerg __dso_hidden void jumpto() const __dead; 641a280fb92Sjoerg 642a280fb92Sjoerg private: 643a280fb92Sjoerg uint32_t reg[REGNO_SH3_PR + 1]; 644a280fb92Sjoerg }; 645a280fb92Sjoerg 646f5cf7457Sjoerg enum { 647f5cf7457Sjoerg DWARF_SPARC64_R0 = 0, 648f5cf7457Sjoerg DWARF_SPARC64_R31 = 31, 649f5cf7457Sjoerg DWARF_SPARC64_PC = 32, 650f5cf7457Sjoerg 651f5cf7457Sjoerg REGNO_SPARC64_R0 = 0, 652f5cf7457Sjoerg REGNO_SPARC64_R14 = 14, 653f5cf7457Sjoerg REGNO_SPARC64_R15 = 15, 654f5cf7457Sjoerg REGNO_SPARC64_R31 = 31, 655f5cf7457Sjoerg REGNO_SPARC64_PC = 32, 656f5cf7457Sjoerg }; 657f5cf7457Sjoerg 658f5cf7457Sjoerg class Registers_SPARC64 { 659f5cf7457Sjoerg public: 660f5cf7457Sjoerg enum { 661f5cf7457Sjoerg LAST_REGISTER = REGNO_SPARC64_PC, 662f5cf7457Sjoerg LAST_RESTORE_REG = REGNO_SPARC64_PC, 663f5cf7457Sjoerg RETURN_OFFSET = 8, 6640282220bSjoerg RETURN_MASK = 0, 665f5cf7457Sjoerg }; 666f5cf7457Sjoerg typedef uint64_t reg_t; 667f5cf7457Sjoerg 668f5cf7457Sjoerg __dso_hidden Registers_SPARC64(); 669f5cf7457Sjoerg 670f5cf7457Sjoerg static int dwarf2regno(int num) { 671f5cf7457Sjoerg if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31) 672f5cf7457Sjoerg return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0); 673f5cf7457Sjoerg if (num == DWARF_SPARC64_PC) 674f5cf7457Sjoerg return REGNO_SPARC64_PC; 675f5cf7457Sjoerg return LAST_REGISTER + 1; 676f5cf7457Sjoerg } 677f5cf7457Sjoerg 678f5cf7457Sjoerg bool validRegister(int num) const { 679f5cf7457Sjoerg return num >= 0 && num <= REGNO_SPARC64_PC; 680f5cf7457Sjoerg } 681f5cf7457Sjoerg 682f5cf7457Sjoerg uint64_t getRegister(int num) const { 683f5cf7457Sjoerg assert(validRegister(num)); 684f5cf7457Sjoerg return reg[num]; 685f5cf7457Sjoerg } 686f5cf7457Sjoerg 687f5cf7457Sjoerg void setRegister(int num, uint64_t value) { 688f5cf7457Sjoerg assert(validRegister(num)); 689f5cf7457Sjoerg reg[num] = value; 690f5cf7457Sjoerg } 691f5cf7457Sjoerg 692f5cf7457Sjoerg uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; } 693f5cf7457Sjoerg 694f5cf7457Sjoerg void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; } 695f5cf7457Sjoerg 696f5cf7457Sjoerg uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; } 697f5cf7457Sjoerg 698f5cf7457Sjoerg void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; } 699f5cf7457Sjoerg 700f5cf7457Sjoerg bool validFloatVectorRegister(int num) const { return false; } 701f5cf7457Sjoerg 702f5cf7457Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) {} 703f5cf7457Sjoerg 704f5cf7457Sjoerg __dso_hidden void jumpto() const __dead; 705f5cf7457Sjoerg 706f5cf7457Sjoerg private: 707f5cf7457Sjoerg uint64_t reg[REGNO_SPARC64_PC + 1]; 708f5cf7457Sjoerg }; 709f5cf7457Sjoerg 710f5cf7457Sjoerg enum { 711f5cf7457Sjoerg DWARF_SPARC_R0 = 0, 712f5cf7457Sjoerg DWARF_SPARC_R31 = 31, 713f5cf7457Sjoerg DWARF_SPARC_PC = 32, 714f5cf7457Sjoerg 715f5cf7457Sjoerg REGNO_SPARC_R0 = 0, 716f5cf7457Sjoerg REGNO_SPARC_R14 = 14, 717f5cf7457Sjoerg REGNO_SPARC_R15 = 15, 718f5cf7457Sjoerg REGNO_SPARC_R31 = 31, 719f5cf7457Sjoerg REGNO_SPARC_PC = 32, 720f5cf7457Sjoerg }; 721f5cf7457Sjoerg 722f5cf7457Sjoerg class Registers_SPARC { 723f5cf7457Sjoerg public: 724f5cf7457Sjoerg enum { 725f5cf7457Sjoerg LAST_REGISTER = REGNO_SPARC_PC, 726f5cf7457Sjoerg LAST_RESTORE_REG = REGNO_SPARC_PC, 727f5cf7457Sjoerg RETURN_OFFSET = 8, 7280282220bSjoerg RETURN_MASK = 0, 729f5cf7457Sjoerg }; 730f5cf7457Sjoerg typedef uint32_t reg_t; 731f5cf7457Sjoerg 732f5cf7457Sjoerg __dso_hidden Registers_SPARC(); 733f5cf7457Sjoerg 734f5cf7457Sjoerg static int dwarf2regno(int num) { 735f5cf7457Sjoerg if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31) 736f5cf7457Sjoerg return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0); 737f5cf7457Sjoerg if (num == DWARF_SPARC_PC) 738f5cf7457Sjoerg return REGNO_SPARC_PC; 739f5cf7457Sjoerg return LAST_REGISTER + 1; 740f5cf7457Sjoerg } 741f5cf7457Sjoerg 742f5cf7457Sjoerg bool validRegister(int num) const { 743f5cf7457Sjoerg return num >= 0 && num <= REGNO_SPARC_PC; 744f5cf7457Sjoerg } 745f5cf7457Sjoerg 746f5cf7457Sjoerg uint64_t getRegister(int num) const { 747f5cf7457Sjoerg assert(validRegister(num)); 748f5cf7457Sjoerg return reg[num]; 749f5cf7457Sjoerg } 750f5cf7457Sjoerg 751f5cf7457Sjoerg void setRegister(int num, uint64_t value) { 752f5cf7457Sjoerg assert(validRegister(num)); 753f5cf7457Sjoerg reg[num] = value; 754f5cf7457Sjoerg } 755f5cf7457Sjoerg 756f5cf7457Sjoerg uint64_t getIP() const { return reg[REGNO_SPARC_PC]; } 757f5cf7457Sjoerg 758f5cf7457Sjoerg void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; } 759f5cf7457Sjoerg 760f5cf7457Sjoerg uint64_t getSP() const { return reg[REGNO_SPARC_R14]; } 761f5cf7457Sjoerg 762f5cf7457Sjoerg void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; } 763f5cf7457Sjoerg 764f5cf7457Sjoerg bool validFloatVectorRegister(int num) const { return false; } 765f5cf7457Sjoerg 766f5cf7457Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) {} 767f5cf7457Sjoerg 768f5cf7457Sjoerg __dso_hidden void jumpto() const __dead; 769f5cf7457Sjoerg 770f5cf7457Sjoerg private: 771f5cf7457Sjoerg uint32_t reg[REGNO_SPARC_PC + 1]; 772f5cf7457Sjoerg }; 773f5cf7457Sjoerg 774e3d4269aSjoerg enum { 775e3d4269aSjoerg DWARF_ALPHA_R0 = 0, 776e3d4269aSjoerg DWARF_ALPHA_R30 = 30, 777e3d4269aSjoerg DWARF_ALPHA_F0 = 32, 778e3d4269aSjoerg DWARF_ALPHA_F30 = 62, 779e3d4269aSjoerg 780e3d4269aSjoerg REGNO_ALPHA_R0 = 0, 781e3d4269aSjoerg REGNO_ALPHA_R26 = 26, 782e3d4269aSjoerg REGNO_ALPHA_R30 = 30, 783e3d4269aSjoerg REGNO_ALPHA_PC = 31, 784e3d4269aSjoerg REGNO_ALPHA_F0 = 32, 785e3d4269aSjoerg REGNO_ALPHA_F30 = 62, 786e3d4269aSjoerg }; 787e3d4269aSjoerg 788e3d4269aSjoerg class Registers_Alpha { 789e3d4269aSjoerg public: 790e3d4269aSjoerg enum { 791e3d4269aSjoerg LAST_REGISTER = REGNO_ALPHA_F30, 792e3d4269aSjoerg LAST_RESTORE_REG = REGNO_ALPHA_F30, 793e3d4269aSjoerg RETURN_OFFSET = 0, 7940282220bSjoerg RETURN_MASK = 0, 795e3d4269aSjoerg }; 796e3d4269aSjoerg typedef uint32_t reg_t; 797e3d4269aSjoerg 798e3d4269aSjoerg __dso_hidden Registers_Alpha(); 799e3d4269aSjoerg 800e3d4269aSjoerg static int dwarf2regno(int num) { return num; } 801e3d4269aSjoerg 802e3d4269aSjoerg bool validRegister(int num) const { 803e3d4269aSjoerg return num >= 0 && num <= REGNO_ALPHA_PC; 804e3d4269aSjoerg } 805e3d4269aSjoerg 806e3d4269aSjoerg uint64_t getRegister(int num) const { 807e3d4269aSjoerg assert(validRegister(num)); 808e3d4269aSjoerg return reg[num]; 809e3d4269aSjoerg } 810e3d4269aSjoerg 811e3d4269aSjoerg void setRegister(int num, uint64_t value) { 812e3d4269aSjoerg assert(validRegister(num)); 813e3d4269aSjoerg reg[num] = value; 814e3d4269aSjoerg } 815e3d4269aSjoerg 816e3d4269aSjoerg uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; } 817e3d4269aSjoerg 818e3d4269aSjoerg void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; } 819e3d4269aSjoerg 820e3d4269aSjoerg uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; } 821e3d4269aSjoerg 822e3d4269aSjoerg void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; } 823e3d4269aSjoerg 824e3d4269aSjoerg bool validFloatVectorRegister(int num) const { 825e3d4269aSjoerg return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30; 826e3d4269aSjoerg } 827e3d4269aSjoerg 828e3d4269aSjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 829e3d4269aSjoerg assert(validFloatVectorRegister(num)); 830e3d4269aSjoerg const void *addr = reinterpret_cast<const void *>(addr_); 831e3d4269aSjoerg memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0])); 832e3d4269aSjoerg } 833e3d4269aSjoerg 834e3d4269aSjoerg __dso_hidden void jumpto() const __dead; 835e3d4269aSjoerg 836e3d4269aSjoerg private: 837e3d4269aSjoerg uint64_t reg[REGNO_ALPHA_PC + 1]; 838e3d4269aSjoerg uint64_t fpreg[31]; 839e3d4269aSjoerg }; 840e3d4269aSjoerg 841a78e9b23Sjoerg enum { 842a78e9b23Sjoerg DWARF_HPPA_R1 = 1, 843a78e9b23Sjoerg DWARF_HPPA_R31 = 31, 844a78e9b23Sjoerg DWARF_HPPA_FR4L = 32, 845a78e9b23Sjoerg DWARF_HPPA_FR31H = 87, 846a78e9b23Sjoerg 847a78e9b23Sjoerg REGNO_HPPA_PC = 0, 848a78e9b23Sjoerg REGNO_HPPA_R1 = 1, 849a78e9b23Sjoerg REGNO_HPPA_R2 = 2, 850a78e9b23Sjoerg REGNO_HPPA_R30 = 30, 851a78e9b23Sjoerg REGNO_HPPA_R31 = 31, 852a78e9b23Sjoerg REGNO_HPPA_FR4L = 32, 853a78e9b23Sjoerg REGNO_HPPA_FR31H = 87, 854a78e9b23Sjoerg }; 855a78e9b23Sjoerg 856a78e9b23Sjoerg class Registers_HPPA { 857a78e9b23Sjoerg public: 858a78e9b23Sjoerg enum { 859a78e9b23Sjoerg LAST_REGISTER = REGNO_HPPA_FR31H, 860a78e9b23Sjoerg LAST_RESTORE_REG = REGNO_HPPA_FR31H, 8610282220bSjoerg RETURN_OFFSET = 0, 8620282220bSjoerg RETURN_MASK = 3, 863a78e9b23Sjoerg }; 864a78e9b23Sjoerg 865a78e9b23Sjoerg __dso_hidden Registers_HPPA(); 866a78e9b23Sjoerg 867a78e9b23Sjoerg static int dwarf2regno(int num) { 868a78e9b23Sjoerg if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31) 869a78e9b23Sjoerg return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1); 870a78e9b23Sjoerg if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H) 871a78e9b23Sjoerg return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H); 872a78e9b23Sjoerg return LAST_REGISTER + 1; 873a78e9b23Sjoerg } 874a78e9b23Sjoerg 875a78e9b23Sjoerg bool validRegister(int num) const { 876a78e9b23Sjoerg return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31; 877a78e9b23Sjoerg } 878a78e9b23Sjoerg 879a78e9b23Sjoerg uint64_t getRegister(int num) const { 880a78e9b23Sjoerg assert(validRegister(num)); 881a78e9b23Sjoerg return reg[num]; 882a78e9b23Sjoerg } 883a78e9b23Sjoerg 884a78e9b23Sjoerg void setRegister(int num, uint64_t value) { 885a78e9b23Sjoerg assert(validRegister(num)); 886a78e9b23Sjoerg reg[num] = value; 887a78e9b23Sjoerg } 888a78e9b23Sjoerg 889a78e9b23Sjoerg uint64_t getIP() const { return reg[REGNO_HPPA_PC]; } 890a78e9b23Sjoerg 891a78e9b23Sjoerg void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; } 892a78e9b23Sjoerg 893a78e9b23Sjoerg uint64_t getSP() const { return reg[REGNO_HPPA_R30]; } 894a78e9b23Sjoerg 895a78e9b23Sjoerg void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; } 896a78e9b23Sjoerg 897a78e9b23Sjoerg bool validFloatVectorRegister(int num) const { 898a78e9b23Sjoerg return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H; 899a78e9b23Sjoerg } 900a78e9b23Sjoerg 901a78e9b23Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 902a78e9b23Sjoerg assert(validFloatVectorRegister(num)); 903a78e9b23Sjoerg const void *addr = reinterpret_cast<const void *>(addr_); 904a78e9b23Sjoerg memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0])); 905a78e9b23Sjoerg } 906a78e9b23Sjoerg 907a78e9b23Sjoerg __dso_hidden void jumpto() const __dead; 908a78e9b23Sjoerg 909a78e9b23Sjoerg private: 910a78e9b23Sjoerg uint32_t reg[REGNO_HPPA_R31 + 1]; 911a78e9b23Sjoerg uint32_t fpreg[56]; 912a78e9b23Sjoerg }; 913a78e9b23Sjoerg 914ed444622Sjoerg enum { 915ed444622Sjoerg DWARF_MIPS_R1 = 0, 916ed444622Sjoerg DWARF_MIPS_R31 = 31, 917ed444622Sjoerg DWARF_MIPS_F0 = 32, 918ed444622Sjoerg DWARF_MIPS_F31 = 63, 919ed444622Sjoerg 920ed444622Sjoerg REGNO_MIPS_PC = 0, 921ed444622Sjoerg REGNO_MIPS_R1 = 0, 922ed444622Sjoerg REGNO_MIPS_R29 = 29, 923ed444622Sjoerg REGNO_MIPS_R31 = 31, 924ed444622Sjoerg REGNO_MIPS_F0 = 33, 925ed444622Sjoerg REGNO_MIPS_F31 = 64 926ed444622Sjoerg }; 927ed444622Sjoerg 928ed444622Sjoerg class Registers_MIPS { 929ed444622Sjoerg public: 930ed444622Sjoerg enum { 931ed444622Sjoerg LAST_REGISTER = REGNO_MIPS_F31, 932ed444622Sjoerg LAST_RESTORE_REG = REGNO_MIPS_F31, 933ed444622Sjoerg RETURN_OFFSET = 0, 9340282220bSjoerg RETURN_MASK = 0, 935ed444622Sjoerg }; 936ed444622Sjoerg 937ed444622Sjoerg __dso_hidden Registers_MIPS(); 938ed444622Sjoerg 939ed444622Sjoerg static int dwarf2regno(int num) { 940ed444622Sjoerg if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31) 941ed444622Sjoerg return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1); 942ed444622Sjoerg if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31) 943ed444622Sjoerg return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0); 944ed444622Sjoerg return LAST_REGISTER + 1; 945ed444622Sjoerg } 946ed444622Sjoerg 947ed444622Sjoerg bool validRegister(int num) const { 948ed444622Sjoerg return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31; 949ed444622Sjoerg } 950ed444622Sjoerg 951ed444622Sjoerg uint64_t getRegister(int num) const { 952ed444622Sjoerg assert(validRegister(num)); 953ed444622Sjoerg return reg[num]; 954ed444622Sjoerg } 955ed444622Sjoerg 956ed444622Sjoerg void setRegister(int num, uint64_t value) { 957ed444622Sjoerg assert(validRegister(num)); 958ed444622Sjoerg reg[num] = value; 959ed444622Sjoerg } 960ed444622Sjoerg 961ed444622Sjoerg uint64_t getIP() const { return reg[REGNO_MIPS_PC]; } 962ed444622Sjoerg 963ed444622Sjoerg void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; } 964ed444622Sjoerg 965ed444622Sjoerg uint64_t getSP() const { return reg[REGNO_MIPS_R29]; } 966ed444622Sjoerg 967ed444622Sjoerg void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; } 968ed444622Sjoerg 969ed444622Sjoerg bool validFloatVectorRegister(int num) const { 970ed444622Sjoerg return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31; 971ed444622Sjoerg } 972ed444622Sjoerg 973ed444622Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 974ed444622Sjoerg assert(validFloatVectorRegister(num)); 975ed444622Sjoerg const void *addr = reinterpret_cast<const void *>(addr_); 976ed444622Sjoerg memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0])); 977ed444622Sjoerg } 978ed444622Sjoerg 979ed444622Sjoerg __dso_hidden void jumpto() const __dead; 980ed444622Sjoerg 981ed444622Sjoerg private: 982ed444622Sjoerg uint32_t reg[REGNO_MIPS_R31 + 1]; 983ed444622Sjoerg uint64_t fpreg[32]; 984ed444622Sjoerg }; 985ed444622Sjoerg 986ed444622Sjoerg enum { 987ed444622Sjoerg DWARF_MIPS64_R1 = 0, 988ed444622Sjoerg DWARF_MIPS64_R31 = 31, 989ed444622Sjoerg DWARF_MIPS64_F0 = 32, 990ed444622Sjoerg DWARF_MIPS64_F31 = 63, 991ed444622Sjoerg 992ed444622Sjoerg REGNO_MIPS64_PC = 0, 993ed444622Sjoerg REGNO_MIPS64_R1 = 0, 994ed444622Sjoerg REGNO_MIPS64_R29 = 29, 995ed444622Sjoerg REGNO_MIPS64_R31 = 31, 996ed444622Sjoerg REGNO_MIPS64_F0 = 33, 997ed444622Sjoerg REGNO_MIPS64_F31 = 64 998ed444622Sjoerg }; 999ed444622Sjoerg 1000ed444622Sjoerg class Registers_MIPS64 { 1001ed444622Sjoerg public: 1002ed444622Sjoerg enum { 1003ed444622Sjoerg LAST_REGISTER = REGNO_MIPS64_F31, 1004ed444622Sjoerg LAST_RESTORE_REG = REGNO_MIPS64_F31, 1005ed444622Sjoerg RETURN_OFFSET = 0, 10060282220bSjoerg RETURN_MASK = 0, 1007ed444622Sjoerg }; 1008ed444622Sjoerg 1009ed444622Sjoerg __dso_hidden Registers_MIPS64(); 1010ed444622Sjoerg 1011ed444622Sjoerg static int dwarf2regno(int num) { 1012ed444622Sjoerg if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31) 1013ed444622Sjoerg return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1); 1014ed444622Sjoerg if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31) 1015ed444622Sjoerg return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0); 1016ed444622Sjoerg return LAST_REGISTER + 1; 1017ed444622Sjoerg } 1018ed444622Sjoerg 1019ed444622Sjoerg bool validRegister(int num) const { 1020ed444622Sjoerg return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31; 1021ed444622Sjoerg } 1022ed444622Sjoerg 1023ed444622Sjoerg uint64_t getRegister(int num) const { 1024ed444622Sjoerg assert(validRegister(num)); 1025ed444622Sjoerg return reg[num]; 1026ed444622Sjoerg } 1027ed444622Sjoerg 1028ed444622Sjoerg void setRegister(int num, uint64_t value) { 1029ed444622Sjoerg assert(validRegister(num)); 1030ed444622Sjoerg reg[num] = value; 1031ed444622Sjoerg } 1032ed444622Sjoerg 1033ed444622Sjoerg uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; } 1034ed444622Sjoerg 1035ed444622Sjoerg void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; } 1036ed444622Sjoerg 1037ed444622Sjoerg uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; } 1038ed444622Sjoerg 1039ed444622Sjoerg void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; } 1040ed444622Sjoerg 1041ed444622Sjoerg bool validFloatVectorRegister(int num) const { 1042ed444622Sjoerg return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31; 1043ed444622Sjoerg } 1044ed444622Sjoerg 1045ed444622Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 1046ed444622Sjoerg assert(validFloatVectorRegister(num)); 1047ed444622Sjoerg const void *addr = reinterpret_cast<const void *>(addr_); 1048ed444622Sjoerg memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0])); 1049ed444622Sjoerg } 1050ed444622Sjoerg 1051ed444622Sjoerg __dso_hidden void jumpto() const __dead; 1052ed444622Sjoerg 1053ed444622Sjoerg private: 1054ed444622Sjoerg uint64_t reg[REGNO_MIPS64_R31 + 1]; 1055ed444622Sjoerg uint64_t fpreg[32]; 1056ed444622Sjoerg }; 1057ed444622Sjoerg 1058938bf86eSmatt enum { 1059938bf86eSmatt DWARF_OR1K_R0 = 0, 1060938bf86eSmatt DWARF_OR1K_SP = 1, 1061938bf86eSmatt DWARF_OR1K_LR = 9, 1062938bf86eSmatt DWARF_OR1K_R31 = 31, 1063938bf86eSmatt DWARF_OR1K_FPCSR = 32, 1064938bf86eSmatt 1065938bf86eSmatt REGNO_OR1K_R0 = 0, 1066938bf86eSmatt REGNO_OR1K_SP = 1, 1067938bf86eSmatt REGNO_OR1K_LR = 9, 1068938bf86eSmatt REGNO_OR1K_R31 = 31, 1069938bf86eSmatt REGNO_OR1K_FPCSR = 32, 1070938bf86eSmatt }; 1071938bf86eSmatt 1072938bf86eSmatt class Registers_or1k { 1073938bf86eSmatt public: 1074938bf86eSmatt enum { 1075938bf86eSmatt LAST_REGISTER = REGNO_OR1K_FPCSR, 1076938bf86eSmatt LAST_RESTORE_REG = REGNO_OR1K_FPCSR, 1077938bf86eSmatt RETURN_OFFSET = 0, 10780282220bSjoerg RETURN_MASK = 0, 1079938bf86eSmatt }; 1080938bf86eSmatt 1081938bf86eSmatt __dso_hidden Registers_or1k(); 1082938bf86eSmatt 1083938bf86eSmatt static int dwarf2regno(int num) { 1084938bf86eSmatt if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31) 1085938bf86eSmatt return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0); 1086938bf86eSmatt if (num == DWARF_OR1K_FPCSR) 1087938bf86eSmatt return REGNO_OR1K_FPCSR; 1088938bf86eSmatt return LAST_REGISTER + 1; 1089938bf86eSmatt } 1090938bf86eSmatt 1091938bf86eSmatt bool validRegister(int num) const { 1092938bf86eSmatt return num >= 0 && num <= LAST_RESTORE_REG; 1093938bf86eSmatt } 1094938bf86eSmatt 1095938bf86eSmatt uint64_t getRegister(int num) const { 1096938bf86eSmatt assert(validRegister(num)); 1097938bf86eSmatt return reg[num]; 1098938bf86eSmatt } 1099938bf86eSmatt 1100938bf86eSmatt void setRegister(int num, uint64_t value) { 1101938bf86eSmatt assert(validRegister(num)); 1102938bf86eSmatt reg[num] = value; 1103938bf86eSmatt } 1104938bf86eSmatt 1105938bf86eSmatt uint64_t getIP() const { return reg[REGNO_OR1K_LR]; } 1106938bf86eSmatt 1107938bf86eSmatt void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; } 1108938bf86eSmatt 1109938bf86eSmatt uint64_t getSP() const { return reg[REGNO_OR1K_SP]; } 1110938bf86eSmatt 1111938bf86eSmatt void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; } 1112938bf86eSmatt 1113938bf86eSmatt bool validFloatVectorRegister(int num) const { 1114938bf86eSmatt return false; 1115938bf86eSmatt } 1116938bf86eSmatt 1117938bf86eSmatt void copyFloatVectorRegister(int num, uint64_t addr_) { 1118938bf86eSmatt } 1119938bf86eSmatt 1120938bf86eSmatt __dso_hidden void jumpto() const __dead; 1121938bf86eSmatt 1122938bf86eSmatt private: 1123938bf86eSmatt uint32_t reg[REGNO_OR1K_FPCSR + 1]; 1124938bf86eSmatt }; 1125938bf86eSmatt 1126a6ecde39Sjoerg #if __i386__ 1127a6ecde39Sjoerg typedef Registers_x86 NativeUnwindRegisters; 1128a6ecde39Sjoerg #elif __x86_64__ 1129a6ecde39Sjoerg typedef Registers_x86_64 NativeUnwindRegisters; 1130a6ecde39Sjoerg #elif __powerpc__ 1131a6ecde39Sjoerg typedef Registers_ppc32 NativeUnwindRegisters; 1132aa37019dSmatt #elif __aarch64__ 1133aa37019dSmatt typedef Registers_aarch64 NativeUnwindRegisters; 1134bdd3372bSjoerg #elif __arm__ 1135a6ecde39Sjoerg typedef Registers_arm32 NativeUnwindRegisters; 1136a6ecde39Sjoerg #elif __vax__ 1137a6ecde39Sjoerg typedef Registers_vax NativeUnwindRegisters; 1138a6ecde39Sjoerg #elif __m68k__ 1139a6ecde39Sjoerg typedef Registers_M68K NativeUnwindRegisters; 1140ed444622Sjoerg #elif __mips_n64 || __mips_n32 1141ed444622Sjoerg typedef Registers_MIPS64 NativeUnwindRegisters; 1142ed444622Sjoerg #elif __mips__ 1143ed444622Sjoerg typedef Registers_MIPS NativeUnwindRegisters; 1144a6ecde39Sjoerg #elif __sh3__ 1145a6ecde39Sjoerg typedef Registers_SH3 NativeUnwindRegisters; 1146f5cf7457Sjoerg #elif __sparc64__ 1147f5cf7457Sjoerg typedef Registers_SPARC64 NativeUnwindRegisters; 1148f5cf7457Sjoerg #elif __sparc__ 1149f5cf7457Sjoerg typedef Registers_SPARC NativeUnwindRegisters; 1150e3d4269aSjoerg #elif __alpha__ 1151e3d4269aSjoerg typedef Registers_Alpha NativeUnwindRegisters; 1152a78e9b23Sjoerg #elif __hppa__ 1153a78e9b23Sjoerg typedef Registers_HPPA NativeUnwindRegisters; 1154938bf86eSmatt #elif __or1k__ 1155938bf86eSmatt typedef Registers_or1k NativeUnwindRegisters; 1156a6ecde39Sjoerg #endif 1157aa0b96d0Sjoerg } // namespace _Unwind 1158aa0b96d0Sjoerg 1159aa0b96d0Sjoerg #endif // __REGISTERS_HPP__ 1160