1*0b57cec5SDimitry Andric //===--- X86.h - Declare X86 target feature support -------------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file declares X86 TargetInfo objects. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_X86_H 14*0b57cec5SDimitry Andric #define LLVM_CLANG_LIB_BASIC_TARGETS_X86_H 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "OSTargets.h" 17*0b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 18*0b57cec5SDimitry Andric #include "clang/Basic/TargetOptions.h" 19*0b57cec5SDimitry Andric #include "llvm/ADT/Triple.h" 20*0b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric namespace clang { 23*0b57cec5SDimitry Andric namespace targets { 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andric // X86 target abstract base class; x86-32 and x86-64 are very close, so 26*0b57cec5SDimitry Andric // most of the implementation can be shared. 27*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric enum X86SSEEnum { 30*0b57cec5SDimitry Andric NoSSE, 31*0b57cec5SDimitry Andric SSE1, 32*0b57cec5SDimitry Andric SSE2, 33*0b57cec5SDimitry Andric SSE3, 34*0b57cec5SDimitry Andric SSSE3, 35*0b57cec5SDimitry Andric SSE41, 36*0b57cec5SDimitry Andric SSE42, 37*0b57cec5SDimitry Andric AVX, 38*0b57cec5SDimitry Andric AVX2, 39*0b57cec5SDimitry Andric AVX512F 40*0b57cec5SDimitry Andric } SSELevel = NoSSE; 41*0b57cec5SDimitry Andric enum MMX3DNowEnum { 42*0b57cec5SDimitry Andric NoMMX3DNow, 43*0b57cec5SDimitry Andric MMX, 44*0b57cec5SDimitry Andric AMD3DNow, 45*0b57cec5SDimitry Andric AMD3DNowAthlon 46*0b57cec5SDimitry Andric } MMX3DNowLevel = NoMMX3DNow; 47*0b57cec5SDimitry Andric enum XOPEnum { NoXOP, SSE4A, FMA4, XOP } XOPLevel = NoXOP; 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric bool HasAES = false; 50*0b57cec5SDimitry Andric bool HasVAES = false; 51*0b57cec5SDimitry Andric bool HasPCLMUL = false; 52*0b57cec5SDimitry Andric bool HasVPCLMULQDQ = false; 53*0b57cec5SDimitry Andric bool HasGFNI = false; 54*0b57cec5SDimitry Andric bool HasLZCNT = false; 55*0b57cec5SDimitry Andric bool HasRDRND = false; 56*0b57cec5SDimitry Andric bool HasFSGSBASE = false; 57*0b57cec5SDimitry Andric bool HasBMI = false; 58*0b57cec5SDimitry Andric bool HasBMI2 = false; 59*0b57cec5SDimitry Andric bool HasPOPCNT = false; 60*0b57cec5SDimitry Andric bool HasRTM = false; 61*0b57cec5SDimitry Andric bool HasPRFCHW = false; 62*0b57cec5SDimitry Andric bool HasRDSEED = false; 63*0b57cec5SDimitry Andric bool HasADX = false; 64*0b57cec5SDimitry Andric bool HasTBM = false; 65*0b57cec5SDimitry Andric bool HasLWP = false; 66*0b57cec5SDimitry Andric bool HasFMA = false; 67*0b57cec5SDimitry Andric bool HasF16C = false; 68*0b57cec5SDimitry Andric bool HasAVX512CD = false; 69*0b57cec5SDimitry Andric bool HasAVX512VPOPCNTDQ = false; 70*0b57cec5SDimitry Andric bool HasAVX512VNNI = false; 71*0b57cec5SDimitry Andric bool HasAVX512BF16 = false; 72*0b57cec5SDimitry Andric bool HasAVX512ER = false; 73*0b57cec5SDimitry Andric bool HasAVX512PF = false; 74*0b57cec5SDimitry Andric bool HasAVX512DQ = false; 75*0b57cec5SDimitry Andric bool HasAVX512BITALG = false; 76*0b57cec5SDimitry Andric bool HasAVX512BW = false; 77*0b57cec5SDimitry Andric bool HasAVX512VL = false; 78*0b57cec5SDimitry Andric bool HasAVX512VBMI = false; 79*0b57cec5SDimitry Andric bool HasAVX512VBMI2 = false; 80*0b57cec5SDimitry Andric bool HasAVX512IFMA = false; 81*0b57cec5SDimitry Andric bool HasAVX512VP2INTERSECT = false; 82*0b57cec5SDimitry Andric bool HasSHA = false; 83*0b57cec5SDimitry Andric bool HasMPX = false; 84*0b57cec5SDimitry Andric bool HasSHSTK = false; 85*0b57cec5SDimitry Andric bool HasSGX = false; 86*0b57cec5SDimitry Andric bool HasCX8 = false; 87*0b57cec5SDimitry Andric bool HasCX16 = false; 88*0b57cec5SDimitry Andric bool HasFXSR = false; 89*0b57cec5SDimitry Andric bool HasXSAVE = false; 90*0b57cec5SDimitry Andric bool HasXSAVEOPT = false; 91*0b57cec5SDimitry Andric bool HasXSAVEC = false; 92*0b57cec5SDimitry Andric bool HasXSAVES = false; 93*0b57cec5SDimitry Andric bool HasMWAITX = false; 94*0b57cec5SDimitry Andric bool HasCLZERO = false; 95*0b57cec5SDimitry Andric bool HasCLDEMOTE = false; 96*0b57cec5SDimitry Andric bool HasPCONFIG = false; 97*0b57cec5SDimitry Andric bool HasPKU = false; 98*0b57cec5SDimitry Andric bool HasCLFLUSHOPT = false; 99*0b57cec5SDimitry Andric bool HasCLWB = false; 100*0b57cec5SDimitry Andric bool HasMOVBE = false; 101*0b57cec5SDimitry Andric bool HasPREFETCHWT1 = false; 102*0b57cec5SDimitry Andric bool HasRDPID = false; 103*0b57cec5SDimitry Andric bool HasRetpolineExternalThunk = false; 104*0b57cec5SDimitry Andric bool HasLAHFSAHF = false; 105*0b57cec5SDimitry Andric bool HasWBNOINVD = false; 106*0b57cec5SDimitry Andric bool HasWAITPKG = false; 107*0b57cec5SDimitry Andric bool HasMOVDIRI = false; 108*0b57cec5SDimitry Andric bool HasMOVDIR64B = false; 109*0b57cec5SDimitry Andric bool HasPTWRITE = false; 110*0b57cec5SDimitry Andric bool HasINVPCID = false; 111*0b57cec5SDimitry Andric bool HasENQCMD = false; 112*0b57cec5SDimitry Andric 113*0b57cec5SDimitry Andric protected: 114*0b57cec5SDimitry Andric /// Enumeration of all of the X86 CPUs supported by Clang. 115*0b57cec5SDimitry Andric /// 116*0b57cec5SDimitry Andric /// Each enumeration represents a particular CPU supported by Clang. These 117*0b57cec5SDimitry Andric /// loosely correspond to the options passed to '-march' or '-mtune' flags. 118*0b57cec5SDimitry Andric enum CPUKind { 119*0b57cec5SDimitry Andric CK_Generic, 120*0b57cec5SDimitry Andric #define PROC(ENUM, STRING, IS64BIT) CK_##ENUM, 121*0b57cec5SDimitry Andric #include "clang/Basic/X86Target.def" 122*0b57cec5SDimitry Andric } CPU = CK_Generic; 123*0b57cec5SDimitry Andric 124*0b57cec5SDimitry Andric bool checkCPUKind(CPUKind Kind) const; 125*0b57cec5SDimitry Andric 126*0b57cec5SDimitry Andric CPUKind getCPUKind(StringRef CPU) const; 127*0b57cec5SDimitry Andric 128*0b57cec5SDimitry Andric enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default; 129*0b57cec5SDimitry Andric 130*0b57cec5SDimitry Andric public: 131*0b57cec5SDimitry Andric X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &) 132*0b57cec5SDimitry Andric : TargetInfo(Triple) { 133*0b57cec5SDimitry Andric LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); 134*0b57cec5SDimitry Andric } 135*0b57cec5SDimitry Andric 136*0b57cec5SDimitry Andric const char *getLongDoubleMangling() const override { 137*0b57cec5SDimitry Andric return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e"; 138*0b57cec5SDimitry Andric } 139*0b57cec5SDimitry Andric 140*0b57cec5SDimitry Andric unsigned getFloatEvalMethod() const override { 141*0b57cec5SDimitry Andric // X87 evaluates with 80 bits "long double" precision. 142*0b57cec5SDimitry Andric return SSELevel == NoSSE ? 2 : 0; 143*0b57cec5SDimitry Andric } 144*0b57cec5SDimitry Andric 145*0b57cec5SDimitry Andric ArrayRef<const char *> getGCCRegNames() const override; 146*0b57cec5SDimitry Andric 147*0b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 148*0b57cec5SDimitry Andric return None; 149*0b57cec5SDimitry Andric } 150*0b57cec5SDimitry Andric 151*0b57cec5SDimitry Andric ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; 152*0b57cec5SDimitry Andric 153*0b57cec5SDimitry Andric bool validateCpuSupports(StringRef Name) const override; 154*0b57cec5SDimitry Andric 155*0b57cec5SDimitry Andric bool validateCpuIs(StringRef Name) const override; 156*0b57cec5SDimitry Andric 157*0b57cec5SDimitry Andric bool validateCPUSpecificCPUDispatch(StringRef Name) const override; 158*0b57cec5SDimitry Andric 159*0b57cec5SDimitry Andric char CPUSpecificManglingCharacter(StringRef Name) const override; 160*0b57cec5SDimitry Andric 161*0b57cec5SDimitry Andric void getCPUSpecificCPUDispatchFeatures( 162*0b57cec5SDimitry Andric StringRef Name, 163*0b57cec5SDimitry Andric llvm::SmallVectorImpl<StringRef> &Features) const override; 164*0b57cec5SDimitry Andric 165*0b57cec5SDimitry Andric bool validateAsmConstraint(const char *&Name, 166*0b57cec5SDimitry Andric TargetInfo::ConstraintInfo &info) const override; 167*0b57cec5SDimitry Andric 168*0b57cec5SDimitry Andric bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize, 169*0b57cec5SDimitry Andric bool &HasSizeMismatch) const override { 170*0b57cec5SDimitry Andric // esp and ebp are the only 32-bit registers the x86 backend can currently 171*0b57cec5SDimitry Andric // handle. 172*0b57cec5SDimitry Andric if (RegName.equals("esp") || RegName.equals("ebp")) { 173*0b57cec5SDimitry Andric // Check that the register size is 32-bit. 174*0b57cec5SDimitry Andric HasSizeMismatch = RegSize != 32; 175*0b57cec5SDimitry Andric return true; 176*0b57cec5SDimitry Andric } 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric return false; 179*0b57cec5SDimitry Andric } 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric bool validateOutputSize(StringRef Constraint, unsigned Size) const override; 182*0b57cec5SDimitry Andric 183*0b57cec5SDimitry Andric bool validateInputSize(StringRef Constraint, unsigned Size) const override; 184*0b57cec5SDimitry Andric 185*0b57cec5SDimitry Andric virtual bool 186*0b57cec5SDimitry Andric checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override { 187*0b57cec5SDimitry Andric return true; 188*0b57cec5SDimitry Andric }; 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric virtual bool 191*0b57cec5SDimitry Andric checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override { 192*0b57cec5SDimitry Andric return true; 193*0b57cec5SDimitry Andric }; 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric 196*0b57cec5SDimitry Andric virtual bool validateOperandSize(StringRef Constraint, unsigned Size) const; 197*0b57cec5SDimitry Andric 198*0b57cec5SDimitry Andric std::string convertConstraint(const char *&Constraint) const override; 199*0b57cec5SDimitry Andric const char *getClobbers() const override { 200*0b57cec5SDimitry Andric return "~{dirflag},~{fpsr},~{flags}"; 201*0b57cec5SDimitry Andric } 202*0b57cec5SDimitry Andric 203*0b57cec5SDimitry Andric StringRef getConstraintRegister(StringRef Constraint, 204*0b57cec5SDimitry Andric StringRef Expression) const override { 205*0b57cec5SDimitry Andric StringRef::iterator I, E; 206*0b57cec5SDimitry Andric for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) { 207*0b57cec5SDimitry Andric if (isalpha(*I) || *I == '@') 208*0b57cec5SDimitry Andric break; 209*0b57cec5SDimitry Andric } 210*0b57cec5SDimitry Andric if (I == E) 211*0b57cec5SDimitry Andric return ""; 212*0b57cec5SDimitry Andric switch (*I) { 213*0b57cec5SDimitry Andric // For the register constraints, return the matching register name 214*0b57cec5SDimitry Andric case 'a': 215*0b57cec5SDimitry Andric return "ax"; 216*0b57cec5SDimitry Andric case 'b': 217*0b57cec5SDimitry Andric return "bx"; 218*0b57cec5SDimitry Andric case 'c': 219*0b57cec5SDimitry Andric return "cx"; 220*0b57cec5SDimitry Andric case 'd': 221*0b57cec5SDimitry Andric return "dx"; 222*0b57cec5SDimitry Andric case 'S': 223*0b57cec5SDimitry Andric return "si"; 224*0b57cec5SDimitry Andric case 'D': 225*0b57cec5SDimitry Andric return "di"; 226*0b57cec5SDimitry Andric // In case the constraint is 'r' we need to return Expression 227*0b57cec5SDimitry Andric case 'r': 228*0b57cec5SDimitry Andric return Expression; 229*0b57cec5SDimitry Andric // Double letters Y<x> constraints 230*0b57cec5SDimitry Andric case 'Y': 231*0b57cec5SDimitry Andric if ((++I != E) && ((*I == '0') || (*I == 'z'))) 232*0b57cec5SDimitry Andric return "xmm0"; 233*0b57cec5SDimitry Andric break; 234*0b57cec5SDimitry Andric default: 235*0b57cec5SDimitry Andric break; 236*0b57cec5SDimitry Andric } 237*0b57cec5SDimitry Andric return ""; 238*0b57cec5SDimitry Andric } 239*0b57cec5SDimitry Andric 240*0b57cec5SDimitry Andric bool useFP16ConversionIntrinsics() const override { 241*0b57cec5SDimitry Andric return false; 242*0b57cec5SDimitry Andric } 243*0b57cec5SDimitry Andric 244*0b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 245*0b57cec5SDimitry Andric MacroBuilder &Builder) const override; 246*0b57cec5SDimitry Andric 247*0b57cec5SDimitry Andric static void setSSELevel(llvm::StringMap<bool> &Features, X86SSEEnum Level, 248*0b57cec5SDimitry Andric bool Enabled); 249*0b57cec5SDimitry Andric 250*0b57cec5SDimitry Andric static void setMMXLevel(llvm::StringMap<bool> &Features, MMX3DNowEnum Level, 251*0b57cec5SDimitry Andric bool Enabled); 252*0b57cec5SDimitry Andric 253*0b57cec5SDimitry Andric static void setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level, 254*0b57cec5SDimitry Andric bool Enabled); 255*0b57cec5SDimitry Andric 256*0b57cec5SDimitry Andric void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, 257*0b57cec5SDimitry Andric bool Enabled) const override { 258*0b57cec5SDimitry Andric setFeatureEnabledImpl(Features, Name, Enabled); 259*0b57cec5SDimitry Andric } 260*0b57cec5SDimitry Andric 261*0b57cec5SDimitry Andric // This exists purely to cut down on the number of virtual calls in 262*0b57cec5SDimitry Andric // initFeatureMap which calls this repeatedly. 263*0b57cec5SDimitry Andric static void setFeatureEnabledImpl(llvm::StringMap<bool> &Features, 264*0b57cec5SDimitry Andric StringRef Name, bool Enabled); 265*0b57cec5SDimitry Andric 266*0b57cec5SDimitry Andric bool 267*0b57cec5SDimitry Andric initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 268*0b57cec5SDimitry Andric StringRef CPU, 269*0b57cec5SDimitry Andric const std::vector<std::string> &FeaturesVec) const override; 270*0b57cec5SDimitry Andric 271*0b57cec5SDimitry Andric bool isValidFeatureName(StringRef Name) const override; 272*0b57cec5SDimitry Andric 273*0b57cec5SDimitry Andric bool hasFeature(StringRef Feature) const override; 274*0b57cec5SDimitry Andric 275*0b57cec5SDimitry Andric bool handleTargetFeatures(std::vector<std::string> &Features, 276*0b57cec5SDimitry Andric DiagnosticsEngine &Diags) override; 277*0b57cec5SDimitry Andric 278*0b57cec5SDimitry Andric StringRef getABI() const override { 279*0b57cec5SDimitry Andric if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F) 280*0b57cec5SDimitry Andric return "avx512"; 281*0b57cec5SDimitry Andric if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX) 282*0b57cec5SDimitry Andric return "avx"; 283*0b57cec5SDimitry Andric if (getTriple().getArch() == llvm::Triple::x86 && 284*0b57cec5SDimitry Andric MMX3DNowLevel == NoMMX3DNow) 285*0b57cec5SDimitry Andric return "no-mmx"; 286*0b57cec5SDimitry Andric return ""; 287*0b57cec5SDimitry Andric } 288*0b57cec5SDimitry Andric 289*0b57cec5SDimitry Andric bool isValidCPUName(StringRef Name) const override { 290*0b57cec5SDimitry Andric return checkCPUKind(getCPUKind(Name)); 291*0b57cec5SDimitry Andric } 292*0b57cec5SDimitry Andric 293*0b57cec5SDimitry Andric void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 294*0b57cec5SDimitry Andric 295*0b57cec5SDimitry Andric bool setCPU(const std::string &Name) override { 296*0b57cec5SDimitry Andric return checkCPUKind(CPU = getCPUKind(Name)); 297*0b57cec5SDimitry Andric } 298*0b57cec5SDimitry Andric 299*0b57cec5SDimitry Andric unsigned multiVersionSortPriority(StringRef Name) const override; 300*0b57cec5SDimitry Andric 301*0b57cec5SDimitry Andric bool setFPMath(StringRef Name) override; 302*0b57cec5SDimitry Andric 303*0b57cec5SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 304*0b57cec5SDimitry Andric // Most of the non-ARM calling conventions are i386 conventions. 305*0b57cec5SDimitry Andric switch (CC) { 306*0b57cec5SDimitry Andric case CC_X86ThisCall: 307*0b57cec5SDimitry Andric case CC_X86FastCall: 308*0b57cec5SDimitry Andric case CC_X86StdCall: 309*0b57cec5SDimitry Andric case CC_X86VectorCall: 310*0b57cec5SDimitry Andric case CC_X86RegCall: 311*0b57cec5SDimitry Andric case CC_C: 312*0b57cec5SDimitry Andric case CC_PreserveMost: 313*0b57cec5SDimitry Andric case CC_Swift: 314*0b57cec5SDimitry Andric case CC_X86Pascal: 315*0b57cec5SDimitry Andric case CC_IntelOclBicc: 316*0b57cec5SDimitry Andric case CC_OpenCLKernel: 317*0b57cec5SDimitry Andric return CCCR_OK; 318*0b57cec5SDimitry Andric default: 319*0b57cec5SDimitry Andric return CCCR_Warning; 320*0b57cec5SDimitry Andric } 321*0b57cec5SDimitry Andric } 322*0b57cec5SDimitry Andric 323*0b57cec5SDimitry Andric CallingConv getDefaultCallingConv() const override { 324*0b57cec5SDimitry Andric return CC_C; 325*0b57cec5SDimitry Andric } 326*0b57cec5SDimitry Andric 327*0b57cec5SDimitry Andric bool hasSjLjLowering() const override { return true; } 328*0b57cec5SDimitry Andric 329*0b57cec5SDimitry Andric void setSupportedOpenCLOpts() override { 330*0b57cec5SDimitry Andric getSupportedOpenCLOpts().supportAll(); 331*0b57cec5SDimitry Andric } 332*0b57cec5SDimitry Andric }; 333*0b57cec5SDimitry Andric 334*0b57cec5SDimitry Andric // X86-32 generic target 335*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo { 336*0b57cec5SDimitry Andric public: 337*0b57cec5SDimitry Andric X86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 338*0b57cec5SDimitry Andric : X86TargetInfo(Triple, Opts) { 339*0b57cec5SDimitry Andric DoubleAlign = LongLongAlign = 32; 340*0b57cec5SDimitry Andric LongDoubleWidth = 96; 341*0b57cec5SDimitry Andric LongDoubleAlign = 32; 342*0b57cec5SDimitry Andric SuitableAlign = 128; 343*0b57cec5SDimitry Andric resetDataLayout("e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"); 344*0b57cec5SDimitry Andric SizeType = UnsignedInt; 345*0b57cec5SDimitry Andric PtrDiffType = SignedInt; 346*0b57cec5SDimitry Andric IntPtrType = SignedInt; 347*0b57cec5SDimitry Andric RegParmMax = 3; 348*0b57cec5SDimitry Andric 349*0b57cec5SDimitry Andric // Use fpret for all types. 350*0b57cec5SDimitry Andric RealTypeUsesObjCFPRet = 351*0b57cec5SDimitry Andric ((1 << TargetInfo::Float) | (1 << TargetInfo::Double) | 352*0b57cec5SDimitry Andric (1 << TargetInfo::LongDouble)); 353*0b57cec5SDimitry Andric 354*0b57cec5SDimitry Andric // x86-32 has atomics up to 8 bytes 355*0b57cec5SDimitry Andric MaxAtomicPromoteWidth = 64; 356*0b57cec5SDimitry Andric MaxAtomicInlineWidth = 32; 357*0b57cec5SDimitry Andric } 358*0b57cec5SDimitry Andric 359*0b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override { 360*0b57cec5SDimitry Andric return TargetInfo::CharPtrBuiltinVaList; 361*0b57cec5SDimitry Andric } 362*0b57cec5SDimitry Andric 363*0b57cec5SDimitry Andric int getEHDataRegisterNumber(unsigned RegNo) const override { 364*0b57cec5SDimitry Andric if (RegNo == 0) 365*0b57cec5SDimitry Andric return 0; 366*0b57cec5SDimitry Andric if (RegNo == 1) 367*0b57cec5SDimitry Andric return 2; 368*0b57cec5SDimitry Andric return -1; 369*0b57cec5SDimitry Andric } 370*0b57cec5SDimitry Andric 371*0b57cec5SDimitry Andric bool validateOperandSize(StringRef Constraint, unsigned Size) const override { 372*0b57cec5SDimitry Andric switch (Constraint[0]) { 373*0b57cec5SDimitry Andric default: 374*0b57cec5SDimitry Andric break; 375*0b57cec5SDimitry Andric case 'R': 376*0b57cec5SDimitry Andric case 'q': 377*0b57cec5SDimitry Andric case 'Q': 378*0b57cec5SDimitry Andric case 'a': 379*0b57cec5SDimitry Andric case 'b': 380*0b57cec5SDimitry Andric case 'c': 381*0b57cec5SDimitry Andric case 'd': 382*0b57cec5SDimitry Andric case 'S': 383*0b57cec5SDimitry Andric case 'D': 384*0b57cec5SDimitry Andric return Size <= 32; 385*0b57cec5SDimitry Andric case 'A': 386*0b57cec5SDimitry Andric return Size <= 64; 387*0b57cec5SDimitry Andric } 388*0b57cec5SDimitry Andric 389*0b57cec5SDimitry Andric return X86TargetInfo::validateOperandSize(Constraint, Size); 390*0b57cec5SDimitry Andric } 391*0b57cec5SDimitry Andric 392*0b57cec5SDimitry Andric void setMaxAtomicWidth() override { 393*0b57cec5SDimitry Andric if (hasFeature("cx8")) 394*0b57cec5SDimitry Andric MaxAtomicInlineWidth = 64; 395*0b57cec5SDimitry Andric } 396*0b57cec5SDimitry Andric 397*0b57cec5SDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const override; 398*0b57cec5SDimitry Andric }; 399*0b57cec5SDimitry Andric 400*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo 401*0b57cec5SDimitry Andric : public NetBSDTargetInfo<X86_32TargetInfo> { 402*0b57cec5SDimitry Andric public: 403*0b57cec5SDimitry Andric NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 404*0b57cec5SDimitry Andric : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {} 405*0b57cec5SDimitry Andric 406*0b57cec5SDimitry Andric unsigned getFloatEvalMethod() const override { 407*0b57cec5SDimitry Andric unsigned Major, Minor, Micro; 408*0b57cec5SDimitry Andric getTriple().getOSVersion(Major, Minor, Micro); 409*0b57cec5SDimitry Andric // New NetBSD uses the default rounding mode. 410*0b57cec5SDimitry Andric if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 26) || Major == 0) 411*0b57cec5SDimitry Andric return X86_32TargetInfo::getFloatEvalMethod(); 412*0b57cec5SDimitry Andric // NetBSD before 6.99.26 defaults to "double" rounding. 413*0b57cec5SDimitry Andric return 1; 414*0b57cec5SDimitry Andric } 415*0b57cec5SDimitry Andric }; 416*0b57cec5SDimitry Andric 417*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo 418*0b57cec5SDimitry Andric : public OpenBSDTargetInfo<X86_32TargetInfo> { 419*0b57cec5SDimitry Andric public: 420*0b57cec5SDimitry Andric OpenBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 421*0b57cec5SDimitry Andric : OpenBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) { 422*0b57cec5SDimitry Andric SizeType = UnsignedLong; 423*0b57cec5SDimitry Andric IntPtrType = SignedLong; 424*0b57cec5SDimitry Andric PtrDiffType = SignedLong; 425*0b57cec5SDimitry Andric } 426*0b57cec5SDimitry Andric }; 427*0b57cec5SDimitry Andric 428*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo 429*0b57cec5SDimitry Andric : public DarwinTargetInfo<X86_32TargetInfo> { 430*0b57cec5SDimitry Andric public: 431*0b57cec5SDimitry Andric DarwinI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 432*0b57cec5SDimitry Andric : DarwinTargetInfo<X86_32TargetInfo>(Triple, Opts) { 433*0b57cec5SDimitry Andric LongDoubleWidth = 128; 434*0b57cec5SDimitry Andric LongDoubleAlign = 128; 435*0b57cec5SDimitry Andric SuitableAlign = 128; 436*0b57cec5SDimitry Andric MaxVectorAlign = 256; 437*0b57cec5SDimitry Andric // The watchOS simulator uses the builtin bool type for Objective-C. 438*0b57cec5SDimitry Andric llvm::Triple T = llvm::Triple(Triple); 439*0b57cec5SDimitry Andric if (T.isWatchOS()) 440*0b57cec5SDimitry Andric UseSignedCharForObjCBool = false; 441*0b57cec5SDimitry Andric SizeType = UnsignedLong; 442*0b57cec5SDimitry Andric IntPtrType = SignedLong; 443*0b57cec5SDimitry Andric resetDataLayout("e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128"); 444*0b57cec5SDimitry Andric HasAlignMac68kSupport = true; 445*0b57cec5SDimitry Andric } 446*0b57cec5SDimitry Andric 447*0b57cec5SDimitry Andric bool handleTargetFeatures(std::vector<std::string> &Features, 448*0b57cec5SDimitry Andric DiagnosticsEngine &Diags) override { 449*0b57cec5SDimitry Andric if (!DarwinTargetInfo<X86_32TargetInfo>::handleTargetFeatures(Features, 450*0b57cec5SDimitry Andric Diags)) 451*0b57cec5SDimitry Andric return false; 452*0b57cec5SDimitry Andric // We now know the features we have: we can decide how to align vectors. 453*0b57cec5SDimitry Andric MaxVectorAlign = 454*0b57cec5SDimitry Andric hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128; 455*0b57cec5SDimitry Andric return true; 456*0b57cec5SDimitry Andric } 457*0b57cec5SDimitry Andric }; 458*0b57cec5SDimitry Andric 459*0b57cec5SDimitry Andric // x86-32 Windows target 460*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo 461*0b57cec5SDimitry Andric : public WindowsTargetInfo<X86_32TargetInfo> { 462*0b57cec5SDimitry Andric public: 463*0b57cec5SDimitry Andric WindowsX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 464*0b57cec5SDimitry Andric : WindowsTargetInfo<X86_32TargetInfo>(Triple, Opts) { 465*0b57cec5SDimitry Andric DoubleAlign = LongLongAlign = 64; 466*0b57cec5SDimitry Andric bool IsWinCOFF = 467*0b57cec5SDimitry Andric getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); 468*0b57cec5SDimitry Andric resetDataLayout(IsWinCOFF 469*0b57cec5SDimitry Andric ? "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" 470*0b57cec5SDimitry Andric : "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"); 471*0b57cec5SDimitry Andric } 472*0b57cec5SDimitry Andric }; 473*0b57cec5SDimitry Andric 474*0b57cec5SDimitry Andric // x86-32 Windows Visual Studio target 475*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32TargetInfo 476*0b57cec5SDimitry Andric : public WindowsX86_32TargetInfo { 477*0b57cec5SDimitry Andric public: 478*0b57cec5SDimitry Andric MicrosoftX86_32TargetInfo(const llvm::Triple &Triple, 479*0b57cec5SDimitry Andric const TargetOptions &Opts) 480*0b57cec5SDimitry Andric : WindowsX86_32TargetInfo(Triple, Opts) { 481*0b57cec5SDimitry Andric LongDoubleWidth = LongDoubleAlign = 64; 482*0b57cec5SDimitry Andric LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 483*0b57cec5SDimitry Andric } 484*0b57cec5SDimitry Andric 485*0b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 486*0b57cec5SDimitry Andric MacroBuilder &Builder) const override { 487*0b57cec5SDimitry Andric WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder); 488*0b57cec5SDimitry Andric // The value of the following reflects processor type. 489*0b57cec5SDimitry Andric // 300=386, 400=486, 500=Pentium, 600=Blend (default) 490*0b57cec5SDimitry Andric // We lost the original triple, so we use the default. 491*0b57cec5SDimitry Andric Builder.defineMacro("_M_IX86", "600"); 492*0b57cec5SDimitry Andric } 493*0b57cec5SDimitry Andric }; 494*0b57cec5SDimitry Andric 495*0b57cec5SDimitry Andric // x86-32 MinGW target 496*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MinGWX86_32TargetInfo 497*0b57cec5SDimitry Andric : public WindowsX86_32TargetInfo { 498*0b57cec5SDimitry Andric public: 499*0b57cec5SDimitry Andric MinGWX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 500*0b57cec5SDimitry Andric : WindowsX86_32TargetInfo(Triple, Opts) { 501*0b57cec5SDimitry Andric HasFloat128 = true; 502*0b57cec5SDimitry Andric } 503*0b57cec5SDimitry Andric 504*0b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 505*0b57cec5SDimitry Andric MacroBuilder &Builder) const override { 506*0b57cec5SDimitry Andric WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder); 507*0b57cec5SDimitry Andric Builder.defineMacro("_X86_"); 508*0b57cec5SDimitry Andric } 509*0b57cec5SDimitry Andric }; 510*0b57cec5SDimitry Andric 511*0b57cec5SDimitry Andric // x86-32 Cygwin target 512*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY CygwinX86_32TargetInfo : public X86_32TargetInfo { 513*0b57cec5SDimitry Andric public: 514*0b57cec5SDimitry Andric CygwinX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 515*0b57cec5SDimitry Andric : X86_32TargetInfo(Triple, Opts) { 516*0b57cec5SDimitry Andric this->WCharType = TargetInfo::UnsignedShort; 517*0b57cec5SDimitry Andric DoubleAlign = LongLongAlign = 64; 518*0b57cec5SDimitry Andric resetDataLayout("e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"); 519*0b57cec5SDimitry Andric } 520*0b57cec5SDimitry Andric 521*0b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 522*0b57cec5SDimitry Andric MacroBuilder &Builder) const override { 523*0b57cec5SDimitry Andric X86_32TargetInfo::getTargetDefines(Opts, Builder); 524*0b57cec5SDimitry Andric Builder.defineMacro("_X86_"); 525*0b57cec5SDimitry Andric Builder.defineMacro("__CYGWIN__"); 526*0b57cec5SDimitry Andric Builder.defineMacro("__CYGWIN32__"); 527*0b57cec5SDimitry Andric addCygMingDefines(Opts, Builder); 528*0b57cec5SDimitry Andric DefineStd(Builder, "unix", Opts); 529*0b57cec5SDimitry Andric if (Opts.CPlusPlus) 530*0b57cec5SDimitry Andric Builder.defineMacro("_GNU_SOURCE"); 531*0b57cec5SDimitry Andric } 532*0b57cec5SDimitry Andric }; 533*0b57cec5SDimitry Andric 534*0b57cec5SDimitry Andric // x86-32 Haiku target 535*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo 536*0b57cec5SDimitry Andric : public HaikuTargetInfo<X86_32TargetInfo> { 537*0b57cec5SDimitry Andric public: 538*0b57cec5SDimitry Andric HaikuX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 539*0b57cec5SDimitry Andric : HaikuTargetInfo<X86_32TargetInfo>(Triple, Opts) {} 540*0b57cec5SDimitry Andric 541*0b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 542*0b57cec5SDimitry Andric MacroBuilder &Builder) const override { 543*0b57cec5SDimitry Andric HaikuTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder); 544*0b57cec5SDimitry Andric Builder.defineMacro("__INTEL__"); 545*0b57cec5SDimitry Andric } 546*0b57cec5SDimitry Andric }; 547*0b57cec5SDimitry Andric 548*0b57cec5SDimitry Andric // X86-32 MCU target 549*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo : public X86_32TargetInfo { 550*0b57cec5SDimitry Andric public: 551*0b57cec5SDimitry Andric MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 552*0b57cec5SDimitry Andric : X86_32TargetInfo(Triple, Opts) { 553*0b57cec5SDimitry Andric LongDoubleWidth = 64; 554*0b57cec5SDimitry Andric LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 555*0b57cec5SDimitry Andric resetDataLayout("e-m:e-p:32:32-i64:32-f64:32-f128:32-n8:16:32-a:0:32-S32"); 556*0b57cec5SDimitry Andric WIntType = UnsignedInt; 557*0b57cec5SDimitry Andric } 558*0b57cec5SDimitry Andric 559*0b57cec5SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 560*0b57cec5SDimitry Andric // On MCU we support only C calling convention. 561*0b57cec5SDimitry Andric return CC == CC_C ? CCCR_OK : CCCR_Warning; 562*0b57cec5SDimitry Andric } 563*0b57cec5SDimitry Andric 564*0b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 565*0b57cec5SDimitry Andric MacroBuilder &Builder) const override { 566*0b57cec5SDimitry Andric X86_32TargetInfo::getTargetDefines(Opts, Builder); 567*0b57cec5SDimitry Andric Builder.defineMacro("__iamcu"); 568*0b57cec5SDimitry Andric Builder.defineMacro("__iamcu__"); 569*0b57cec5SDimitry Andric } 570*0b57cec5SDimitry Andric 571*0b57cec5SDimitry Andric bool allowsLargerPreferedTypeAlignment() const override { return false; } 572*0b57cec5SDimitry Andric }; 573*0b57cec5SDimitry Andric 574*0b57cec5SDimitry Andric // x86-32 RTEMS target 575*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY RTEMSX86_32TargetInfo : public X86_32TargetInfo { 576*0b57cec5SDimitry Andric public: 577*0b57cec5SDimitry Andric RTEMSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 578*0b57cec5SDimitry Andric : X86_32TargetInfo(Triple, Opts) { 579*0b57cec5SDimitry Andric SizeType = UnsignedLong; 580*0b57cec5SDimitry Andric IntPtrType = SignedLong; 581*0b57cec5SDimitry Andric PtrDiffType = SignedLong; 582*0b57cec5SDimitry Andric } 583*0b57cec5SDimitry Andric 584*0b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 585*0b57cec5SDimitry Andric MacroBuilder &Builder) const override { 586*0b57cec5SDimitry Andric X86_32TargetInfo::getTargetDefines(Opts, Builder); 587*0b57cec5SDimitry Andric Builder.defineMacro("__INTEL__"); 588*0b57cec5SDimitry Andric Builder.defineMacro("__rtems__"); 589*0b57cec5SDimitry Andric } 590*0b57cec5SDimitry Andric }; 591*0b57cec5SDimitry Andric 592*0b57cec5SDimitry Andric // x86-64 generic target 593*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo { 594*0b57cec5SDimitry Andric public: 595*0b57cec5SDimitry Andric X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 596*0b57cec5SDimitry Andric : X86TargetInfo(Triple, Opts) { 597*0b57cec5SDimitry Andric const bool IsX32 = getTriple().getEnvironment() == llvm::Triple::GNUX32; 598*0b57cec5SDimitry Andric bool IsWinCOFF = 599*0b57cec5SDimitry Andric getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); 600*0b57cec5SDimitry Andric LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64; 601*0b57cec5SDimitry Andric LongDoubleWidth = 128; 602*0b57cec5SDimitry Andric LongDoubleAlign = 128; 603*0b57cec5SDimitry Andric LargeArrayMinWidth = 128; 604*0b57cec5SDimitry Andric LargeArrayAlign = 128; 605*0b57cec5SDimitry Andric SuitableAlign = 128; 606*0b57cec5SDimitry Andric SizeType = IsX32 ? UnsignedInt : UnsignedLong; 607*0b57cec5SDimitry Andric PtrDiffType = IsX32 ? SignedInt : SignedLong; 608*0b57cec5SDimitry Andric IntPtrType = IsX32 ? SignedInt : SignedLong; 609*0b57cec5SDimitry Andric IntMaxType = IsX32 ? SignedLongLong : SignedLong; 610*0b57cec5SDimitry Andric Int64Type = IsX32 ? SignedLongLong : SignedLong; 611*0b57cec5SDimitry Andric RegParmMax = 6; 612*0b57cec5SDimitry Andric 613*0b57cec5SDimitry Andric // Pointers are 32-bit in x32. 614*0b57cec5SDimitry Andric resetDataLayout(IsX32 615*0b57cec5SDimitry Andric ? "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128" 616*0b57cec5SDimitry Andric : IsWinCOFF ? "e-m:w-i64:64-f80:128-n8:16:32:64-S128" 617*0b57cec5SDimitry Andric : "e-m:e-i64:64-f80:128-n8:16:32:64-S128"); 618*0b57cec5SDimitry Andric 619*0b57cec5SDimitry Andric // Use fpret only for long double. 620*0b57cec5SDimitry Andric RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble); 621*0b57cec5SDimitry Andric 622*0b57cec5SDimitry Andric // Use fp2ret for _Complex long double. 623*0b57cec5SDimitry Andric ComplexLongDoubleUsesFP2Ret = true; 624*0b57cec5SDimitry Andric 625*0b57cec5SDimitry Andric // Make __builtin_ms_va_list available. 626*0b57cec5SDimitry Andric HasBuiltinMSVaList = true; 627*0b57cec5SDimitry Andric 628*0b57cec5SDimitry Andric // x86-64 has atomics up to 16 bytes. 629*0b57cec5SDimitry Andric MaxAtomicPromoteWidth = 128; 630*0b57cec5SDimitry Andric MaxAtomicInlineWidth = 64; 631*0b57cec5SDimitry Andric } 632*0b57cec5SDimitry Andric 633*0b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override { 634*0b57cec5SDimitry Andric return TargetInfo::X86_64ABIBuiltinVaList; 635*0b57cec5SDimitry Andric } 636*0b57cec5SDimitry Andric 637*0b57cec5SDimitry Andric int getEHDataRegisterNumber(unsigned RegNo) const override { 638*0b57cec5SDimitry Andric if (RegNo == 0) 639*0b57cec5SDimitry Andric return 0; 640*0b57cec5SDimitry Andric if (RegNo == 1) 641*0b57cec5SDimitry Andric return 1; 642*0b57cec5SDimitry Andric return -1; 643*0b57cec5SDimitry Andric } 644*0b57cec5SDimitry Andric 645*0b57cec5SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 646*0b57cec5SDimitry Andric switch (CC) { 647*0b57cec5SDimitry Andric case CC_C: 648*0b57cec5SDimitry Andric case CC_Swift: 649*0b57cec5SDimitry Andric case CC_X86VectorCall: 650*0b57cec5SDimitry Andric case CC_IntelOclBicc: 651*0b57cec5SDimitry Andric case CC_Win64: 652*0b57cec5SDimitry Andric case CC_PreserveMost: 653*0b57cec5SDimitry Andric case CC_PreserveAll: 654*0b57cec5SDimitry Andric case CC_X86RegCall: 655*0b57cec5SDimitry Andric case CC_OpenCLKernel: 656*0b57cec5SDimitry Andric return CCCR_OK; 657*0b57cec5SDimitry Andric default: 658*0b57cec5SDimitry Andric return CCCR_Warning; 659*0b57cec5SDimitry Andric } 660*0b57cec5SDimitry Andric } 661*0b57cec5SDimitry Andric 662*0b57cec5SDimitry Andric CallingConv getDefaultCallingConv() const override { 663*0b57cec5SDimitry Andric return CC_C; 664*0b57cec5SDimitry Andric } 665*0b57cec5SDimitry Andric 666*0b57cec5SDimitry Andric // for x32 we need it here explicitly 667*0b57cec5SDimitry Andric bool hasInt128Type() const override { return true; } 668*0b57cec5SDimitry Andric 669*0b57cec5SDimitry Andric unsigned getUnwindWordWidth() const override { return 64; } 670*0b57cec5SDimitry Andric 671*0b57cec5SDimitry Andric unsigned getRegisterWidth() const override { return 64; } 672*0b57cec5SDimitry Andric 673*0b57cec5SDimitry Andric bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize, 674*0b57cec5SDimitry Andric bool &HasSizeMismatch) const override { 675*0b57cec5SDimitry Andric // rsp and rbp are the only 64-bit registers the x86 backend can currently 676*0b57cec5SDimitry Andric // handle. 677*0b57cec5SDimitry Andric if (RegName.equals("rsp") || RegName.equals("rbp")) { 678*0b57cec5SDimitry Andric // Check that the register size is 64-bit. 679*0b57cec5SDimitry Andric HasSizeMismatch = RegSize != 64; 680*0b57cec5SDimitry Andric return true; 681*0b57cec5SDimitry Andric } 682*0b57cec5SDimitry Andric 683*0b57cec5SDimitry Andric // Check if the register is a 32-bit register the backend can handle. 684*0b57cec5SDimitry Andric return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize, 685*0b57cec5SDimitry Andric HasSizeMismatch); 686*0b57cec5SDimitry Andric } 687*0b57cec5SDimitry Andric 688*0b57cec5SDimitry Andric void setMaxAtomicWidth() override { 689*0b57cec5SDimitry Andric if (hasFeature("cx16")) 690*0b57cec5SDimitry Andric MaxAtomicInlineWidth = 128; 691*0b57cec5SDimitry Andric } 692*0b57cec5SDimitry Andric 693*0b57cec5SDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const override; 694*0b57cec5SDimitry Andric }; 695*0b57cec5SDimitry Andric 696*0b57cec5SDimitry Andric // x86-64 Windows target 697*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo 698*0b57cec5SDimitry Andric : public WindowsTargetInfo<X86_64TargetInfo> { 699*0b57cec5SDimitry Andric public: 700*0b57cec5SDimitry Andric WindowsX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 701*0b57cec5SDimitry Andric : WindowsTargetInfo<X86_64TargetInfo>(Triple, Opts) { 702*0b57cec5SDimitry Andric LongWidth = LongAlign = 32; 703*0b57cec5SDimitry Andric DoubleAlign = LongLongAlign = 64; 704*0b57cec5SDimitry Andric IntMaxType = SignedLongLong; 705*0b57cec5SDimitry Andric Int64Type = SignedLongLong; 706*0b57cec5SDimitry Andric SizeType = UnsignedLongLong; 707*0b57cec5SDimitry Andric PtrDiffType = SignedLongLong; 708*0b57cec5SDimitry Andric IntPtrType = SignedLongLong; 709*0b57cec5SDimitry Andric } 710*0b57cec5SDimitry Andric 711*0b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override { 712*0b57cec5SDimitry Andric return TargetInfo::CharPtrBuiltinVaList; 713*0b57cec5SDimitry Andric } 714*0b57cec5SDimitry Andric 715*0b57cec5SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 716*0b57cec5SDimitry Andric switch (CC) { 717*0b57cec5SDimitry Andric case CC_X86StdCall: 718*0b57cec5SDimitry Andric case CC_X86ThisCall: 719*0b57cec5SDimitry Andric case CC_X86FastCall: 720*0b57cec5SDimitry Andric return CCCR_Ignore; 721*0b57cec5SDimitry Andric case CC_C: 722*0b57cec5SDimitry Andric case CC_X86VectorCall: 723*0b57cec5SDimitry Andric case CC_IntelOclBicc: 724*0b57cec5SDimitry Andric case CC_PreserveMost: 725*0b57cec5SDimitry Andric case CC_PreserveAll: 726*0b57cec5SDimitry Andric case CC_X86_64SysV: 727*0b57cec5SDimitry Andric case CC_Swift: 728*0b57cec5SDimitry Andric case CC_X86RegCall: 729*0b57cec5SDimitry Andric case CC_OpenCLKernel: 730*0b57cec5SDimitry Andric return CCCR_OK; 731*0b57cec5SDimitry Andric default: 732*0b57cec5SDimitry Andric return CCCR_Warning; 733*0b57cec5SDimitry Andric } 734*0b57cec5SDimitry Andric } 735*0b57cec5SDimitry Andric }; 736*0b57cec5SDimitry Andric 737*0b57cec5SDimitry Andric // x86-64 Windows Visual Studio target 738*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo 739*0b57cec5SDimitry Andric : public WindowsX86_64TargetInfo { 740*0b57cec5SDimitry Andric public: 741*0b57cec5SDimitry Andric MicrosoftX86_64TargetInfo(const llvm::Triple &Triple, 742*0b57cec5SDimitry Andric const TargetOptions &Opts) 743*0b57cec5SDimitry Andric : WindowsX86_64TargetInfo(Triple, Opts) { 744*0b57cec5SDimitry Andric LongDoubleWidth = LongDoubleAlign = 64; 745*0b57cec5SDimitry Andric LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 746*0b57cec5SDimitry Andric } 747*0b57cec5SDimitry Andric 748*0b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 749*0b57cec5SDimitry Andric MacroBuilder &Builder) const override { 750*0b57cec5SDimitry Andric WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder); 751*0b57cec5SDimitry Andric Builder.defineMacro("_M_X64", "100"); 752*0b57cec5SDimitry Andric Builder.defineMacro("_M_AMD64", "100"); 753*0b57cec5SDimitry Andric } 754*0b57cec5SDimitry Andric 755*0b57cec5SDimitry Andric TargetInfo::CallingConvKind 756*0b57cec5SDimitry Andric getCallingConvKind(bool ClangABICompat4) const override { 757*0b57cec5SDimitry Andric return CCK_MicrosoftWin64; 758*0b57cec5SDimitry Andric } 759*0b57cec5SDimitry Andric }; 760*0b57cec5SDimitry Andric 761*0b57cec5SDimitry Andric // x86-64 MinGW target 762*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo 763*0b57cec5SDimitry Andric : public WindowsX86_64TargetInfo { 764*0b57cec5SDimitry Andric public: 765*0b57cec5SDimitry Andric MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 766*0b57cec5SDimitry Andric : WindowsX86_64TargetInfo(Triple, Opts) { 767*0b57cec5SDimitry Andric // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks 768*0b57cec5SDimitry Andric // with x86 FP ops. Weird. 769*0b57cec5SDimitry Andric LongDoubleWidth = LongDoubleAlign = 128; 770*0b57cec5SDimitry Andric LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); 771*0b57cec5SDimitry Andric HasFloat128 = true; 772*0b57cec5SDimitry Andric } 773*0b57cec5SDimitry Andric }; 774*0b57cec5SDimitry Andric 775*0b57cec5SDimitry Andric // x86-64 Cygwin target 776*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo : public X86_64TargetInfo { 777*0b57cec5SDimitry Andric public: 778*0b57cec5SDimitry Andric CygwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 779*0b57cec5SDimitry Andric : X86_64TargetInfo(Triple, Opts) { 780*0b57cec5SDimitry Andric this->WCharType = TargetInfo::UnsignedShort; 781*0b57cec5SDimitry Andric TLSSupported = false; 782*0b57cec5SDimitry Andric } 783*0b57cec5SDimitry Andric 784*0b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 785*0b57cec5SDimitry Andric MacroBuilder &Builder) const override { 786*0b57cec5SDimitry Andric X86_64TargetInfo::getTargetDefines(Opts, Builder); 787*0b57cec5SDimitry Andric Builder.defineMacro("__x86_64__"); 788*0b57cec5SDimitry Andric Builder.defineMacro("__CYGWIN__"); 789*0b57cec5SDimitry Andric Builder.defineMacro("__CYGWIN64__"); 790*0b57cec5SDimitry Andric addCygMingDefines(Opts, Builder); 791*0b57cec5SDimitry Andric DefineStd(Builder, "unix", Opts); 792*0b57cec5SDimitry Andric if (Opts.CPlusPlus) 793*0b57cec5SDimitry Andric Builder.defineMacro("_GNU_SOURCE"); 794*0b57cec5SDimitry Andric } 795*0b57cec5SDimitry Andric }; 796*0b57cec5SDimitry Andric 797*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo 798*0b57cec5SDimitry Andric : public DarwinTargetInfo<X86_64TargetInfo> { 799*0b57cec5SDimitry Andric public: 800*0b57cec5SDimitry Andric DarwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 801*0b57cec5SDimitry Andric : DarwinTargetInfo<X86_64TargetInfo>(Triple, Opts) { 802*0b57cec5SDimitry Andric Int64Type = SignedLongLong; 803*0b57cec5SDimitry Andric // The 64-bit iOS simulator uses the builtin bool type for Objective-C. 804*0b57cec5SDimitry Andric llvm::Triple T = llvm::Triple(Triple); 805*0b57cec5SDimitry Andric if (T.isiOS()) 806*0b57cec5SDimitry Andric UseSignedCharForObjCBool = false; 807*0b57cec5SDimitry Andric resetDataLayout("e-m:o-i64:64-f80:128-n8:16:32:64-S128"); 808*0b57cec5SDimitry Andric } 809*0b57cec5SDimitry Andric 810*0b57cec5SDimitry Andric bool handleTargetFeatures(std::vector<std::string> &Features, 811*0b57cec5SDimitry Andric DiagnosticsEngine &Diags) override { 812*0b57cec5SDimitry Andric if (!DarwinTargetInfo<X86_64TargetInfo>::handleTargetFeatures(Features, 813*0b57cec5SDimitry Andric Diags)) 814*0b57cec5SDimitry Andric return false; 815*0b57cec5SDimitry Andric // We now know the features we have: we can decide how to align vectors. 816*0b57cec5SDimitry Andric MaxVectorAlign = 817*0b57cec5SDimitry Andric hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128; 818*0b57cec5SDimitry Andric return true; 819*0b57cec5SDimitry Andric } 820*0b57cec5SDimitry Andric }; 821*0b57cec5SDimitry Andric 822*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo 823*0b57cec5SDimitry Andric : public OpenBSDTargetInfo<X86_64TargetInfo> { 824*0b57cec5SDimitry Andric public: 825*0b57cec5SDimitry Andric OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 826*0b57cec5SDimitry Andric : OpenBSDTargetInfo<X86_64TargetInfo>(Triple, Opts) { 827*0b57cec5SDimitry Andric IntMaxType = SignedLongLong; 828*0b57cec5SDimitry Andric Int64Type = SignedLongLong; 829*0b57cec5SDimitry Andric } 830*0b57cec5SDimitry Andric }; 831*0b57cec5SDimitry Andric 832*0b57cec5SDimitry Andric // x86_32 Android target 833*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY AndroidX86_32TargetInfo 834*0b57cec5SDimitry Andric : public LinuxTargetInfo<X86_32TargetInfo> { 835*0b57cec5SDimitry Andric public: 836*0b57cec5SDimitry Andric AndroidX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 837*0b57cec5SDimitry Andric : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) { 838*0b57cec5SDimitry Andric SuitableAlign = 32; 839*0b57cec5SDimitry Andric LongDoubleWidth = 64; 840*0b57cec5SDimitry Andric LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 841*0b57cec5SDimitry Andric } 842*0b57cec5SDimitry Andric }; 843*0b57cec5SDimitry Andric 844*0b57cec5SDimitry Andric // x86_64 Android target 845*0b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY AndroidX86_64TargetInfo 846*0b57cec5SDimitry Andric : public LinuxTargetInfo<X86_64TargetInfo> { 847*0b57cec5SDimitry Andric public: 848*0b57cec5SDimitry Andric AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 849*0b57cec5SDimitry Andric : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) { 850*0b57cec5SDimitry Andric LongDoubleFormat = &llvm::APFloat::IEEEquad(); 851*0b57cec5SDimitry Andric } 852*0b57cec5SDimitry Andric }; 853*0b57cec5SDimitry Andric } // namespace targets 854*0b57cec5SDimitry Andric } // namespace clang 855*0b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H 856