1*aa0b96d0Sjoerg //===----------------------------- Registers.hpp --------------------------===// 2*aa0b96d0Sjoerg // 3*aa0b96d0Sjoerg // The LLVM Compiler Infrastructure 4*aa0b96d0Sjoerg // 5*aa0b96d0Sjoerg // This file is dual licensed under the MIT and the University of Illinois Open 6*aa0b96d0Sjoerg // Source Licenses. See LICENSE.TXT for details. 7*aa0b96d0Sjoerg // 8*aa0b96d0Sjoerg // 9*aa0b96d0Sjoerg // Models register sets for supported processors. 10*aa0b96d0Sjoerg // 11*aa0b96d0Sjoerg //===----------------------------------------------------------------------===// 12*aa0b96d0Sjoerg #ifndef __REGISTERS_HPP__ 13*aa0b96d0Sjoerg #define __REGISTERS_HPP__ 14*aa0b96d0Sjoerg 15*aa0b96d0Sjoerg #include <cassert> 16*aa0b96d0Sjoerg #include <cstdint> 17*aa0b96d0Sjoerg 18*aa0b96d0Sjoerg namespace _Unwind { 19*aa0b96d0Sjoerg 20*aa0b96d0Sjoerg enum { 21*aa0b96d0Sjoerg REGNO_X86_EAX = 0, 22*aa0b96d0Sjoerg REGNO_X86_ECX = 1, 23*aa0b96d0Sjoerg REGNO_X86_EDX = 2, 24*aa0b96d0Sjoerg REGNO_X86_EBX = 3, 25*aa0b96d0Sjoerg REGNO_X86_ESP = 4, 26*aa0b96d0Sjoerg REGNO_X86_EBP = 5, 27*aa0b96d0Sjoerg REGNO_X86_ESI = 6, 28*aa0b96d0Sjoerg REGNO_X86_EDI = 7, 29*aa0b96d0Sjoerg REGNO_X86_EIP = 8, 30*aa0b96d0Sjoerg }; 31*aa0b96d0Sjoerg 32*aa0b96d0Sjoerg class Registers_x86 { 33*aa0b96d0Sjoerg public: 34*aa0b96d0Sjoerg enum { 35*aa0b96d0Sjoerg LAST_RESTORE_REG = REGNO_X86_EIP, 36*aa0b96d0Sjoerg IP_PSEUDO_REG = REGNO_X86_EIP, 37*aa0b96d0Sjoerg LAST_REGISTER = REGNO_X86_EIP, 38*aa0b96d0Sjoerg }; 39*aa0b96d0Sjoerg 40*aa0b96d0Sjoerg __dso_hidden Registers_x86(); 41*aa0b96d0Sjoerg 42*aa0b96d0Sjoerg static int dwarf2regno(int num) { return num; } 43*aa0b96d0Sjoerg 44*aa0b96d0Sjoerg bool validRegister(int num) const { 45*aa0b96d0Sjoerg return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI; 46*aa0b96d0Sjoerg } 47*aa0b96d0Sjoerg 48*aa0b96d0Sjoerg uint32_t getRegister(int num) const { 49*aa0b96d0Sjoerg assert(validRegister(num)); 50*aa0b96d0Sjoerg return reg[num]; 51*aa0b96d0Sjoerg } 52*aa0b96d0Sjoerg 53*aa0b96d0Sjoerg void setRegister(int num, uint32_t value) { 54*aa0b96d0Sjoerg assert(validRegister(num)); 55*aa0b96d0Sjoerg reg[num] = value; 56*aa0b96d0Sjoerg } 57*aa0b96d0Sjoerg 58*aa0b96d0Sjoerg uint32_t getIP() const { return reg[REGNO_X86_EIP]; } 59*aa0b96d0Sjoerg 60*aa0b96d0Sjoerg void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; } 61*aa0b96d0Sjoerg 62*aa0b96d0Sjoerg uint32_t getSP() const { return reg[REGNO_X86_ESP]; } 63*aa0b96d0Sjoerg 64*aa0b96d0Sjoerg void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; } 65*aa0b96d0Sjoerg 66*aa0b96d0Sjoerg bool validFloatVectorRegister(int num) const { return false; } 67*aa0b96d0Sjoerg 68*aa0b96d0Sjoerg void copyFloatVectorRegister(int num, uint32_t addr) { 69*aa0b96d0Sjoerg } 70*aa0b96d0Sjoerg 71*aa0b96d0Sjoerg __dso_hidden void jumpto() const __dead; 72*aa0b96d0Sjoerg 73*aa0b96d0Sjoerg private: 74*aa0b96d0Sjoerg uint32_t reg[REGNO_X86_EIP + 1]; 75*aa0b96d0Sjoerg }; 76*aa0b96d0Sjoerg 77*aa0b96d0Sjoerg enum { 78*aa0b96d0Sjoerg REGNO_X86_64_RAX = 0, 79*aa0b96d0Sjoerg REGNO_X86_64_RDX = 1, 80*aa0b96d0Sjoerg REGNO_X86_64_RCX = 2, 81*aa0b96d0Sjoerg REGNO_X86_64_RBX = 3, 82*aa0b96d0Sjoerg REGNO_X86_64_RSI = 4, 83*aa0b96d0Sjoerg REGNO_X86_64_RDI = 5, 84*aa0b96d0Sjoerg REGNO_X86_64_RBP = 6, 85*aa0b96d0Sjoerg REGNO_X86_64_RSP = 7, 86*aa0b96d0Sjoerg REGNO_X86_64_R8 = 8, 87*aa0b96d0Sjoerg REGNO_X86_64_R9 = 9, 88*aa0b96d0Sjoerg REGNO_X86_64_R10 = 10, 89*aa0b96d0Sjoerg REGNO_X86_64_R11 = 11, 90*aa0b96d0Sjoerg REGNO_X86_64_R12 = 12, 91*aa0b96d0Sjoerg REGNO_X86_64_R13 = 13, 92*aa0b96d0Sjoerg REGNO_X86_64_R14 = 14, 93*aa0b96d0Sjoerg REGNO_X86_64_R15 = 15, 94*aa0b96d0Sjoerg REGNO_X86_64_RIP = 16, 95*aa0b96d0Sjoerg }; 96*aa0b96d0Sjoerg 97*aa0b96d0Sjoerg class Registers_x86_64 { 98*aa0b96d0Sjoerg public: 99*aa0b96d0Sjoerg enum { 100*aa0b96d0Sjoerg LAST_RESTORE_REG = REGNO_X86_64_RIP, 101*aa0b96d0Sjoerg IP_PSEUDO_REG = REGNO_X86_64_RIP, 102*aa0b96d0Sjoerg LAST_REGISTER = REGNO_X86_64_RIP, 103*aa0b96d0Sjoerg }; 104*aa0b96d0Sjoerg 105*aa0b96d0Sjoerg __dso_hidden Registers_x86_64(); 106*aa0b96d0Sjoerg 107*aa0b96d0Sjoerg static int dwarf2regno(int num) { return num; } 108*aa0b96d0Sjoerg 109*aa0b96d0Sjoerg bool validRegister(int num) const { 110*aa0b96d0Sjoerg return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15; 111*aa0b96d0Sjoerg } 112*aa0b96d0Sjoerg 113*aa0b96d0Sjoerg uint64_t getRegister(int num) const { 114*aa0b96d0Sjoerg assert(validRegister(num)); 115*aa0b96d0Sjoerg return reg[num]; 116*aa0b96d0Sjoerg } 117*aa0b96d0Sjoerg 118*aa0b96d0Sjoerg void setRegister(int num, uint64_t value) { 119*aa0b96d0Sjoerg assert(validRegister(num)); 120*aa0b96d0Sjoerg reg[num] = value; 121*aa0b96d0Sjoerg } 122*aa0b96d0Sjoerg 123*aa0b96d0Sjoerg uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; } 124*aa0b96d0Sjoerg 125*aa0b96d0Sjoerg void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; } 126*aa0b96d0Sjoerg 127*aa0b96d0Sjoerg uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; } 128*aa0b96d0Sjoerg 129*aa0b96d0Sjoerg void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; } 130*aa0b96d0Sjoerg 131*aa0b96d0Sjoerg bool validFloatVectorRegister(int num) const { return false; } 132*aa0b96d0Sjoerg 133*aa0b96d0Sjoerg void copyFloatVectorRegister(int num, uint64_t addr) { 134*aa0b96d0Sjoerg } 135*aa0b96d0Sjoerg 136*aa0b96d0Sjoerg __dso_hidden void jumpto() const __dead; 137*aa0b96d0Sjoerg 138*aa0b96d0Sjoerg private: 139*aa0b96d0Sjoerg uint64_t reg[REGNO_X86_64_RIP + 1]; 140*aa0b96d0Sjoerg }; 141*aa0b96d0Sjoerg 142*aa0b96d0Sjoerg enum { 143*aa0b96d0Sjoerg DWARF_PPC32_R0 = 0, 144*aa0b96d0Sjoerg DWARF_PPC32_R31 = 31, 145*aa0b96d0Sjoerg DWARF_PPC32_F0 = 32, 146*aa0b96d0Sjoerg DWARF_PPC32_F31 = 63, 147*aa0b96d0Sjoerg DWARF_PPC32_V0 = 1124, 148*aa0b96d0Sjoerg DWARF_PPC32_V31 = 1155, 149*aa0b96d0Sjoerg DWARF_PPC32_LR = 65, 150*aa0b96d0Sjoerg DWARF_PPC32_CTR = 66, 151*aa0b96d0Sjoerg DWARF_PPC32_XER = 76, 152*aa0b96d0Sjoerg REGNO_PPC32_R0 = 0, 153*aa0b96d0Sjoerg REGNO_PPC32_R1 = 0, 154*aa0b96d0Sjoerg REGNO_PPC32_R31 = 31, 155*aa0b96d0Sjoerg REGNO_PPC32_CR = 32, 156*aa0b96d0Sjoerg REGNO_PPC32_LR = 33, 157*aa0b96d0Sjoerg REGNO_PPC32_CTR = 34, 158*aa0b96d0Sjoerg REGNO_PPC32_XER = 35, 159*aa0b96d0Sjoerg REGNO_PPC32_SRR0 = 36, 160*aa0b96d0Sjoerg REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1, 161*aa0b96d0Sjoerg REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31, 162*aa0b96d0Sjoerg REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1, 163*aa0b96d0Sjoerg REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31, 164*aa0b96d0Sjoerg }; 165*aa0b96d0Sjoerg 166*aa0b96d0Sjoerg class Registers_ppc32 { 167*aa0b96d0Sjoerg public: 168*aa0b96d0Sjoerg enum { 169*aa0b96d0Sjoerg LAST_RESTORE_REG = REGNO_PPC32_V31, 170*aa0b96d0Sjoerg IP_PSEUDO_REG = REGNO_PPC32_SRR0, 171*aa0b96d0Sjoerg LAST_REGISTER = REGNO_PPC32_V31, 172*aa0b96d0Sjoerg }; 173*aa0b96d0Sjoerg 174*aa0b96d0Sjoerg __dso_hidden Registers_ppc32(); 175*aa0b96d0Sjoerg 176*aa0b96d0Sjoerg static int dwarf2regno(int num) { 177*aa0b96d0Sjoerg if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31) 178*aa0b96d0Sjoerg return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0); 179*aa0b96d0Sjoerg if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31) 180*aa0b96d0Sjoerg return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0); 181*aa0b96d0Sjoerg if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31) 182*aa0b96d0Sjoerg return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0); 183*aa0b96d0Sjoerg return LAST_REGISTER + 1; 184*aa0b96d0Sjoerg } 185*aa0b96d0Sjoerg 186*aa0b96d0Sjoerg bool validRegister(int num) const { 187*aa0b96d0Sjoerg return num >= 0 && num <= LAST_RESTORE_REG; 188*aa0b96d0Sjoerg } 189*aa0b96d0Sjoerg 190*aa0b96d0Sjoerg uint64_t getRegister(int num) const { 191*aa0b96d0Sjoerg assert(validRegister(num)); 192*aa0b96d0Sjoerg return reg[num]; 193*aa0b96d0Sjoerg } 194*aa0b96d0Sjoerg 195*aa0b96d0Sjoerg void setRegister(int num, uint64_t value) { 196*aa0b96d0Sjoerg assert(validRegister(num)); 197*aa0b96d0Sjoerg reg[num] = value; 198*aa0b96d0Sjoerg } 199*aa0b96d0Sjoerg 200*aa0b96d0Sjoerg uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; } 201*aa0b96d0Sjoerg 202*aa0b96d0Sjoerg void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; } 203*aa0b96d0Sjoerg 204*aa0b96d0Sjoerg uint64_t getSP() const { return reg[REGNO_PPC32_R1]; } 205*aa0b96d0Sjoerg 206*aa0b96d0Sjoerg void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; } 207*aa0b96d0Sjoerg 208*aa0b96d0Sjoerg bool validFloatVectorRegister(int num) const { 209*aa0b96d0Sjoerg return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) || 210*aa0b96d0Sjoerg (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31); 211*aa0b96d0Sjoerg } 212*aa0b96d0Sjoerg 213*aa0b96d0Sjoerg void copyFloatVectorRegister(int num, uint64_t addr_) { 214*aa0b96d0Sjoerg const void *addr = reinterpret_cast<const void *>(addr_); 215*aa0b96d0Sjoerg if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) 216*aa0b96d0Sjoerg memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0])); 217*aa0b96d0Sjoerg else 218*aa0b96d0Sjoerg memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0])); 219*aa0b96d0Sjoerg } 220*aa0b96d0Sjoerg 221*aa0b96d0Sjoerg __dso_hidden void jumpto() const __dead; 222*aa0b96d0Sjoerg 223*aa0b96d0Sjoerg private: 224*aa0b96d0Sjoerg struct vecreg_t { 225*aa0b96d0Sjoerg uint64_t low, high; 226*aa0b96d0Sjoerg }; 227*aa0b96d0Sjoerg uint32_t reg[REGNO_PPC32_SRR0 + 1]; 228*aa0b96d0Sjoerg uint64_t fpreg[32]; 229*aa0b96d0Sjoerg vecreg_t vecreg[64]; 230*aa0b96d0Sjoerg }; 231*aa0b96d0Sjoerg 232*aa0b96d0Sjoerg } // namespace _Unwind 233*aa0b96d0Sjoerg 234*aa0b96d0Sjoerg #endif // __REGISTERS_HPP__ 235