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 15aa0b96d0Sjoerg #include <cassert> 16aa0b96d0Sjoerg #include <cstdint> 17aa0b96d0Sjoerg 18aa0b96d0Sjoerg namespace _Unwind { 19aa0b96d0Sjoerg 20aa0b96d0Sjoerg enum { 21aa0b96d0Sjoerg REGNO_X86_EAX = 0, 22aa0b96d0Sjoerg REGNO_X86_ECX = 1, 23aa0b96d0Sjoerg REGNO_X86_EDX = 2, 24aa0b96d0Sjoerg REGNO_X86_EBX = 3, 25aa0b96d0Sjoerg REGNO_X86_ESP = 4, 26aa0b96d0Sjoerg REGNO_X86_EBP = 5, 27aa0b96d0Sjoerg REGNO_X86_ESI = 6, 28aa0b96d0Sjoerg REGNO_X86_EDI = 7, 29aa0b96d0Sjoerg REGNO_X86_EIP = 8, 30aa0b96d0Sjoerg }; 31aa0b96d0Sjoerg 32aa0b96d0Sjoerg class Registers_x86 { 33aa0b96d0Sjoerg public: 34aa0b96d0Sjoerg enum { 35aa0b96d0Sjoerg LAST_REGISTER = REGNO_X86_EIP, 36916de6d0Sjoerg LAST_RESTORE_REG = REGNO_X86_EIP, 37916de6d0Sjoerg RETURN_REG = REGNO_X86_EIP, 38*9788222aSjoerg RETURN_OFFSET = 0, 39aa0b96d0Sjoerg }; 40aa0b96d0Sjoerg 41aa0b96d0Sjoerg __dso_hidden Registers_x86(); 42aa0b96d0Sjoerg 43aa0b96d0Sjoerg static int dwarf2regno(int num) { return num; } 44aa0b96d0Sjoerg 45aa0b96d0Sjoerg bool validRegister(int num) const { 46aa0b96d0Sjoerg return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI; 47aa0b96d0Sjoerg } 48aa0b96d0Sjoerg 49aa0b96d0Sjoerg uint32_t getRegister(int num) const { 50aa0b96d0Sjoerg assert(validRegister(num)); 51aa0b96d0Sjoerg return reg[num]; 52aa0b96d0Sjoerg } 53aa0b96d0Sjoerg 54aa0b96d0Sjoerg void setRegister(int num, uint32_t value) { 55aa0b96d0Sjoerg assert(validRegister(num)); 56aa0b96d0Sjoerg reg[num] = value; 57aa0b96d0Sjoerg } 58aa0b96d0Sjoerg 59aa0b96d0Sjoerg uint32_t getIP() const { return reg[REGNO_X86_EIP]; } 60aa0b96d0Sjoerg 61aa0b96d0Sjoerg void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; } 62aa0b96d0Sjoerg 63aa0b96d0Sjoerg uint32_t getSP() const { return reg[REGNO_X86_ESP]; } 64aa0b96d0Sjoerg 65aa0b96d0Sjoerg void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; } 66aa0b96d0Sjoerg 67aa0b96d0Sjoerg bool validFloatVectorRegister(int num) const { return false; } 68aa0b96d0Sjoerg 69aa0b96d0Sjoerg void copyFloatVectorRegister(int num, uint32_t addr) { 70aa0b96d0Sjoerg } 71aa0b96d0Sjoerg 72aa0b96d0Sjoerg __dso_hidden void jumpto() const __dead; 73aa0b96d0Sjoerg 74aa0b96d0Sjoerg private: 75aa0b96d0Sjoerg uint32_t reg[REGNO_X86_EIP + 1]; 76aa0b96d0Sjoerg }; 77aa0b96d0Sjoerg 78aa0b96d0Sjoerg enum { 79aa0b96d0Sjoerg REGNO_X86_64_RAX = 0, 80aa0b96d0Sjoerg REGNO_X86_64_RDX = 1, 81aa0b96d0Sjoerg REGNO_X86_64_RCX = 2, 82aa0b96d0Sjoerg REGNO_X86_64_RBX = 3, 83aa0b96d0Sjoerg REGNO_X86_64_RSI = 4, 84aa0b96d0Sjoerg REGNO_X86_64_RDI = 5, 85aa0b96d0Sjoerg REGNO_X86_64_RBP = 6, 86aa0b96d0Sjoerg REGNO_X86_64_RSP = 7, 87aa0b96d0Sjoerg REGNO_X86_64_R8 = 8, 88aa0b96d0Sjoerg REGNO_X86_64_R9 = 9, 89aa0b96d0Sjoerg REGNO_X86_64_R10 = 10, 90aa0b96d0Sjoerg REGNO_X86_64_R11 = 11, 91aa0b96d0Sjoerg REGNO_X86_64_R12 = 12, 92aa0b96d0Sjoerg REGNO_X86_64_R13 = 13, 93aa0b96d0Sjoerg REGNO_X86_64_R14 = 14, 94aa0b96d0Sjoerg REGNO_X86_64_R15 = 15, 95aa0b96d0Sjoerg REGNO_X86_64_RIP = 16, 96aa0b96d0Sjoerg }; 97aa0b96d0Sjoerg 98aa0b96d0Sjoerg class Registers_x86_64 { 99aa0b96d0Sjoerg public: 100aa0b96d0Sjoerg enum { 101aa0b96d0Sjoerg LAST_REGISTER = REGNO_X86_64_RIP, 102916de6d0Sjoerg LAST_RESTORE_REG = REGNO_X86_64_RIP, 103916de6d0Sjoerg RETURN_REG = REGNO_X86_64_RIP, 104*9788222aSjoerg RETURN_OFFSET = 0, 105aa0b96d0Sjoerg }; 106aa0b96d0Sjoerg 107aa0b96d0Sjoerg __dso_hidden Registers_x86_64(); 108aa0b96d0Sjoerg 109aa0b96d0Sjoerg static int dwarf2regno(int num) { return num; } 110aa0b96d0Sjoerg 111aa0b96d0Sjoerg bool validRegister(int num) const { 112aa0b96d0Sjoerg return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15; 113aa0b96d0Sjoerg } 114aa0b96d0Sjoerg 115aa0b96d0Sjoerg uint64_t getRegister(int num) const { 116aa0b96d0Sjoerg assert(validRegister(num)); 117aa0b96d0Sjoerg return reg[num]; 118aa0b96d0Sjoerg } 119aa0b96d0Sjoerg 120aa0b96d0Sjoerg void setRegister(int num, uint64_t value) { 121aa0b96d0Sjoerg assert(validRegister(num)); 122aa0b96d0Sjoerg reg[num] = value; 123aa0b96d0Sjoerg } 124aa0b96d0Sjoerg 125aa0b96d0Sjoerg uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; } 126aa0b96d0Sjoerg 127aa0b96d0Sjoerg void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; } 128aa0b96d0Sjoerg 129aa0b96d0Sjoerg uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; } 130aa0b96d0Sjoerg 131aa0b96d0Sjoerg void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; } 132aa0b96d0Sjoerg 133aa0b96d0Sjoerg bool validFloatVectorRegister(int num) const { return false; } 134aa0b96d0Sjoerg 135aa0b96d0Sjoerg void copyFloatVectorRegister(int num, uint64_t addr) { 136aa0b96d0Sjoerg } 137aa0b96d0Sjoerg 138aa0b96d0Sjoerg __dso_hidden void jumpto() const __dead; 139aa0b96d0Sjoerg 140aa0b96d0Sjoerg private: 141aa0b96d0Sjoerg uint64_t reg[REGNO_X86_64_RIP + 1]; 142aa0b96d0Sjoerg }; 143aa0b96d0Sjoerg 144aa0b96d0Sjoerg enum { 145aa0b96d0Sjoerg DWARF_PPC32_R0 = 0, 146aa0b96d0Sjoerg DWARF_PPC32_R31 = 31, 147aa0b96d0Sjoerg DWARF_PPC32_F0 = 32, 148aa0b96d0Sjoerg DWARF_PPC32_F31 = 63, 149aa0b96d0Sjoerg DWARF_PPC32_LR = 65, 150b238bfcaSjoerg DWARF_PPC32_CR = 70, 151b238bfcaSjoerg DWARF_PPC32_V0 = 77, 152b238bfcaSjoerg DWARF_PPC32_V31 = 108, 153b238bfcaSjoerg 154aa0b96d0Sjoerg REGNO_PPC32_R0 = 0, 155b238bfcaSjoerg REGNO_PPC32_R1 = 1, 156aa0b96d0Sjoerg REGNO_PPC32_R31 = 31, 157b238bfcaSjoerg REGNO_PPC32_LR = 32, 158b238bfcaSjoerg REGNO_PPC32_CR = 33, 159b238bfcaSjoerg REGNO_PPC32_SRR0 = 34, 160b238bfcaSjoerg 161aa0b96d0Sjoerg REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1, 162aa0b96d0Sjoerg REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31, 163aa0b96d0Sjoerg REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1, 164aa0b96d0Sjoerg REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31, 165aa0b96d0Sjoerg }; 166aa0b96d0Sjoerg 167aa0b96d0Sjoerg class Registers_ppc32 { 168aa0b96d0Sjoerg public: 169aa0b96d0Sjoerg enum { 170aa0b96d0Sjoerg LAST_REGISTER = REGNO_PPC32_V31, 171916de6d0Sjoerg LAST_RESTORE_REG = REGNO_PPC32_V31, 172916de6d0Sjoerg RETURN_REG = REGNO_PPC32_LR, 173*9788222aSjoerg RETURN_OFFSET = 0, 174aa0b96d0Sjoerg }; 175aa0b96d0Sjoerg 176aa0b96d0Sjoerg __dso_hidden Registers_ppc32(); 177aa0b96d0Sjoerg 178aa0b96d0Sjoerg static int dwarf2regno(int num) { 179aa0b96d0Sjoerg if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31) 180aa0b96d0Sjoerg return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0); 181aa0b96d0Sjoerg if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31) 182aa0b96d0Sjoerg return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0); 183aa0b96d0Sjoerg if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31) 184aa0b96d0Sjoerg return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0); 185b238bfcaSjoerg switch (num) { 186b238bfcaSjoerg case DWARF_PPC32_LR: 187b238bfcaSjoerg return REGNO_PPC32_LR; 188b238bfcaSjoerg case DWARF_PPC32_CR: 189b238bfcaSjoerg return REGNO_PPC32_CR; 190b238bfcaSjoerg default: 191aa0b96d0Sjoerg return LAST_REGISTER + 1; 192aa0b96d0Sjoerg } 193b238bfcaSjoerg } 194aa0b96d0Sjoerg 195aa0b96d0Sjoerg bool validRegister(int num) const { 196aa0b96d0Sjoerg return num >= 0 && num <= LAST_RESTORE_REG; 197aa0b96d0Sjoerg } 198aa0b96d0Sjoerg 199aa0b96d0Sjoerg uint64_t getRegister(int num) const { 200aa0b96d0Sjoerg assert(validRegister(num)); 201aa0b96d0Sjoerg return reg[num]; 202aa0b96d0Sjoerg } 203aa0b96d0Sjoerg 204aa0b96d0Sjoerg void setRegister(int num, uint64_t value) { 205aa0b96d0Sjoerg assert(validRegister(num)); 206aa0b96d0Sjoerg reg[num] = value; 207aa0b96d0Sjoerg } 208aa0b96d0Sjoerg 209aa0b96d0Sjoerg uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; } 210aa0b96d0Sjoerg 211aa0b96d0Sjoerg void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; } 212aa0b96d0Sjoerg 213aa0b96d0Sjoerg uint64_t getSP() const { return reg[REGNO_PPC32_R1]; } 214aa0b96d0Sjoerg 215aa0b96d0Sjoerg void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; } 216aa0b96d0Sjoerg 217aa0b96d0Sjoerg bool validFloatVectorRegister(int num) const { 218aa0b96d0Sjoerg return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) || 219aa0b96d0Sjoerg (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31); 220aa0b96d0Sjoerg } 221aa0b96d0Sjoerg 222aa0b96d0Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 223aa0b96d0Sjoerg const void *addr = reinterpret_cast<const void *>(addr_); 224aa0b96d0Sjoerg if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) 225aa0b96d0Sjoerg memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0])); 226aa0b96d0Sjoerg else 227aa0b96d0Sjoerg memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0])); 228aa0b96d0Sjoerg } 229aa0b96d0Sjoerg 230aa0b96d0Sjoerg __dso_hidden void jumpto() const __dead; 231aa0b96d0Sjoerg 232aa0b96d0Sjoerg private: 233aa0b96d0Sjoerg struct vecreg_t { 234aa0b96d0Sjoerg uint64_t low, high; 235aa0b96d0Sjoerg }; 236aa0b96d0Sjoerg uint32_t reg[REGNO_PPC32_SRR0 + 1]; 237b238bfcaSjoerg uint32_t dummy; 238aa0b96d0Sjoerg uint64_t fpreg[32]; 239aa0b96d0Sjoerg vecreg_t vecreg[64]; 240aa0b96d0Sjoerg }; 241aa0b96d0Sjoerg 242eb98b3ccSmatt enum { 243eb98b3ccSmatt DWARF_ARM32_R0 = 0, 244eb98b3ccSmatt DWARF_ARM32_R15 = 15, 245eb98b3ccSmatt DWARF_ARM32_SPSR = 128, 246eb98b3ccSmatt DWARF_ARM32_D0 = 256, // VFP-v3/Neon 247eb98b3ccSmatt DWARF_ARM32_D31 = 287, 248eb98b3ccSmatt REGNO_ARM32_R0 = 0, 249eb98b3ccSmatt REGNO_ARM32_SP = 13, 250eb98b3ccSmatt REGNO_ARM32_R15 = 15, 251eb98b3ccSmatt REGNO_ARM32_SPSR = 16, 252eb98b3ccSmatt REGNO_ARM32_D0 = 0, 253eb98b3ccSmatt REGNO_ARM32_D31 = 31, 254eb98b3ccSmatt }; 255eb98b3ccSmatt 256eb98b3ccSmatt class Registers_arm32 { 257eb98b3ccSmatt public: 258eb98b3ccSmatt enum { 259eb98b3ccSmatt LAST_REGISTER = REGNO_ARM32_D31, 260916de6d0Sjoerg LAST_RESTORE_REG = REGNO_ARM32_SPSR, 261916de6d0Sjoerg RETURN_REG = REGNO_ARM32_SPSR, 262*9788222aSjoerg RETURN_OFFSET = 0, 263eb98b3ccSmatt }; 264eb98b3ccSmatt 265eb98b3ccSmatt __dso_hidden Registers_arm32(); 266eb98b3ccSmatt 267eb98b3ccSmatt static int dwarf2regno(int num) { 268eb98b3ccSmatt if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15) 269eb98b3ccSmatt return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0); 270eb98b3ccSmatt if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31) 271eb98b3ccSmatt return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0); 272eb98b3ccSmatt if (num == DWARF_ARM32_SPSR) 273eb98b3ccSmatt return REGNO_ARM32_SPSR; 274eb98b3ccSmatt return LAST_REGISTER + 1; 275eb98b3ccSmatt } 276eb98b3ccSmatt 277eb98b3ccSmatt bool validRegister(int num) const { 278eb98b3ccSmatt return num >= 0 && num <= LAST_RESTORE_REG; 279eb98b3ccSmatt } 280eb98b3ccSmatt 281eb98b3ccSmatt uint64_t getRegister(int num) const { 282eb98b3ccSmatt assert(validRegister(num)); 283eb98b3ccSmatt return reg[num]; 284eb98b3ccSmatt } 285eb98b3ccSmatt 286eb98b3ccSmatt void setRegister(int num, uint64_t value) { 287eb98b3ccSmatt assert(validRegister(num)); 288eb98b3ccSmatt reg[num] = value; 289eb98b3ccSmatt } 290eb98b3ccSmatt 291eb98b3ccSmatt uint64_t getIP() const { return reg[REGNO_ARM32_R15]; } 292eb98b3ccSmatt 293eb98b3ccSmatt void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; } 294eb98b3ccSmatt 295eb98b3ccSmatt uint64_t getSP() const { return reg[REGNO_ARM32_SP]; } 296eb98b3ccSmatt 297eb98b3ccSmatt void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; } 298eb98b3ccSmatt 299eb98b3ccSmatt bool validFloatVectorRegister(int num) const { 300eb98b3ccSmatt return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31); 301eb98b3ccSmatt } 302eb98b3ccSmatt 303eb98b3ccSmatt void copyFloatVectorRegister(int num, uint64_t addr_) { 304eb98b3ccSmatt const void *addr = reinterpret_cast<const void *>(addr_); 305eb98b3ccSmatt memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0])); 306eb98b3ccSmatt } 307eb98b3ccSmatt 308eb98b3ccSmatt __dso_hidden void jumpto() const __dead; 309eb98b3ccSmatt 310eb98b3ccSmatt private: 311eb98b3ccSmatt uint32_t reg[REGNO_ARM32_SPSR + 1]; 312eb98b3ccSmatt uint64_t fpreg[32]; 313eb98b3ccSmatt }; 314eb98b3ccSmatt 315396ee378Sjoerg enum { 316396ee378Sjoerg DWARF_VAX_R0 = 0, 317396ee378Sjoerg DWARF_VAX_R15 = 15, 318396ee378Sjoerg DWARF_VAX_PSW = 16, 319396ee378Sjoerg 320396ee378Sjoerg REGNO_VAX_R0 = 0, 321396ee378Sjoerg REGNO_VAX_R14 = 14, 322396ee378Sjoerg REGNO_VAX_R15 = 15, 323396ee378Sjoerg REGNO_VAX_PSW = 16, 324396ee378Sjoerg }; 325396ee378Sjoerg 326396ee378Sjoerg class Registers_vax { 327396ee378Sjoerg public: 328396ee378Sjoerg enum { 329396ee378Sjoerg LAST_REGISTER = REGNO_VAX_PSW, 330396ee378Sjoerg LAST_RESTORE_REG = REGNO_VAX_PSW, 331396ee378Sjoerg RETURN_REG = REGNO_VAX_R15, 332*9788222aSjoerg RETURN_OFFSET = 0, 333396ee378Sjoerg }; 334396ee378Sjoerg 335396ee378Sjoerg __dso_hidden Registers_vax(); 336396ee378Sjoerg 337396ee378Sjoerg static int dwarf2regno(int num) { 338396ee378Sjoerg if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15) 339396ee378Sjoerg return REGNO_VAX_R0 + (num - DWARF_VAX_R0); 340396ee378Sjoerg if (num == DWARF_VAX_PSW) 341396ee378Sjoerg return REGNO_VAX_PSW; 342396ee378Sjoerg return LAST_REGISTER + 1; 343396ee378Sjoerg } 344396ee378Sjoerg 345396ee378Sjoerg bool validRegister(int num) const { 346396ee378Sjoerg return num >= 0 && num <= LAST_RESTORE_REG; 347396ee378Sjoerg } 348396ee378Sjoerg 349396ee378Sjoerg uint64_t getRegister(int num) const { 350396ee378Sjoerg assert(validRegister(num)); 351396ee378Sjoerg return reg[num]; 352396ee378Sjoerg } 353396ee378Sjoerg 354396ee378Sjoerg void setRegister(int num, uint64_t value) { 355396ee378Sjoerg assert(validRegister(num)); 356396ee378Sjoerg reg[num] = value; 357396ee378Sjoerg } 358396ee378Sjoerg 359396ee378Sjoerg uint64_t getIP() const { return reg[REGNO_VAX_R15]; } 360396ee378Sjoerg 361396ee378Sjoerg void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; } 362396ee378Sjoerg 363396ee378Sjoerg uint64_t getSP() const { return reg[REGNO_VAX_R14]; } 364396ee378Sjoerg 365396ee378Sjoerg void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; } 366396ee378Sjoerg 367396ee378Sjoerg bool validFloatVectorRegister(int num) const { 368396ee378Sjoerg return false; 369396ee378Sjoerg } 370396ee378Sjoerg 371396ee378Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 372396ee378Sjoerg } 373396ee378Sjoerg 374396ee378Sjoerg __dso_hidden void jumpto() const __dead; 375396ee378Sjoerg 376396ee378Sjoerg private: 377396ee378Sjoerg uint32_t reg[REGNO_VAX_PSW + 1]; 378396ee378Sjoerg }; 379396ee378Sjoerg 380a55c6bd8Sjoerg enum { 381a55c6bd8Sjoerg DWARF_M68K_A0 = 0, 382a55c6bd8Sjoerg DWARF_M68K_A7 = 7, 383a55c6bd8Sjoerg DWARF_M68K_D0 = 8, 384a55c6bd8Sjoerg DWARF_M68K_D7 = 15, 385c05d688cSjoerg DWARF_M68K_FP0 = 16, 386c05d688cSjoerg DWARF_M68K_FP7 = 23, 387a55c6bd8Sjoerg DWARF_M68K_PC = 24, 388a55c6bd8Sjoerg 389a55c6bd8Sjoerg REGNO_M68K_A0 = 0, 390a55c6bd8Sjoerg REGNO_M68K_A7 = 7, 391a55c6bd8Sjoerg REGNO_M68K_D0 = 8, 392a55c6bd8Sjoerg REGNO_M68K_D7 = 15, 393a55c6bd8Sjoerg REGNO_M68K_PC = 16, 394c05d688cSjoerg REGNO_M68K_FP0 = 17, 395c05d688cSjoerg REGNO_M68K_FP7 = 24, 396a55c6bd8Sjoerg }; 397a55c6bd8Sjoerg 398a55c6bd8Sjoerg class Registers_M68K { 399a55c6bd8Sjoerg public: 400a55c6bd8Sjoerg enum { 401c05d688cSjoerg LAST_REGISTER = REGNO_M68K_FP7, 402c05d688cSjoerg LAST_RESTORE_REG = REGNO_M68K_FP7, 403a55c6bd8Sjoerg RETURN_REG = REGNO_M68K_PC, 404*9788222aSjoerg RETURN_OFFSET = 0, 405a55c6bd8Sjoerg }; 406a55c6bd8Sjoerg 407a55c6bd8Sjoerg __dso_hidden Registers_M68K(); 408a55c6bd8Sjoerg 409a55c6bd8Sjoerg static int dwarf2regno(int num) { 410a55c6bd8Sjoerg if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7) 411a55c6bd8Sjoerg return REGNO_M68K_A0 + (num - DWARF_M68K_A0); 412a55c6bd8Sjoerg if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7) 413a55c6bd8Sjoerg return REGNO_M68K_D0 + (num - DWARF_M68K_D0); 414c05d688cSjoerg if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7) 415c05d688cSjoerg return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0); 416a55c6bd8Sjoerg if (num == DWARF_M68K_PC) 417a55c6bd8Sjoerg return REGNO_M68K_PC; 418a55c6bd8Sjoerg return LAST_REGISTER + 1; 419a55c6bd8Sjoerg } 420a55c6bd8Sjoerg 421a55c6bd8Sjoerg bool validRegister(int num) const { 422c05d688cSjoerg return num >= 0 && num <= REGNO_M68K_PC; 423a55c6bd8Sjoerg } 424a55c6bd8Sjoerg 425a55c6bd8Sjoerg uint64_t getRegister(int num) const { 426a55c6bd8Sjoerg assert(validRegister(num)); 427a55c6bd8Sjoerg return reg[num]; 428a55c6bd8Sjoerg } 429a55c6bd8Sjoerg 430a55c6bd8Sjoerg void setRegister(int num, uint64_t value) { 431a55c6bd8Sjoerg assert(validRegister(num)); 432a55c6bd8Sjoerg reg[num] = value; 433a55c6bd8Sjoerg } 434a55c6bd8Sjoerg 435a55c6bd8Sjoerg uint64_t getIP() const { return reg[REGNO_M68K_PC]; } 436a55c6bd8Sjoerg 437a55c6bd8Sjoerg void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; } 438a55c6bd8Sjoerg 439a55c6bd8Sjoerg uint64_t getSP() const { return reg[REGNO_M68K_A7]; } 440a55c6bd8Sjoerg 441a55c6bd8Sjoerg void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; } 442a55c6bd8Sjoerg 443a55c6bd8Sjoerg bool validFloatVectorRegister(int num) const { 444c05d688cSjoerg return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7; 445a55c6bd8Sjoerg } 446a55c6bd8Sjoerg 447a55c6bd8Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 448c05d688cSjoerg assert(validFloatVectorRegister(num)); 449c05d688cSjoerg const void *addr = reinterpret_cast<const void *>(addr_); 450c05d688cSjoerg memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0])); 451a55c6bd8Sjoerg } 452a55c6bd8Sjoerg 453a55c6bd8Sjoerg __dso_hidden void jumpto() const __dead; 454a55c6bd8Sjoerg 455a55c6bd8Sjoerg private: 456c05d688cSjoerg typedef uint32_t fpreg_t[3]; 457c05d688cSjoerg 458a55c6bd8Sjoerg uint32_t reg[REGNO_M68K_PC + 1]; 459c05d688cSjoerg uint32_t dummy; 460c05d688cSjoerg fpreg_t fpreg[8]; 461a55c6bd8Sjoerg }; 462a55c6bd8Sjoerg 463a280fb92Sjoerg enum { 464a280fb92Sjoerg DWARF_SH3_R0 = 0, 465a280fb92Sjoerg DWARF_SH3_R15 = 15, 466a280fb92Sjoerg DWARF_SH3_PC = 16, 467a280fb92Sjoerg DWARF_SH3_PR = 17, 468a280fb92Sjoerg 469a280fb92Sjoerg REGNO_SH3_R0 = 0, 470a280fb92Sjoerg REGNO_SH3_R15 = 15, 471a280fb92Sjoerg REGNO_SH3_PC = 16, 472a280fb92Sjoerg REGNO_SH3_PR = 17, 473a280fb92Sjoerg }; 474a280fb92Sjoerg 475a280fb92Sjoerg class Registers_SH3 { 476a280fb92Sjoerg public: 477a280fb92Sjoerg enum { 478a280fb92Sjoerg LAST_REGISTER = REGNO_SH3_PR, 479a280fb92Sjoerg LAST_RESTORE_REG = REGNO_SH3_PR, 480a280fb92Sjoerg RETURN_REG = REGNO_SH3_PR, 481*9788222aSjoerg RETURN_OFFSET = 0, 482a280fb92Sjoerg }; 483a280fb92Sjoerg 484a280fb92Sjoerg __dso_hidden Registers_SH3(); 485a280fb92Sjoerg 486a280fb92Sjoerg static int dwarf2regno(int num) { 487a280fb92Sjoerg if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15) 488a280fb92Sjoerg return REGNO_SH3_R0 + (num - DWARF_SH3_R0); 489a280fb92Sjoerg if (num == DWARF_SH3_PC) 490a280fb92Sjoerg return REGNO_SH3_PC; 491a280fb92Sjoerg if (num == DWARF_SH3_PR) 492a280fb92Sjoerg return REGNO_SH3_PR; 493a280fb92Sjoerg return LAST_REGISTER + 1; 494a280fb92Sjoerg } 495a280fb92Sjoerg 496a280fb92Sjoerg bool validRegister(int num) const { 497a280fb92Sjoerg return num >= 0 && num <= REGNO_SH3_PR; 498a280fb92Sjoerg } 499a280fb92Sjoerg 500a280fb92Sjoerg uint64_t getRegister(int num) const { 501a280fb92Sjoerg assert(validRegister(num)); 502a280fb92Sjoerg return reg[num]; 503a280fb92Sjoerg } 504a280fb92Sjoerg 505a280fb92Sjoerg void setRegister(int num, uint64_t value) { 506a280fb92Sjoerg assert(validRegister(num)); 507a280fb92Sjoerg reg[num] = value; 508a280fb92Sjoerg } 509a280fb92Sjoerg 510a280fb92Sjoerg uint64_t getIP() const { return reg[REGNO_SH3_PC]; } 511a280fb92Sjoerg 512a280fb92Sjoerg void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; } 513a280fb92Sjoerg 514a280fb92Sjoerg uint64_t getSP() const { return reg[REGNO_SH3_R15]; } 515a280fb92Sjoerg 516a280fb92Sjoerg void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; } 517a280fb92Sjoerg 518a280fb92Sjoerg bool validFloatVectorRegister(int num) const { return false; } 519a280fb92Sjoerg 520a280fb92Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) {} 521a280fb92Sjoerg 522a280fb92Sjoerg __dso_hidden void jumpto() const __dead; 523a280fb92Sjoerg 524a280fb92Sjoerg private: 525a280fb92Sjoerg uint32_t reg[REGNO_SH3_PR + 1]; 526a280fb92Sjoerg }; 527a280fb92Sjoerg 528a6ecde39Sjoerg #if __i386__ 529a6ecde39Sjoerg typedef Registers_x86 NativeUnwindRegisters; 530a6ecde39Sjoerg #elif __x86_64__ 531a6ecde39Sjoerg typedef Registers_x86_64 NativeUnwindRegisters; 532a6ecde39Sjoerg #elif __powerpc__ 533a6ecde39Sjoerg typedef Registers_ppc32 NativeUnwindRegisters; 534a6ecde39Sjoerg #elif __arm__ && !defined(__ARM_EABI__) 535a6ecde39Sjoerg typedef Registers_arm32 NativeUnwindRegisters; 536a6ecde39Sjoerg #elif __vax__ 537a6ecde39Sjoerg typedef Registers_vax NativeUnwindRegisters; 538a6ecde39Sjoerg #elif __m68k__ 539a6ecde39Sjoerg typedef Registers_M68K NativeUnwindRegisters; 540a6ecde39Sjoerg #elif __sh3__ 541a6ecde39Sjoerg typedef Registers_SH3 NativeUnwindRegisters; 542a6ecde39Sjoerg #endif 543aa0b96d0Sjoerg } // namespace _Unwind 544aa0b96d0Sjoerg 545aa0b96d0Sjoerg #endif // __REGISTERS_HPP__ 546