1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceRegistersX8632.h - Register information ---*- C++ -*-===// 2*03ce13f7SAndroid Build Coastguard Worker // 3*03ce13f7SAndroid Build Coastguard Worker // The Subzero Code Generator 4*03ce13f7SAndroid Build Coastguard Worker // 5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*03ce13f7SAndroid Build Coastguard Worker // 8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*03ce13f7SAndroid Build Coastguard Worker /// 10*03ce13f7SAndroid Build Coastguard Worker /// \file 11*03ce13f7SAndroid Build Coastguard Worker /// \brief Declares the registers and their encodings for x86-32. 12*03ce13f7SAndroid Build Coastguard Worker /// 13*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 14*03ce13f7SAndroid Build Coastguard Worker 15*03ce13f7SAndroid Build Coastguard Worker #ifndef SUBZERO_SRC_ICEREGISTERSX8632_H 16*03ce13f7SAndroid Build Coastguard Worker #define SUBZERO_SRC_ICEREGISTERSX8632_H 17*03ce13f7SAndroid Build Coastguard Worker 18*03ce13f7SAndroid Build Coastguard Worker #include "IceBitVector.h" 19*03ce13f7SAndroid Build Coastguard Worker #include "IceDefs.h" 20*03ce13f7SAndroid Build Coastguard Worker #include "IceInstX8632.def" 21*03ce13f7SAndroid Build Coastguard Worker #include "IceTargetLowering.h" 22*03ce13f7SAndroid Build Coastguard Worker #include "IceTargetLoweringX86RegClass.h" 23*03ce13f7SAndroid Build Coastguard Worker #include "IceTypes.h" 24*03ce13f7SAndroid Build Coastguard Worker 25*03ce13f7SAndroid Build Coastguard Worker #include <initializer_list> 26*03ce13f7SAndroid Build Coastguard Worker 27*03ce13f7SAndroid Build Coastguard Worker namespace Ice { 28*03ce13f7SAndroid Build Coastguard Worker using namespace ::Ice::X86; 29*03ce13f7SAndroid Build Coastguard Worker 30*03ce13f7SAndroid Build Coastguard Worker class RegX8632 { 31*03ce13f7SAndroid Build Coastguard Worker public: 32*03ce13f7SAndroid Build Coastguard Worker /// An enum of every register. The enum value may not match the encoding used 33*03ce13f7SAndroid Build Coastguard Worker /// to binary encode register operands in instructions. 34*03ce13f7SAndroid Build Coastguard Worker enum AllRegisters { 35*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 36*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 37*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 38*03ce13f7SAndroid Build Coastguard Worker val, 39*03ce13f7SAndroid Build Coastguard Worker REGX8632_TABLE 40*03ce13f7SAndroid Build Coastguard Worker #undef X 41*03ce13f7SAndroid Build Coastguard Worker Reg_NUM 42*03ce13f7SAndroid Build Coastguard Worker }; 43*03ce13f7SAndroid Build Coastguard Worker 44*03ce13f7SAndroid Build Coastguard Worker /// An enum of GPR Registers. The enum value does match the encoding used to 45*03ce13f7SAndroid Build Coastguard Worker /// binary encode register operands in instructions. 46*03ce13f7SAndroid Build Coastguard Worker enum GPRRegister { 47*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 48*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 49*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 50*03ce13f7SAndroid Build Coastguard Worker Encoded_##val = encode, 51*03ce13f7SAndroid Build Coastguard Worker REGX8632_GPR_TABLE 52*03ce13f7SAndroid Build Coastguard Worker #undef X 53*03ce13f7SAndroid Build Coastguard Worker Encoded_Not_GPR = -1 54*03ce13f7SAndroid Build Coastguard Worker }; 55*03ce13f7SAndroid Build Coastguard Worker 56*03ce13f7SAndroid Build Coastguard Worker /// An enum of XMM Registers. The enum value does match the encoding used to 57*03ce13f7SAndroid Build Coastguard Worker /// binary encode register operands in instructions. 58*03ce13f7SAndroid Build Coastguard Worker enum XmmRegister { 59*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 60*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 61*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 62*03ce13f7SAndroid Build Coastguard Worker Encoded_##val = encode, 63*03ce13f7SAndroid Build Coastguard Worker REGX8632_XMM_TABLE 64*03ce13f7SAndroid Build Coastguard Worker #undef X 65*03ce13f7SAndroid Build Coastguard Worker Encoded_Not_Xmm = -1 66*03ce13f7SAndroid Build Coastguard Worker }; 67*03ce13f7SAndroid Build Coastguard Worker 68*03ce13f7SAndroid Build Coastguard Worker /// An enum of Byte Registers. The enum value does match the encoding used to 69*03ce13f7SAndroid Build Coastguard Worker /// binary encode register operands in instructions. 70*03ce13f7SAndroid Build Coastguard Worker enum ByteRegister { 71*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 72*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 73*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 74*03ce13f7SAndroid Build Coastguard Worker Encoded_8_##val = encode, 75*03ce13f7SAndroid Build Coastguard Worker REGX8632_BYTEREG_TABLE 76*03ce13f7SAndroid Build Coastguard Worker #undef X 77*03ce13f7SAndroid Build Coastguard Worker Encoded_Not_ByteReg = -1 78*03ce13f7SAndroid Build Coastguard Worker }; 79*03ce13f7SAndroid Build Coastguard Worker 80*03ce13f7SAndroid Build Coastguard Worker /// An enum of X87 Stack Registers. The enum value does match the encoding 81*03ce13f7SAndroid Build Coastguard Worker /// used to binary encode register operands in instructions. 82*03ce13f7SAndroid Build Coastguard Worker enum X87STRegister { 83*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name) Encoded_##val = encode, 84*03ce13f7SAndroid Build Coastguard Worker X87ST_REGX8632_TABLE 85*03ce13f7SAndroid Build Coastguard Worker #undef X 86*03ce13f7SAndroid Build Coastguard Worker Encoded_Not_X87STReg = -1 87*03ce13f7SAndroid Build Coastguard Worker }; 88*03ce13f7SAndroid Build Coastguard Worker getEncodedSTReg(uint32_t X87RegNum)89*03ce13f7SAndroid Build Coastguard Worker static inline X87STRegister getEncodedSTReg(uint32_t X87RegNum) { 90*03ce13f7SAndroid Build Coastguard Worker assert(int(Encoded_X87ST_First) <= int(X87RegNum)); 91*03ce13f7SAndroid Build Coastguard Worker assert(X87RegNum <= Encoded_X87ST_Last); 92*03ce13f7SAndroid Build Coastguard Worker return X87STRegister(X87RegNum); 93*03ce13f7SAndroid Build Coastguard Worker } 94*03ce13f7SAndroid Build Coastguard Worker getRegName(RegNumT RegNum)95*03ce13f7SAndroid Build Coastguard Worker static inline const char *getRegName(RegNumT RegNum) { 96*03ce13f7SAndroid Build Coastguard Worker static const char *const RegNames[Reg_NUM] = { 97*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 98*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 99*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 100*03ce13f7SAndroid Build Coastguard Worker name, 101*03ce13f7SAndroid Build Coastguard Worker REGX8632_TABLE 102*03ce13f7SAndroid Build Coastguard Worker #undef X 103*03ce13f7SAndroid Build Coastguard Worker }; 104*03ce13f7SAndroid Build Coastguard Worker RegNum.assertIsValid(); 105*03ce13f7SAndroid Build Coastguard Worker return RegNames[RegNum]; 106*03ce13f7SAndroid Build Coastguard Worker } 107*03ce13f7SAndroid Build Coastguard Worker getEncodedGPR(RegNumT RegNum)108*03ce13f7SAndroid Build Coastguard Worker static inline GPRRegister getEncodedGPR(RegNumT RegNum) { 109*03ce13f7SAndroid Build Coastguard Worker static const GPRRegister GPRRegs[Reg_NUM] = { 110*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 111*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 112*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 113*03ce13f7SAndroid Build Coastguard Worker GPRRegister(isGPR ? encode : GPRRegister::Encoded_Not_GPR), 114*03ce13f7SAndroid Build Coastguard Worker REGX8632_TABLE 115*03ce13f7SAndroid Build Coastguard Worker #undef X 116*03ce13f7SAndroid Build Coastguard Worker }; 117*03ce13f7SAndroid Build Coastguard Worker RegNum.assertIsValid(); 118*03ce13f7SAndroid Build Coastguard Worker assert(GPRRegs[RegNum] != GPRRegister::Encoded_Not_GPR); 119*03ce13f7SAndroid Build Coastguard Worker return GPRRegs[RegNum]; 120*03ce13f7SAndroid Build Coastguard Worker } 121*03ce13f7SAndroid Build Coastguard Worker getEncodedByteReg(RegNumT RegNum)122*03ce13f7SAndroid Build Coastguard Worker static inline ByteRegister getEncodedByteReg(RegNumT RegNum) { 123*03ce13f7SAndroid Build Coastguard Worker static const ByteRegister ByteRegs[Reg_NUM] = { 124*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 125*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 126*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 127*03ce13f7SAndroid Build Coastguard Worker ByteRegister(is8 ? encode : ByteRegister::Encoded_Not_ByteReg), 128*03ce13f7SAndroid Build Coastguard Worker REGX8632_TABLE 129*03ce13f7SAndroid Build Coastguard Worker #undef X 130*03ce13f7SAndroid Build Coastguard Worker }; 131*03ce13f7SAndroid Build Coastguard Worker RegNum.assertIsValid(); 132*03ce13f7SAndroid Build Coastguard Worker assert(ByteRegs[RegNum] != ByteRegister::Encoded_Not_ByteReg); 133*03ce13f7SAndroid Build Coastguard Worker return ByteRegs[RegNum]; 134*03ce13f7SAndroid Build Coastguard Worker } 135*03ce13f7SAndroid Build Coastguard Worker isXmm(RegNumT RegNum)136*03ce13f7SAndroid Build Coastguard Worker static inline bool isXmm(RegNumT RegNum) { 137*03ce13f7SAndroid Build Coastguard Worker static const bool IsXmm[Reg_NUM] = { 138*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 139*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 140*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 141*03ce13f7SAndroid Build Coastguard Worker isXmm, 142*03ce13f7SAndroid Build Coastguard Worker REGX8632_TABLE 143*03ce13f7SAndroid Build Coastguard Worker #undef X 144*03ce13f7SAndroid Build Coastguard Worker }; 145*03ce13f7SAndroid Build Coastguard Worker return IsXmm[RegNum]; 146*03ce13f7SAndroid Build Coastguard Worker } 147*03ce13f7SAndroid Build Coastguard Worker getEncodedXmm(RegNumT RegNum)148*03ce13f7SAndroid Build Coastguard Worker static inline XmmRegister getEncodedXmm(RegNumT RegNum) { 149*03ce13f7SAndroid Build Coastguard Worker static const XmmRegister XmmRegs[Reg_NUM] = { 150*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 151*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 152*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 153*03ce13f7SAndroid Build Coastguard Worker XmmRegister(isXmm ? encode : XmmRegister::Encoded_Not_Xmm), 154*03ce13f7SAndroid Build Coastguard Worker REGX8632_TABLE 155*03ce13f7SAndroid Build Coastguard Worker #undef X 156*03ce13f7SAndroid Build Coastguard Worker }; 157*03ce13f7SAndroid Build Coastguard Worker RegNum.assertIsValid(); 158*03ce13f7SAndroid Build Coastguard Worker assert(XmmRegs[RegNum] != XmmRegister::Encoded_Not_Xmm); 159*03ce13f7SAndroid Build Coastguard Worker return XmmRegs[RegNum]; 160*03ce13f7SAndroid Build Coastguard Worker } 161*03ce13f7SAndroid Build Coastguard Worker getEncoding(RegNumT RegNum)162*03ce13f7SAndroid Build Coastguard Worker static inline uint32_t getEncoding(RegNumT RegNum) { 163*03ce13f7SAndroid Build Coastguard Worker static const uint32_t Encoding[Reg_NUM] = { 164*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 165*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 166*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 167*03ce13f7SAndroid Build Coastguard Worker encode, 168*03ce13f7SAndroid Build Coastguard Worker REGX8632_TABLE 169*03ce13f7SAndroid Build Coastguard Worker #undef X 170*03ce13f7SAndroid Build Coastguard Worker }; 171*03ce13f7SAndroid Build Coastguard Worker RegNum.assertIsValid(); 172*03ce13f7SAndroid Build Coastguard Worker return Encoding[RegNum]; 173*03ce13f7SAndroid Build Coastguard Worker } 174*03ce13f7SAndroid Build Coastguard Worker getBaseReg(RegNumT RegNum)175*03ce13f7SAndroid Build Coastguard Worker static inline RegNumT getBaseReg(RegNumT RegNum) { 176*03ce13f7SAndroid Build Coastguard Worker static const RegNumT BaseRegs[Reg_NUM] = { 177*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 178*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 179*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 180*03ce13f7SAndroid Build Coastguard Worker base, 181*03ce13f7SAndroid Build Coastguard Worker REGX8632_TABLE 182*03ce13f7SAndroid Build Coastguard Worker #undef X 183*03ce13f7SAndroid Build Coastguard Worker }; 184*03ce13f7SAndroid Build Coastguard Worker RegNum.assertIsValid(); 185*03ce13f7SAndroid Build Coastguard Worker return BaseRegs[RegNum]; 186*03ce13f7SAndroid Build Coastguard Worker } 187*03ce13f7SAndroid Build Coastguard Worker 188*03ce13f7SAndroid Build Coastguard Worker private: getFirstGprForType(Type Ty)189*03ce13f7SAndroid Build Coastguard Worker static inline AllRegisters getFirstGprForType(Type Ty) { 190*03ce13f7SAndroid Build Coastguard Worker switch (Ty) { 191*03ce13f7SAndroid Build Coastguard Worker default: 192*03ce13f7SAndroid Build Coastguard Worker llvm_unreachable("Invalid type for GPR."); 193*03ce13f7SAndroid Build Coastguard Worker case IceType_i1: 194*03ce13f7SAndroid Build Coastguard Worker case IceType_i8: 195*03ce13f7SAndroid Build Coastguard Worker return Reg_al; 196*03ce13f7SAndroid Build Coastguard Worker case IceType_i16: 197*03ce13f7SAndroid Build Coastguard Worker return Reg_ax; 198*03ce13f7SAndroid Build Coastguard Worker case IceType_i32: 199*03ce13f7SAndroid Build Coastguard Worker return Reg_eax; 200*03ce13f7SAndroid Build Coastguard Worker } 201*03ce13f7SAndroid Build Coastguard Worker } 202*03ce13f7SAndroid Build Coastguard Worker 203*03ce13f7SAndroid Build Coastguard Worker public: 204*03ce13f7SAndroid Build Coastguard Worker // Return a register in RegNum's alias set that is suitable for Ty. getGprForType(Type Ty,RegNumT RegNum)205*03ce13f7SAndroid Build Coastguard Worker static inline RegNumT getGprForType(Type Ty, RegNumT RegNum) { 206*03ce13f7SAndroid Build Coastguard Worker assert(RegNum.hasValue()); 207*03ce13f7SAndroid Build Coastguard Worker 208*03ce13f7SAndroid Build Coastguard Worker if (!isScalarIntegerType(Ty)) { 209*03ce13f7SAndroid Build Coastguard Worker return RegNum; 210*03ce13f7SAndroid Build Coastguard Worker } 211*03ce13f7SAndroid Build Coastguard Worker 212*03ce13f7SAndroid Build Coastguard Worker // [abcd]h registers are not convertible to their ?l, ?x, and e?x versions. 213*03ce13f7SAndroid Build Coastguard Worker switch (RegNum) { 214*03ce13f7SAndroid Build Coastguard Worker default: 215*03ce13f7SAndroid Build Coastguard Worker break; 216*03ce13f7SAndroid Build Coastguard Worker case Reg_ah: 217*03ce13f7SAndroid Build Coastguard Worker case Reg_bh: 218*03ce13f7SAndroid Build Coastguard Worker case Reg_ch: 219*03ce13f7SAndroid Build Coastguard Worker case Reg_dh: 220*03ce13f7SAndroid Build Coastguard Worker assert(isByteSizedType(Ty)); 221*03ce13f7SAndroid Build Coastguard Worker return RegNum; 222*03ce13f7SAndroid Build Coastguard Worker } 223*03ce13f7SAndroid Build Coastguard Worker 224*03ce13f7SAndroid Build Coastguard Worker const AllRegisters FirstGprForType = getFirstGprForType(Ty); 225*03ce13f7SAndroid Build Coastguard Worker 226*03ce13f7SAndroid Build Coastguard Worker switch (RegNum) { 227*03ce13f7SAndroid Build Coastguard Worker default: 228*03ce13f7SAndroid Build Coastguard Worker llvm::report_fatal_error("Unknown register."); 229*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 230*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 231*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 232*03ce13f7SAndroid Build Coastguard Worker case val: { \ 233*03ce13f7SAndroid Build Coastguard Worker if (!isGPR) \ 234*03ce13f7SAndroid Build Coastguard Worker return val; \ 235*03ce13f7SAndroid Build Coastguard Worker assert((is32) || (is16) || (is8) || getBaseReg(val) == Reg_esp); \ 236*03ce13f7SAndroid Build Coastguard Worker constexpr AllRegisters FirstGprWithRegNumSize = \ 237*03ce13f7SAndroid Build Coastguard Worker (((is32) || val == Reg_esp) \ 238*03ce13f7SAndroid Build Coastguard Worker ? Reg_eax \ 239*03ce13f7SAndroid Build Coastguard Worker : (((is16) || val == Reg_sp) ? Reg_ax : Reg_al)); \ 240*03ce13f7SAndroid Build Coastguard Worker const RegNumT NewRegNum = \ 241*03ce13f7SAndroid Build Coastguard Worker RegNumT::fixme(RegNum - FirstGprWithRegNumSize + FirstGprForType); \ 242*03ce13f7SAndroid Build Coastguard Worker assert(getBaseReg(RegNum) == getBaseReg(NewRegNum) && \ 243*03ce13f7SAndroid Build Coastguard Worker "Error involving " #val); \ 244*03ce13f7SAndroid Build Coastguard Worker return NewRegNum; \ 245*03ce13f7SAndroid Build Coastguard Worker } 246*03ce13f7SAndroid Build Coastguard Worker REGX8632_TABLE 247*03ce13f7SAndroid Build Coastguard Worker #undef X 248*03ce13f7SAndroid Build Coastguard Worker } 249*03ce13f7SAndroid Build Coastguard Worker } 250*03ce13f7SAndroid Build Coastguard Worker 251*03ce13f7SAndroid Build Coastguard Worker public: 252*03ce13f7SAndroid Build Coastguard Worker static inline void initRegisterSet(const::Ice::ClFlags &,std::array<SmallBitVector,RCX86_NUM> * TypeToRegisterSet,std::array<SmallBitVector,Reg_NUM> * RegisterAliases)253*03ce13f7SAndroid Build Coastguard Worker initRegisterSet(const ::Ice::ClFlags & /*Flags*/, 254*03ce13f7SAndroid Build Coastguard Worker std::array<SmallBitVector, RCX86_NUM> *TypeToRegisterSet, 255*03ce13f7SAndroid Build Coastguard Worker std::array<SmallBitVector, Reg_NUM> *RegisterAliases) { 256*03ce13f7SAndroid Build Coastguard Worker SmallBitVector IntegerRegistersI32(Reg_NUM); 257*03ce13f7SAndroid Build Coastguard Worker SmallBitVector IntegerRegistersI16(Reg_NUM); 258*03ce13f7SAndroid Build Coastguard Worker SmallBitVector IntegerRegistersI8(Reg_NUM); 259*03ce13f7SAndroid Build Coastguard Worker SmallBitVector FloatRegisters(Reg_NUM); 260*03ce13f7SAndroid Build Coastguard Worker SmallBitVector VectorRegisters(Reg_NUM); 261*03ce13f7SAndroid Build Coastguard Worker SmallBitVector Trunc64To8Registers(Reg_NUM); 262*03ce13f7SAndroid Build Coastguard Worker SmallBitVector Trunc32To8Registers(Reg_NUM); 263*03ce13f7SAndroid Build Coastguard Worker SmallBitVector Trunc16To8Registers(Reg_NUM); 264*03ce13f7SAndroid Build Coastguard Worker SmallBitVector Trunc8RcvrRegisters(Reg_NUM); 265*03ce13f7SAndroid Build Coastguard Worker SmallBitVector AhRcvrRegisters(Reg_NUM); 266*03ce13f7SAndroid Build Coastguard Worker SmallBitVector InvalidRegisters(Reg_NUM); 267*03ce13f7SAndroid Build Coastguard Worker 268*03ce13f7SAndroid Build Coastguard Worker static constexpr struct { 269*03ce13f7SAndroid Build Coastguard Worker uint16_t Val; 270*03ce13f7SAndroid Build Coastguard Worker unsigned Is64 : 1; 271*03ce13f7SAndroid Build Coastguard Worker unsigned Is32 : 1; 272*03ce13f7SAndroid Build Coastguard Worker unsigned Is16 : 1; 273*03ce13f7SAndroid Build Coastguard Worker unsigned Is8 : 1; 274*03ce13f7SAndroid Build Coastguard Worker unsigned IsXmm : 1; 275*03ce13f7SAndroid Build Coastguard Worker unsigned Is64To8 : 1; 276*03ce13f7SAndroid Build Coastguard Worker unsigned Is32To8 : 1; 277*03ce13f7SAndroid Build Coastguard Worker unsigned Is16To8 : 1; 278*03ce13f7SAndroid Build Coastguard Worker unsigned IsTrunc8Rcvr : 1; 279*03ce13f7SAndroid Build Coastguard Worker unsigned IsAhRcvr : 1; 280*03ce13f7SAndroid Build Coastguard Worker #define NUM_ALIASES_BITS 2 281*03ce13f7SAndroid Build Coastguard Worker SizeT NumAliases : (NUM_ALIASES_BITS + 1); 282*03ce13f7SAndroid Build Coastguard Worker uint16_t Aliases[1 << NUM_ALIASES_BITS]; 283*03ce13f7SAndroid Build Coastguard Worker #undef NUM_ALIASES_BITS 284*03ce13f7SAndroid Build Coastguard Worker } X8632RegTable[Reg_NUM] = { 285*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 286*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 287*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 288*03ce13f7SAndroid Build Coastguard Worker { \ 289*03ce13f7SAndroid Build Coastguard Worker val, is64, is32, \ 290*03ce13f7SAndroid Build Coastguard Worker is16, is8, isXmm, \ 291*03ce13f7SAndroid Build Coastguard Worker is64To8, is32To8, is16To8, \ 292*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, (std::initializer_list<uint16_t> aliases).size(), \ 293*03ce13f7SAndroid Build Coastguard Worker aliases, \ 294*03ce13f7SAndroid Build Coastguard Worker }, 295*03ce13f7SAndroid Build Coastguard Worker REGX8632_TABLE 296*03ce13f7SAndroid Build Coastguard Worker #undef X 297*03ce13f7SAndroid Build Coastguard Worker }; 298*03ce13f7SAndroid Build Coastguard Worker 299*03ce13f7SAndroid Build Coastguard Worker for (SizeT ii = 0; ii < llvm::array_lengthof(X8632RegTable); ++ii) { 300*03ce13f7SAndroid Build Coastguard Worker const auto &Entry = X8632RegTable[ii]; 301*03ce13f7SAndroid Build Coastguard Worker (IntegerRegistersI32)[Entry.Val] = Entry.Is32; 302*03ce13f7SAndroid Build Coastguard Worker (IntegerRegistersI16)[Entry.Val] = Entry.Is16; 303*03ce13f7SAndroid Build Coastguard Worker (IntegerRegistersI8)[Entry.Val] = Entry.Is8; 304*03ce13f7SAndroid Build Coastguard Worker (FloatRegisters)[Entry.Val] = Entry.IsXmm; 305*03ce13f7SAndroid Build Coastguard Worker (VectorRegisters)[Entry.Val] = Entry.IsXmm; 306*03ce13f7SAndroid Build Coastguard Worker (Trunc64To8Registers)[Entry.Val] = Entry.Is64To8; 307*03ce13f7SAndroid Build Coastguard Worker (Trunc32To8Registers)[Entry.Val] = Entry.Is32To8; 308*03ce13f7SAndroid Build Coastguard Worker (Trunc16To8Registers)[Entry.Val] = Entry.Is16To8; 309*03ce13f7SAndroid Build Coastguard Worker (Trunc8RcvrRegisters)[Entry.Val] = Entry.IsTrunc8Rcvr; 310*03ce13f7SAndroid Build Coastguard Worker (AhRcvrRegisters)[Entry.Val] = Entry.IsAhRcvr; 311*03ce13f7SAndroid Build Coastguard Worker (*RegisterAliases)[Entry.Val].resize(Reg_NUM); 312*03ce13f7SAndroid Build Coastguard Worker for (SizeT J = 0; J < Entry.NumAliases; J++) { 313*03ce13f7SAndroid Build Coastguard Worker SizeT Alias = Entry.Aliases[J]; 314*03ce13f7SAndroid Build Coastguard Worker assert(!(*RegisterAliases)[Entry.Val][Alias] && "Duplicate alias"); 315*03ce13f7SAndroid Build Coastguard Worker (*RegisterAliases)[Entry.Val].set(Alias); 316*03ce13f7SAndroid Build Coastguard Worker } 317*03ce13f7SAndroid Build Coastguard Worker (*RegisterAliases)[Entry.Val].set(Entry.Val); 318*03ce13f7SAndroid Build Coastguard Worker } 319*03ce13f7SAndroid Build Coastguard Worker 320*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_void] = InvalidRegisters; 321*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8; 322*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_i8] = IntegerRegistersI8; 323*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_i16] = IntegerRegistersI16; 324*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_i32] = IntegerRegistersI32; 325*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_i64] = InvalidRegisters; 326*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_f32] = FloatRegisters; 327*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_f64] = FloatRegisters; 328*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_v4i1] = VectorRegisters; 329*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_v8i1] = VectorRegisters; 330*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_v16i1] = VectorRegisters; 331*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_v16i8] = VectorRegisters; 332*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_v8i16] = VectorRegisters; 333*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_v4i32] = VectorRegisters; 334*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RC_v4f32] = VectorRegisters; 335*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RCX86_Is64To8] = Trunc64To8Registers; 336*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RCX86_Is32To8] = Trunc32To8Registers; 337*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RCX86_Is16To8] = Trunc16To8Registers; 338*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RCX86_IsTrunc8Rcvr] = Trunc8RcvrRegisters; 339*03ce13f7SAndroid Build Coastguard Worker (*TypeToRegisterSet)[RCX86_IsAhRcvr] = AhRcvrRegisters; 340*03ce13f7SAndroid Build Coastguard Worker } 341*03ce13f7SAndroid Build Coastguard Worker 342*03ce13f7SAndroid Build Coastguard Worker static inline SmallBitVector getRegisterSet(const::Ice::ClFlags &,TargetLowering::RegSetMask Include,TargetLowering::RegSetMask Exclude)343*03ce13f7SAndroid Build Coastguard Worker getRegisterSet(const ::Ice::ClFlags & /*Flags*/, 344*03ce13f7SAndroid Build Coastguard Worker TargetLowering::RegSetMask Include, 345*03ce13f7SAndroid Build Coastguard Worker TargetLowering::RegSetMask Exclude) { 346*03ce13f7SAndroid Build Coastguard Worker SmallBitVector Registers(Reg_NUM); 347*03ce13f7SAndroid Build Coastguard Worker 348*03ce13f7SAndroid Build Coastguard Worker #define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \ 349*03ce13f7SAndroid Build Coastguard Worker isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \ 350*03ce13f7SAndroid Build Coastguard Worker isTrunc8Rcvr, isAhRcvr, aliases) \ 351*03ce13f7SAndroid Build Coastguard Worker if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave)) \ 352*03ce13f7SAndroid Build Coastguard Worker Registers[val] = true; \ 353*03ce13f7SAndroid Build Coastguard Worker if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave)) \ 354*03ce13f7SAndroid Build Coastguard Worker Registers[val] = true; \ 355*03ce13f7SAndroid Build Coastguard Worker if (stackptr && (Include & ::Ice::TargetLowering::RegSet_StackPointer)) \ 356*03ce13f7SAndroid Build Coastguard Worker Registers[val] = true; \ 357*03ce13f7SAndroid Build Coastguard Worker if (frameptr && (Include & ::Ice::TargetLowering::RegSet_FramePointer)) \ 358*03ce13f7SAndroid Build Coastguard Worker Registers[val] = true; \ 359*03ce13f7SAndroid Build Coastguard Worker if (scratch && (Exclude & ::Ice::TargetLowering::RegSet_CallerSave)) \ 360*03ce13f7SAndroid Build Coastguard Worker Registers[val] = false; \ 361*03ce13f7SAndroid Build Coastguard Worker if (preserved && (Exclude & ::Ice::TargetLowering::RegSet_CalleeSave)) \ 362*03ce13f7SAndroid Build Coastguard Worker Registers[val] = false; \ 363*03ce13f7SAndroid Build Coastguard Worker if (stackptr && (Exclude & ::Ice::TargetLowering::RegSet_StackPointer)) \ 364*03ce13f7SAndroid Build Coastguard Worker Registers[val] = false; \ 365*03ce13f7SAndroid Build Coastguard Worker if (frameptr && (Exclude & ::Ice::TargetLowering::RegSet_FramePointer)) \ 366*03ce13f7SAndroid Build Coastguard Worker Registers[val] = false; 367*03ce13f7SAndroid Build Coastguard Worker 368*03ce13f7SAndroid Build Coastguard Worker REGX8632_TABLE 369*03ce13f7SAndroid Build Coastguard Worker 370*03ce13f7SAndroid Build Coastguard Worker #undef X 371*03ce13f7SAndroid Build Coastguard Worker 372*03ce13f7SAndroid Build Coastguard Worker return Registers; 373*03ce13f7SAndroid Build Coastguard Worker } 374*03ce13f7SAndroid Build Coastguard Worker 375*03ce13f7SAndroid Build Coastguard Worker // x86-32 calling convention: 376*03ce13f7SAndroid Build Coastguard Worker // 377*03ce13f7SAndroid Build Coastguard Worker // * The first four arguments of vector type, regardless of their position 378*03ce13f7SAndroid Build Coastguard Worker // relative to the other arguments in the argument list, are placed in 379*03ce13f7SAndroid Build Coastguard Worker // registers xmm0 - xmm3. 380*03ce13f7SAndroid Build Coastguard Worker // 381*03ce13f7SAndroid Build Coastguard Worker // This intends to match the section "IA-32 Function Calling Convention" of 382*03ce13f7SAndroid Build Coastguard Worker // the document "OS X ABI Function Call Guide" by Apple. 383*03ce13f7SAndroid Build Coastguard Worker 384*03ce13f7SAndroid Build Coastguard Worker /// The maximum number of arguments to pass in XMM registers 385*03ce13f7SAndroid Build Coastguard Worker static constexpr uint32_t X86_MAX_XMM_ARGS = 4; 386*03ce13f7SAndroid Build Coastguard Worker /// The maximum number of arguments to pass in GPR registers 387*03ce13f7SAndroid Build Coastguard Worker static constexpr uint32_t X86_MAX_GPR_ARGS = 0; 388*03ce13f7SAndroid Build Coastguard Worker /// Get the register for a given argument slot in the XMM registers. getRegisterForXmmArgNum(uint32_t ArgNum)389*03ce13f7SAndroid Build Coastguard Worker static inline RegNumT getRegisterForXmmArgNum(uint32_t ArgNum) { 390*03ce13f7SAndroid Build Coastguard Worker // TODO(sehr): Change to use the CCArg technique used in ARM32. 391*03ce13f7SAndroid Build Coastguard Worker static_assert(Reg_xmm0 + 1 == Reg_xmm1, 392*03ce13f7SAndroid Build Coastguard Worker "Inconsistency between XMM register numbers and ordinals"); 393*03ce13f7SAndroid Build Coastguard Worker if (ArgNum >= X86_MAX_XMM_ARGS) { 394*03ce13f7SAndroid Build Coastguard Worker return RegNumT(); 395*03ce13f7SAndroid Build Coastguard Worker } 396*03ce13f7SAndroid Build Coastguard Worker return RegNumT::fixme(Reg_xmm0 + ArgNum); 397*03ce13f7SAndroid Build Coastguard Worker } 398*03ce13f7SAndroid Build Coastguard Worker /// Get the register for a given argument slot in the GPRs. getRegisterForGprArgNum(Type Ty,uint32_t ArgNum)399*03ce13f7SAndroid Build Coastguard Worker static inline RegNumT getRegisterForGprArgNum(Type Ty, uint32_t ArgNum) { 400*03ce13f7SAndroid Build Coastguard Worker assert(Ty == IceType_i64 || Ty == IceType_i32); 401*03ce13f7SAndroid Build Coastguard Worker (void)Ty; 402*03ce13f7SAndroid Build Coastguard Worker (void)ArgNum; 403*03ce13f7SAndroid Build Coastguard Worker return RegNumT(); 404*03ce13f7SAndroid Build Coastguard Worker } 405*03ce13f7SAndroid Build Coastguard Worker // Given the absolute argument position and argument position by type, return 406*03ce13f7SAndroid Build Coastguard Worker // the register index to assign it to. getArgIndex(SizeT argPos,SizeT argPosByType)407*03ce13f7SAndroid Build Coastguard Worker static inline SizeT getArgIndex(SizeT argPos, SizeT argPosByType) { 408*03ce13f7SAndroid Build Coastguard Worker (void)argPos; 409*03ce13f7SAndroid Build Coastguard Worker return argPosByType; 410*03ce13f7SAndroid Build Coastguard Worker }; 411*03ce13f7SAndroid Build Coastguard Worker }; 412*03ce13f7SAndroid Build Coastguard Worker 413*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice 414*03ce13f7SAndroid Build Coastguard Worker 415*03ce13f7SAndroid Build Coastguard Worker #endif // SUBZERO_SRC_ICEREGISTERSX8632_H 416