17330f729Sjoerg //===--- X86.h - Declare X86 target feature support -------------*- C++ -*-===// 27330f729Sjoerg // 37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information. 57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 67330f729Sjoerg // 77330f729Sjoerg //===----------------------------------------------------------------------===// 87330f729Sjoerg // 97330f729Sjoerg // This file declares X86 TargetInfo objects. 107330f729Sjoerg // 117330f729Sjoerg //===----------------------------------------------------------------------===// 127330f729Sjoerg 137330f729Sjoerg #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_X86_H 147330f729Sjoerg #define LLVM_CLANG_LIB_BASIC_TARGETS_X86_H 157330f729Sjoerg 167330f729Sjoerg #include "OSTargets.h" 177330f729Sjoerg #include "clang/Basic/TargetInfo.h" 187330f729Sjoerg #include "clang/Basic/TargetOptions.h" 197330f729Sjoerg #include "llvm/ADT/Triple.h" 207330f729Sjoerg #include "llvm/Support/Compiler.h" 21*e038c9c4Sjoerg #include "llvm/Support/X86TargetParser.h" 227330f729Sjoerg 237330f729Sjoerg namespace clang { 247330f729Sjoerg namespace targets { 257330f729Sjoerg 26*e038c9c4Sjoerg static const unsigned X86AddrSpaceMap[] = { 27*e038c9c4Sjoerg 0, // Default 28*e038c9c4Sjoerg 0, // opencl_global 29*e038c9c4Sjoerg 0, // opencl_local 30*e038c9c4Sjoerg 0, // opencl_constant 31*e038c9c4Sjoerg 0, // opencl_private 32*e038c9c4Sjoerg 0, // opencl_generic 33*e038c9c4Sjoerg 0, // opencl_global_device 34*e038c9c4Sjoerg 0, // opencl_global_host 35*e038c9c4Sjoerg 0, // cuda_device 36*e038c9c4Sjoerg 0, // cuda_constant 37*e038c9c4Sjoerg 0, // cuda_shared 38*e038c9c4Sjoerg 0, // sycl_global 39*e038c9c4Sjoerg 0, // sycl_global_device 40*e038c9c4Sjoerg 0, // sycl_global_host 41*e038c9c4Sjoerg 0, // sycl_local 42*e038c9c4Sjoerg 0, // sycl_private 43*e038c9c4Sjoerg 270, // ptr32_sptr 44*e038c9c4Sjoerg 271, // ptr32_uptr 45*e038c9c4Sjoerg 272 // ptr64 46*e038c9c4Sjoerg }; 47*e038c9c4Sjoerg 487330f729Sjoerg // X86 target abstract base class; x86-32 and x86-64 are very close, so 497330f729Sjoerg // most of the implementation can be shared. 507330f729Sjoerg class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { 517330f729Sjoerg 527330f729Sjoerg enum X86SSEEnum { 537330f729Sjoerg NoSSE, 547330f729Sjoerg SSE1, 557330f729Sjoerg SSE2, 567330f729Sjoerg SSE3, 577330f729Sjoerg SSSE3, 587330f729Sjoerg SSE41, 597330f729Sjoerg SSE42, 607330f729Sjoerg AVX, 617330f729Sjoerg AVX2, 627330f729Sjoerg AVX512F 637330f729Sjoerg } SSELevel = NoSSE; 647330f729Sjoerg enum MMX3DNowEnum { 657330f729Sjoerg NoMMX3DNow, 667330f729Sjoerg MMX, 677330f729Sjoerg AMD3DNow, 687330f729Sjoerg AMD3DNowAthlon 697330f729Sjoerg } MMX3DNowLevel = NoMMX3DNow; 707330f729Sjoerg enum XOPEnum { NoXOP, SSE4A, FMA4, XOP } XOPLevel = NoXOP; 71*e038c9c4Sjoerg enum AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 }; 727330f729Sjoerg 737330f729Sjoerg bool HasAES = false; 747330f729Sjoerg bool HasVAES = false; 757330f729Sjoerg bool HasPCLMUL = false; 767330f729Sjoerg bool HasVPCLMULQDQ = false; 777330f729Sjoerg bool HasGFNI = false; 787330f729Sjoerg bool HasLZCNT = false; 797330f729Sjoerg bool HasRDRND = false; 807330f729Sjoerg bool HasFSGSBASE = false; 817330f729Sjoerg bool HasBMI = false; 827330f729Sjoerg bool HasBMI2 = false; 837330f729Sjoerg bool HasPOPCNT = false; 847330f729Sjoerg bool HasRTM = false; 857330f729Sjoerg bool HasPRFCHW = false; 867330f729Sjoerg bool HasRDSEED = false; 877330f729Sjoerg bool HasADX = false; 887330f729Sjoerg bool HasTBM = false; 897330f729Sjoerg bool HasLWP = false; 907330f729Sjoerg bool HasFMA = false; 917330f729Sjoerg bool HasF16C = false; 927330f729Sjoerg bool HasAVX512CD = false; 937330f729Sjoerg bool HasAVX512VPOPCNTDQ = false; 947330f729Sjoerg bool HasAVX512VNNI = false; 957330f729Sjoerg bool HasAVX512BF16 = false; 967330f729Sjoerg bool HasAVX512ER = false; 977330f729Sjoerg bool HasAVX512PF = false; 987330f729Sjoerg bool HasAVX512DQ = false; 997330f729Sjoerg bool HasAVX512BITALG = false; 1007330f729Sjoerg bool HasAVX512BW = false; 1017330f729Sjoerg bool HasAVX512VL = false; 1027330f729Sjoerg bool HasAVX512VBMI = false; 1037330f729Sjoerg bool HasAVX512VBMI2 = false; 1047330f729Sjoerg bool HasAVX512IFMA = false; 1057330f729Sjoerg bool HasAVX512VP2INTERSECT = false; 1067330f729Sjoerg bool HasSHA = false; 1077330f729Sjoerg bool HasSHSTK = false; 1087330f729Sjoerg bool HasSGX = false; 1097330f729Sjoerg bool HasCX8 = false; 1107330f729Sjoerg bool HasCX16 = false; 1117330f729Sjoerg bool HasFXSR = false; 1127330f729Sjoerg bool HasXSAVE = false; 1137330f729Sjoerg bool HasXSAVEOPT = false; 1147330f729Sjoerg bool HasXSAVEC = false; 1157330f729Sjoerg bool HasXSAVES = false; 1167330f729Sjoerg bool HasMWAITX = false; 1177330f729Sjoerg bool HasCLZERO = false; 1187330f729Sjoerg bool HasCLDEMOTE = false; 1197330f729Sjoerg bool HasPCONFIG = false; 1207330f729Sjoerg bool HasPKU = false; 1217330f729Sjoerg bool HasCLFLUSHOPT = false; 1227330f729Sjoerg bool HasCLWB = false; 1237330f729Sjoerg bool HasMOVBE = false; 1247330f729Sjoerg bool HasPREFETCHWT1 = false; 1257330f729Sjoerg bool HasRDPID = false; 1267330f729Sjoerg bool HasRetpolineExternalThunk = false; 1277330f729Sjoerg bool HasLAHFSAHF = false; 1287330f729Sjoerg bool HasWBNOINVD = false; 1297330f729Sjoerg bool HasWAITPKG = false; 1307330f729Sjoerg bool HasMOVDIRI = false; 1317330f729Sjoerg bool HasMOVDIR64B = false; 1327330f729Sjoerg bool HasPTWRITE = false; 1337330f729Sjoerg bool HasINVPCID = false; 1347330f729Sjoerg bool HasENQCMD = false; 135*e038c9c4Sjoerg bool HasKL = false; // For key locker 136*e038c9c4Sjoerg bool HasWIDEKL = false; // For wide key locker 137*e038c9c4Sjoerg bool HasHRESET = false; 138*e038c9c4Sjoerg bool HasAVXVNNI = false; 139*e038c9c4Sjoerg bool HasAMXTILE = false; 140*e038c9c4Sjoerg bool HasAMXINT8 = false; 141*e038c9c4Sjoerg bool HasAMXBF16 = false; 142*e038c9c4Sjoerg bool HasSERIALIZE = false; 143*e038c9c4Sjoerg bool HasTSXLDTRK = false; 144*e038c9c4Sjoerg bool HasUINTR = false; 1457330f729Sjoerg 1467330f729Sjoerg protected: 147*e038c9c4Sjoerg llvm::X86::CPUKind CPU = llvm::X86::CK_None; 1487330f729Sjoerg 1497330f729Sjoerg enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default; 1507330f729Sjoerg 1517330f729Sjoerg public: X86TargetInfo(const llvm::Triple & Triple,const TargetOptions &)1527330f729Sjoerg X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &) 1537330f729Sjoerg : TargetInfo(Triple) { 1547330f729Sjoerg LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); 155*e038c9c4Sjoerg AddrSpaceMap = &X86AddrSpaceMap; 156*e038c9c4Sjoerg HasStrictFP = true; 157*e038c9c4Sjoerg 158*e038c9c4Sjoerg bool IsWinCOFF = 159*e038c9c4Sjoerg getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); 160*e038c9c4Sjoerg if (IsWinCOFF) 161*e038c9c4Sjoerg MaxVectorAlign = MaxTLSAlign = 8192u * getCharWidth(); 1627330f729Sjoerg } 1637330f729Sjoerg getLongDoubleMangling()1647330f729Sjoerg const char *getLongDoubleMangling() const override { 1657330f729Sjoerg return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e"; 1667330f729Sjoerg } 1677330f729Sjoerg getFloatEvalMethod()1687330f729Sjoerg unsigned getFloatEvalMethod() const override { 1697330f729Sjoerg // X87 evaluates with 80 bits "long double" precision. 1707330f729Sjoerg return SSELevel == NoSSE ? 2 : 0; 1717330f729Sjoerg } 1727330f729Sjoerg 1737330f729Sjoerg ArrayRef<const char *> getGCCRegNames() const override; 1747330f729Sjoerg getGCCRegAliases()1757330f729Sjoerg ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 1767330f729Sjoerg return None; 1777330f729Sjoerg } 1787330f729Sjoerg 1797330f729Sjoerg ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; 1807330f729Sjoerg isSPRegName(StringRef RegName)181*e038c9c4Sjoerg bool isSPRegName(StringRef RegName) const override { 182*e038c9c4Sjoerg return RegName.equals("esp") || RegName.equals("rsp"); 183*e038c9c4Sjoerg } 184*e038c9c4Sjoerg 1857330f729Sjoerg bool validateCpuSupports(StringRef Name) const override; 1867330f729Sjoerg 1877330f729Sjoerg bool validateCpuIs(StringRef Name) const override; 1887330f729Sjoerg 1897330f729Sjoerg bool validateCPUSpecificCPUDispatch(StringRef Name) const override; 1907330f729Sjoerg 1917330f729Sjoerg char CPUSpecificManglingCharacter(StringRef Name) const override; 1927330f729Sjoerg 1937330f729Sjoerg void getCPUSpecificCPUDispatchFeatures( 1947330f729Sjoerg StringRef Name, 1957330f729Sjoerg llvm::SmallVectorImpl<StringRef> &Features) const override; 1967330f729Sjoerg 197*e038c9c4Sjoerg Optional<unsigned> getCPUCacheLineSize() const override; 198*e038c9c4Sjoerg 1997330f729Sjoerg bool validateAsmConstraint(const char *&Name, 2007330f729Sjoerg TargetInfo::ConstraintInfo &info) const override; 2017330f729Sjoerg validateGlobalRegisterVariable(StringRef RegName,unsigned RegSize,bool & HasSizeMismatch)2027330f729Sjoerg bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize, 2037330f729Sjoerg bool &HasSizeMismatch) const override { 2047330f729Sjoerg // esp and ebp are the only 32-bit registers the x86 backend can currently 2057330f729Sjoerg // handle. 2067330f729Sjoerg if (RegName.equals("esp") || RegName.equals("ebp")) { 2077330f729Sjoerg // Check that the register size is 32-bit. 2087330f729Sjoerg HasSizeMismatch = RegSize != 32; 2097330f729Sjoerg return true; 2107330f729Sjoerg } 2117330f729Sjoerg 2127330f729Sjoerg return false; 2137330f729Sjoerg } 2147330f729Sjoerg 215*e038c9c4Sjoerg bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap, 216*e038c9c4Sjoerg StringRef Constraint, unsigned Size) const override; 2177330f729Sjoerg 218*e038c9c4Sjoerg bool validateInputSize(const llvm::StringMap<bool> &FeatureMap, 219*e038c9c4Sjoerg StringRef Constraint, unsigned Size) const override; 2207330f729Sjoerg 2217330f729Sjoerg virtual bool checkCFProtectionReturnSupported(DiagnosticsEngine & Diags)2227330f729Sjoerg checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override { 2237330f729Sjoerg return true; 2247330f729Sjoerg }; 2257330f729Sjoerg 2267330f729Sjoerg virtual bool checkCFProtectionBranchSupported(DiagnosticsEngine & Diags)2277330f729Sjoerg checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override { 2287330f729Sjoerg return true; 2297330f729Sjoerg }; 2307330f729Sjoerg 231*e038c9c4Sjoerg virtual bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap, 232*e038c9c4Sjoerg StringRef Constraint, unsigned Size) const; 2337330f729Sjoerg 2347330f729Sjoerg std::string convertConstraint(const char *&Constraint) const override; getClobbers()2357330f729Sjoerg const char *getClobbers() const override { 2367330f729Sjoerg return "~{dirflag},~{fpsr},~{flags}"; 2377330f729Sjoerg } 2387330f729Sjoerg getConstraintRegister(StringRef Constraint,StringRef Expression)2397330f729Sjoerg StringRef getConstraintRegister(StringRef Constraint, 2407330f729Sjoerg StringRef Expression) const override { 2417330f729Sjoerg StringRef::iterator I, E; 2427330f729Sjoerg for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) { 2437330f729Sjoerg if (isalpha(*I) || *I == '@') 2447330f729Sjoerg break; 2457330f729Sjoerg } 2467330f729Sjoerg if (I == E) 2477330f729Sjoerg return ""; 2487330f729Sjoerg switch (*I) { 2497330f729Sjoerg // For the register constraints, return the matching register name 2507330f729Sjoerg case 'a': 2517330f729Sjoerg return "ax"; 2527330f729Sjoerg case 'b': 2537330f729Sjoerg return "bx"; 2547330f729Sjoerg case 'c': 2557330f729Sjoerg return "cx"; 2567330f729Sjoerg case 'd': 2577330f729Sjoerg return "dx"; 2587330f729Sjoerg case 'S': 2597330f729Sjoerg return "si"; 2607330f729Sjoerg case 'D': 2617330f729Sjoerg return "di"; 2627330f729Sjoerg // In case the constraint is 'r' we need to return Expression 2637330f729Sjoerg case 'r': 2647330f729Sjoerg return Expression; 2657330f729Sjoerg // Double letters Y<x> constraints 2667330f729Sjoerg case 'Y': 2677330f729Sjoerg if ((++I != E) && ((*I == '0') || (*I == 'z'))) 2687330f729Sjoerg return "xmm0"; 2697330f729Sjoerg break; 2707330f729Sjoerg default: 2717330f729Sjoerg break; 2727330f729Sjoerg } 2737330f729Sjoerg return ""; 2747330f729Sjoerg } 2757330f729Sjoerg useFP16ConversionIntrinsics()2767330f729Sjoerg bool useFP16ConversionIntrinsics() const override { 2777330f729Sjoerg return false; 2787330f729Sjoerg } 2797330f729Sjoerg 2807330f729Sjoerg void getTargetDefines(const LangOptions &Opts, 2817330f729Sjoerg MacroBuilder &Builder) const override; 2827330f729Sjoerg 2837330f729Sjoerg void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, 284*e038c9c4Sjoerg bool Enabled) const final; 2857330f729Sjoerg 2867330f729Sjoerg bool 2877330f729Sjoerg initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 2887330f729Sjoerg StringRef CPU, 2897330f729Sjoerg const std::vector<std::string> &FeaturesVec) const override; 2907330f729Sjoerg 2917330f729Sjoerg bool isValidFeatureName(StringRef Name) const override; 2927330f729Sjoerg 293*e038c9c4Sjoerg bool hasFeature(StringRef Feature) const final; 2947330f729Sjoerg 2957330f729Sjoerg bool handleTargetFeatures(std::vector<std::string> &Features, 2967330f729Sjoerg DiagnosticsEngine &Diags) override; 2977330f729Sjoerg getABI()2987330f729Sjoerg StringRef getABI() const override { 2997330f729Sjoerg if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F) 3007330f729Sjoerg return "avx512"; 3017330f729Sjoerg if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX) 3027330f729Sjoerg return "avx"; 3037330f729Sjoerg if (getTriple().getArch() == llvm::Triple::x86 && 3047330f729Sjoerg MMX3DNowLevel == NoMMX3DNow) 3057330f729Sjoerg return "no-mmx"; 3067330f729Sjoerg return ""; 3077330f729Sjoerg } 3087330f729Sjoerg supportsTargetAttributeTune()309*e038c9c4Sjoerg bool supportsTargetAttributeTune() const override { 310*e038c9c4Sjoerg return true; 311*e038c9c4Sjoerg } 312*e038c9c4Sjoerg isValidCPUName(StringRef Name)3137330f729Sjoerg bool isValidCPUName(StringRef Name) const override { 314*e038c9c4Sjoerg bool Only64Bit = getTriple().getArch() != llvm::Triple::x86; 315*e038c9c4Sjoerg return llvm::X86::parseArchX86(Name, Only64Bit) != llvm::X86::CK_None; 316*e038c9c4Sjoerg } 317*e038c9c4Sjoerg isValidTuneCPUName(StringRef Name)318*e038c9c4Sjoerg bool isValidTuneCPUName(StringRef Name) const override { 319*e038c9c4Sjoerg if (Name == "generic") 320*e038c9c4Sjoerg return true; 321*e038c9c4Sjoerg 322*e038c9c4Sjoerg // Allow 32-bit only CPUs regardless of 64-bit mode unlike isValidCPUName. 323*e038c9c4Sjoerg // NOTE: gcc rejects 32-bit mtune CPUs in 64-bit mode. But being lenient 324*e038c9c4Sjoerg // since mtune was ignored by clang for so long. 325*e038c9c4Sjoerg return llvm::X86::parseTuneCPU(Name) != llvm::X86::CK_None; 3267330f729Sjoerg } 3277330f729Sjoerg 3287330f729Sjoerg void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 329*e038c9c4Sjoerg void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override; 3307330f729Sjoerg setCPU(const std::string & Name)3317330f729Sjoerg bool setCPU(const std::string &Name) override { 332*e038c9c4Sjoerg bool Only64Bit = getTriple().getArch() != llvm::Triple::x86; 333*e038c9c4Sjoerg CPU = llvm::X86::parseArchX86(Name, Only64Bit); 334*e038c9c4Sjoerg return CPU != llvm::X86::CK_None; 3357330f729Sjoerg } 3367330f729Sjoerg 3377330f729Sjoerg unsigned multiVersionSortPriority(StringRef Name) const override; 3387330f729Sjoerg 3397330f729Sjoerg bool setFPMath(StringRef Name) override; 3407330f729Sjoerg supportsExtendIntArgs()341*e038c9c4Sjoerg bool supportsExtendIntArgs() const override { 342*e038c9c4Sjoerg return getTriple().getArch() != llvm::Triple::x86; 343*e038c9c4Sjoerg } 344*e038c9c4Sjoerg checkCallingConvention(CallingConv CC)3457330f729Sjoerg CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 3467330f729Sjoerg // Most of the non-ARM calling conventions are i386 conventions. 3477330f729Sjoerg switch (CC) { 3487330f729Sjoerg case CC_X86ThisCall: 3497330f729Sjoerg case CC_X86FastCall: 3507330f729Sjoerg case CC_X86StdCall: 3517330f729Sjoerg case CC_X86VectorCall: 3527330f729Sjoerg case CC_X86RegCall: 3537330f729Sjoerg case CC_C: 3547330f729Sjoerg case CC_PreserveMost: 3557330f729Sjoerg case CC_Swift: 3567330f729Sjoerg case CC_X86Pascal: 3577330f729Sjoerg case CC_IntelOclBicc: 3587330f729Sjoerg case CC_OpenCLKernel: 3597330f729Sjoerg return CCCR_OK; 3607330f729Sjoerg default: 3617330f729Sjoerg return CCCR_Warning; 3627330f729Sjoerg } 3637330f729Sjoerg } 3647330f729Sjoerg getDefaultCallingConv()3657330f729Sjoerg CallingConv getDefaultCallingConv() const override { 3667330f729Sjoerg return CC_C; 3677330f729Sjoerg } 3687330f729Sjoerg hasSjLjLowering()3697330f729Sjoerg bool hasSjLjLowering() const override { return true; } 3707330f729Sjoerg setSupportedOpenCLOpts()371*e038c9c4Sjoerg void setSupportedOpenCLOpts() override { supportAllOpenCLOpts(); } 372*e038c9c4Sjoerg getPointerWidthV(unsigned AddrSpace)373*e038c9c4Sjoerg uint64_t getPointerWidthV(unsigned AddrSpace) const override { 374*e038c9c4Sjoerg if (AddrSpace == ptr32_sptr || AddrSpace == ptr32_uptr) 375*e038c9c4Sjoerg return 32; 376*e038c9c4Sjoerg if (AddrSpace == ptr64) 377*e038c9c4Sjoerg return 64; 378*e038c9c4Sjoerg return PointerWidth; 379*e038c9c4Sjoerg } 380*e038c9c4Sjoerg getPointerAlignV(unsigned AddrSpace)381*e038c9c4Sjoerg uint64_t getPointerAlignV(unsigned AddrSpace) const override { 382*e038c9c4Sjoerg return getPointerWidthV(AddrSpace); 3837330f729Sjoerg } 3847330f729Sjoerg }; 3857330f729Sjoerg 3867330f729Sjoerg // X86-32 generic target 3877330f729Sjoerg class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo { 3887330f729Sjoerg public: X86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)3897330f729Sjoerg X86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 3907330f729Sjoerg : X86TargetInfo(Triple, Opts) { 3917330f729Sjoerg DoubleAlign = LongLongAlign = 32; 3927330f729Sjoerg LongDoubleWidth = 96; 3937330f729Sjoerg LongDoubleAlign = 32; 3947330f729Sjoerg SuitableAlign = 128; 395*e038c9c4Sjoerg resetDataLayout( 396*e038c9c4Sjoerg Triple.isOSBinFormatMachO() 397*e038c9c4Sjoerg ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-" 398*e038c9c4Sjoerg "f80:32-n8:16:32-S128" 399*e038c9c4Sjoerg : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-" 400*e038c9c4Sjoerg "f80:32-n8:16:32-S128", 401*e038c9c4Sjoerg Triple.isOSBinFormatMachO() ? "_" : ""); 4027330f729Sjoerg SizeType = UnsignedInt; 4037330f729Sjoerg PtrDiffType = SignedInt; 4047330f729Sjoerg IntPtrType = SignedInt; 4057330f729Sjoerg RegParmMax = 3; 4067330f729Sjoerg 4077330f729Sjoerg // Use fpret for all types. 4087330f729Sjoerg RealTypeUsesObjCFPRet = 4097330f729Sjoerg ((1 << TargetInfo::Float) | (1 << TargetInfo::Double) | 4107330f729Sjoerg (1 << TargetInfo::LongDouble)); 4117330f729Sjoerg 4127330f729Sjoerg // x86-32 has atomics up to 8 bytes 4137330f729Sjoerg MaxAtomicPromoteWidth = 64; 4147330f729Sjoerg MaxAtomicInlineWidth = 32; 4157330f729Sjoerg } 4167330f729Sjoerg getBuiltinVaListKind()4177330f729Sjoerg BuiltinVaListKind getBuiltinVaListKind() const override { 4187330f729Sjoerg return TargetInfo::CharPtrBuiltinVaList; 4197330f729Sjoerg } 4207330f729Sjoerg getEHDataRegisterNumber(unsigned RegNo)4217330f729Sjoerg int getEHDataRegisterNumber(unsigned RegNo) const override { 4227330f729Sjoerg if (RegNo == 0) 4237330f729Sjoerg return 0; 4247330f729Sjoerg if (RegNo == 1) 4257330f729Sjoerg return 2; 4267330f729Sjoerg return -1; 4277330f729Sjoerg } 4287330f729Sjoerg validateOperandSize(const llvm::StringMap<bool> & FeatureMap,StringRef Constraint,unsigned Size)429*e038c9c4Sjoerg bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap, 430*e038c9c4Sjoerg StringRef Constraint, unsigned Size) const override { 4317330f729Sjoerg switch (Constraint[0]) { 4327330f729Sjoerg default: 4337330f729Sjoerg break; 4347330f729Sjoerg case 'R': 4357330f729Sjoerg case 'q': 4367330f729Sjoerg case 'Q': 4377330f729Sjoerg case 'a': 4387330f729Sjoerg case 'b': 4397330f729Sjoerg case 'c': 4407330f729Sjoerg case 'd': 4417330f729Sjoerg case 'S': 4427330f729Sjoerg case 'D': 4437330f729Sjoerg return Size <= 32; 4447330f729Sjoerg case 'A': 4457330f729Sjoerg return Size <= 64; 4467330f729Sjoerg } 4477330f729Sjoerg 448*e038c9c4Sjoerg return X86TargetInfo::validateOperandSize(FeatureMap, Constraint, Size); 4497330f729Sjoerg } 4507330f729Sjoerg setMaxAtomicWidth()4517330f729Sjoerg void setMaxAtomicWidth() override { 4527330f729Sjoerg if (hasFeature("cx8")) 4537330f729Sjoerg MaxAtomicInlineWidth = 64; 4547330f729Sjoerg } 4557330f729Sjoerg 4567330f729Sjoerg ArrayRef<Builtin::Info> getTargetBuiltins() const override; 457*e038c9c4Sjoerg hasExtIntType()458*e038c9c4Sjoerg bool hasExtIntType() const override { return true; } 4597330f729Sjoerg }; 4607330f729Sjoerg 4617330f729Sjoerg class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo 4627330f729Sjoerg : public NetBSDTargetInfo<X86_32TargetInfo> { 4637330f729Sjoerg public: NetBSDI386TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4647330f729Sjoerg NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 4657330f729Sjoerg : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {} 4667330f729Sjoerg getFloatEvalMethod()4677330f729Sjoerg unsigned getFloatEvalMethod() const override { 4687330f729Sjoerg unsigned Major, Minor, Micro; 4697330f729Sjoerg getTriple().getOSVersion(Major, Minor, Micro); 4707330f729Sjoerg // New NetBSD uses the default rounding mode. 4717330f729Sjoerg if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 26) || Major == 0) 4727330f729Sjoerg return X86_32TargetInfo::getFloatEvalMethod(); 4737330f729Sjoerg // NetBSD before 6.99.26 defaults to "double" rounding. 4747330f729Sjoerg return 1; 4757330f729Sjoerg } 4767330f729Sjoerg }; 4777330f729Sjoerg 4787330f729Sjoerg class LLVM_LIBRARY_VISIBILITY OpenBSDI386TargetInfo 4797330f729Sjoerg : public OpenBSDTargetInfo<X86_32TargetInfo> { 4807330f729Sjoerg public: OpenBSDI386TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4817330f729Sjoerg OpenBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 4827330f729Sjoerg : OpenBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) { 4837330f729Sjoerg SizeType = UnsignedLong; 4847330f729Sjoerg IntPtrType = SignedLong; 4857330f729Sjoerg PtrDiffType = SignedLong; 4867330f729Sjoerg } 4877330f729Sjoerg }; 4887330f729Sjoerg 4897330f729Sjoerg class LLVM_LIBRARY_VISIBILITY DarwinI386TargetInfo 4907330f729Sjoerg : public DarwinTargetInfo<X86_32TargetInfo> { 4917330f729Sjoerg public: DarwinI386TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)4927330f729Sjoerg DarwinI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 4937330f729Sjoerg : DarwinTargetInfo<X86_32TargetInfo>(Triple, Opts) { 4947330f729Sjoerg LongDoubleWidth = 128; 4957330f729Sjoerg LongDoubleAlign = 128; 4967330f729Sjoerg SuitableAlign = 128; 4977330f729Sjoerg MaxVectorAlign = 256; 4987330f729Sjoerg // The watchOS simulator uses the builtin bool type for Objective-C. 4997330f729Sjoerg llvm::Triple T = llvm::Triple(Triple); 5007330f729Sjoerg if (T.isWatchOS()) 5017330f729Sjoerg UseSignedCharForObjCBool = false; 5027330f729Sjoerg SizeType = UnsignedLong; 5037330f729Sjoerg IntPtrType = SignedLong; 5047330f729Sjoerg resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-" 505*e038c9c4Sjoerg "f80:128-n8:16:32-S128", "_"); 5067330f729Sjoerg HasAlignMac68kSupport = true; 5077330f729Sjoerg } 5087330f729Sjoerg handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)5097330f729Sjoerg bool handleTargetFeatures(std::vector<std::string> &Features, 5107330f729Sjoerg DiagnosticsEngine &Diags) override { 5117330f729Sjoerg if (!DarwinTargetInfo<X86_32TargetInfo>::handleTargetFeatures(Features, 5127330f729Sjoerg Diags)) 5137330f729Sjoerg return false; 5147330f729Sjoerg // We now know the features we have: we can decide how to align vectors. 5157330f729Sjoerg MaxVectorAlign = 5167330f729Sjoerg hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128; 5177330f729Sjoerg return true; 5187330f729Sjoerg } 5197330f729Sjoerg }; 5207330f729Sjoerg 5217330f729Sjoerg // x86-32 Windows target 5227330f729Sjoerg class LLVM_LIBRARY_VISIBILITY WindowsX86_32TargetInfo 5237330f729Sjoerg : public WindowsTargetInfo<X86_32TargetInfo> { 5247330f729Sjoerg public: WindowsX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5257330f729Sjoerg WindowsX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 5267330f729Sjoerg : WindowsTargetInfo<X86_32TargetInfo>(Triple, Opts) { 5277330f729Sjoerg DoubleAlign = LongLongAlign = 64; 5287330f729Sjoerg bool IsWinCOFF = 5297330f729Sjoerg getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); 5307330f729Sjoerg resetDataLayout(IsWinCOFF ? "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:" 5317330f729Sjoerg "64-i64:64-f80:32-n8:16:32-a:0:32-S32" 5327330f729Sjoerg : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:" 533*e038c9c4Sjoerg "64-i64:64-f80:32-n8:16:32-a:0:32-S32", 534*e038c9c4Sjoerg IsWinCOFF ? "_" : ""); 5357330f729Sjoerg } 5367330f729Sjoerg }; 5377330f729Sjoerg 5387330f729Sjoerg // x86-32 Windows Visual Studio target 5397330f729Sjoerg class LLVM_LIBRARY_VISIBILITY MicrosoftX86_32TargetInfo 5407330f729Sjoerg : public WindowsX86_32TargetInfo { 5417330f729Sjoerg public: MicrosoftX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5427330f729Sjoerg MicrosoftX86_32TargetInfo(const llvm::Triple &Triple, 5437330f729Sjoerg const TargetOptions &Opts) 5447330f729Sjoerg : WindowsX86_32TargetInfo(Triple, Opts) { 5457330f729Sjoerg LongDoubleWidth = LongDoubleAlign = 64; 5467330f729Sjoerg LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 5477330f729Sjoerg } 5487330f729Sjoerg getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)5497330f729Sjoerg void getTargetDefines(const LangOptions &Opts, 5507330f729Sjoerg MacroBuilder &Builder) const override { 5517330f729Sjoerg WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder); 5527330f729Sjoerg // The value of the following reflects processor type. 5537330f729Sjoerg // 300=386, 400=486, 500=Pentium, 600=Blend (default) 5547330f729Sjoerg // We lost the original triple, so we use the default. 5557330f729Sjoerg Builder.defineMacro("_M_IX86", "600"); 5567330f729Sjoerg } 5577330f729Sjoerg }; 5587330f729Sjoerg 5597330f729Sjoerg // x86-32 MinGW target 5607330f729Sjoerg class LLVM_LIBRARY_VISIBILITY MinGWX86_32TargetInfo 5617330f729Sjoerg : public WindowsX86_32TargetInfo { 5627330f729Sjoerg public: MinGWX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5637330f729Sjoerg MinGWX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 5647330f729Sjoerg : WindowsX86_32TargetInfo(Triple, Opts) { 5657330f729Sjoerg HasFloat128 = true; 5667330f729Sjoerg } 5677330f729Sjoerg getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)5687330f729Sjoerg void getTargetDefines(const LangOptions &Opts, 5697330f729Sjoerg MacroBuilder &Builder) const override { 5707330f729Sjoerg WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder); 5717330f729Sjoerg Builder.defineMacro("_X86_"); 5727330f729Sjoerg } 5737330f729Sjoerg }; 5747330f729Sjoerg 5757330f729Sjoerg // x86-32 Cygwin target 5767330f729Sjoerg class LLVM_LIBRARY_VISIBILITY CygwinX86_32TargetInfo : public X86_32TargetInfo { 5777330f729Sjoerg public: CygwinX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)5787330f729Sjoerg CygwinX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 5797330f729Sjoerg : X86_32TargetInfo(Triple, Opts) { 5807330f729Sjoerg this->WCharType = TargetInfo::UnsignedShort; 5817330f729Sjoerg DoubleAlign = LongLongAlign = 64; 5827330f729Sjoerg resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:" 583*e038c9c4Sjoerg "32-n8:16:32-a:0:32-S32", 584*e038c9c4Sjoerg "_"); 5857330f729Sjoerg } 5867330f729Sjoerg getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)5877330f729Sjoerg void getTargetDefines(const LangOptions &Opts, 5887330f729Sjoerg MacroBuilder &Builder) const override { 5897330f729Sjoerg X86_32TargetInfo::getTargetDefines(Opts, Builder); 5907330f729Sjoerg Builder.defineMacro("_X86_"); 5917330f729Sjoerg Builder.defineMacro("__CYGWIN__"); 5927330f729Sjoerg Builder.defineMacro("__CYGWIN32__"); 5937330f729Sjoerg addCygMingDefines(Opts, Builder); 5947330f729Sjoerg DefineStd(Builder, "unix", Opts); 5957330f729Sjoerg if (Opts.CPlusPlus) 5967330f729Sjoerg Builder.defineMacro("_GNU_SOURCE"); 5977330f729Sjoerg } 5987330f729Sjoerg }; 5997330f729Sjoerg 6007330f729Sjoerg // x86-32 Haiku target 6017330f729Sjoerg class LLVM_LIBRARY_VISIBILITY HaikuX86_32TargetInfo 6027330f729Sjoerg : public HaikuTargetInfo<X86_32TargetInfo> { 6037330f729Sjoerg public: HaikuX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6047330f729Sjoerg HaikuX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 6057330f729Sjoerg : HaikuTargetInfo<X86_32TargetInfo>(Triple, Opts) {} 6067330f729Sjoerg getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)6077330f729Sjoerg void getTargetDefines(const LangOptions &Opts, 6087330f729Sjoerg MacroBuilder &Builder) const override { 6097330f729Sjoerg HaikuTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder); 6107330f729Sjoerg Builder.defineMacro("__INTEL__"); 6117330f729Sjoerg } 6127330f729Sjoerg }; 6137330f729Sjoerg 6147330f729Sjoerg // X86-32 MCU target 6157330f729Sjoerg class LLVM_LIBRARY_VISIBILITY MCUX86_32TargetInfo : public X86_32TargetInfo { 6167330f729Sjoerg public: MCUX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6177330f729Sjoerg MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 6187330f729Sjoerg : X86_32TargetInfo(Triple, Opts) { 6197330f729Sjoerg LongDoubleWidth = 64; 6207330f729Sjoerg LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 6217330f729Sjoerg resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-f64:" 6227330f729Sjoerg "32-f128:32-n8:16:32-a:0:32-S32"); 6237330f729Sjoerg WIntType = UnsignedInt; 6247330f729Sjoerg } 6257330f729Sjoerg checkCallingConvention(CallingConv CC)6267330f729Sjoerg CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 6277330f729Sjoerg // On MCU we support only C calling convention. 6287330f729Sjoerg return CC == CC_C ? CCCR_OK : CCCR_Warning; 6297330f729Sjoerg } 6307330f729Sjoerg getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)6317330f729Sjoerg void getTargetDefines(const LangOptions &Opts, 6327330f729Sjoerg MacroBuilder &Builder) const override { 6337330f729Sjoerg X86_32TargetInfo::getTargetDefines(Opts, Builder); 6347330f729Sjoerg Builder.defineMacro("__iamcu"); 6357330f729Sjoerg Builder.defineMacro("__iamcu__"); 6367330f729Sjoerg } 6377330f729Sjoerg allowsLargerPreferedTypeAlignment()6387330f729Sjoerg bool allowsLargerPreferedTypeAlignment() const override { return false; } 6397330f729Sjoerg }; 6407330f729Sjoerg 6417330f729Sjoerg // x86-32 RTEMS target 6427330f729Sjoerg class LLVM_LIBRARY_VISIBILITY RTEMSX86_32TargetInfo : public X86_32TargetInfo { 6437330f729Sjoerg public: RTEMSX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6447330f729Sjoerg RTEMSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 6457330f729Sjoerg : X86_32TargetInfo(Triple, Opts) { 6467330f729Sjoerg SizeType = UnsignedLong; 6477330f729Sjoerg IntPtrType = SignedLong; 6487330f729Sjoerg PtrDiffType = SignedLong; 6497330f729Sjoerg } 6507330f729Sjoerg getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)6517330f729Sjoerg void getTargetDefines(const LangOptions &Opts, 6527330f729Sjoerg MacroBuilder &Builder) const override { 6537330f729Sjoerg X86_32TargetInfo::getTargetDefines(Opts, Builder); 6547330f729Sjoerg Builder.defineMacro("__INTEL__"); 6557330f729Sjoerg Builder.defineMacro("__rtems__"); 6567330f729Sjoerg } 6577330f729Sjoerg }; 6587330f729Sjoerg 6597330f729Sjoerg // x86-64 generic target 6607330f729Sjoerg class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo { 6617330f729Sjoerg public: X86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)6627330f729Sjoerg X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 6637330f729Sjoerg : X86TargetInfo(Triple, Opts) { 6647330f729Sjoerg const bool IsX32 = getTriple().getEnvironment() == llvm::Triple::GNUX32; 6657330f729Sjoerg bool IsWinCOFF = 6667330f729Sjoerg getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); 6677330f729Sjoerg LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64; 6687330f729Sjoerg LongDoubleWidth = 128; 6697330f729Sjoerg LongDoubleAlign = 128; 6707330f729Sjoerg LargeArrayMinWidth = 128; 6717330f729Sjoerg LargeArrayAlign = 128; 6727330f729Sjoerg SuitableAlign = 128; 6737330f729Sjoerg SizeType = IsX32 ? UnsignedInt : UnsignedLong; 6747330f729Sjoerg PtrDiffType = IsX32 ? SignedInt : SignedLong; 6757330f729Sjoerg IntPtrType = IsX32 ? SignedInt : SignedLong; 6767330f729Sjoerg IntMaxType = IsX32 ? SignedLongLong : SignedLong; 6777330f729Sjoerg Int64Type = IsX32 ? SignedLongLong : SignedLong; 6787330f729Sjoerg RegParmMax = 6; 6797330f729Sjoerg 6807330f729Sjoerg // Pointers are 32-bit in x32. 6817330f729Sjoerg resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-" 6827330f729Sjoerg "i64:64-f80:128-n8:16:32:64-S128" 6837330f729Sjoerg : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:" 6847330f729Sjoerg "64-i64:64-f80:128-n8:16:32:64-S128" 6857330f729Sjoerg : "e-m:e-p270:32:32-p271:32:32-p272:64:" 6867330f729Sjoerg "64-i64:64-f80:128-n8:16:32:64-S128"); 6877330f729Sjoerg 6887330f729Sjoerg // Use fpret only for long double. 6897330f729Sjoerg RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble); 6907330f729Sjoerg 6917330f729Sjoerg // Use fp2ret for _Complex long double. 6927330f729Sjoerg ComplexLongDoubleUsesFP2Ret = true; 6937330f729Sjoerg 6947330f729Sjoerg // Make __builtin_ms_va_list available. 6957330f729Sjoerg HasBuiltinMSVaList = true; 6967330f729Sjoerg 6977330f729Sjoerg // x86-64 has atomics up to 16 bytes. 6987330f729Sjoerg MaxAtomicPromoteWidth = 128; 6997330f729Sjoerg MaxAtomicInlineWidth = 64; 7007330f729Sjoerg } 7017330f729Sjoerg getBuiltinVaListKind()7027330f729Sjoerg BuiltinVaListKind getBuiltinVaListKind() const override { 7037330f729Sjoerg return TargetInfo::X86_64ABIBuiltinVaList; 7047330f729Sjoerg } 7057330f729Sjoerg getEHDataRegisterNumber(unsigned RegNo)7067330f729Sjoerg int getEHDataRegisterNumber(unsigned RegNo) const override { 7077330f729Sjoerg if (RegNo == 0) 7087330f729Sjoerg return 0; 7097330f729Sjoerg if (RegNo == 1) 7107330f729Sjoerg return 1; 7117330f729Sjoerg return -1; 7127330f729Sjoerg } 7137330f729Sjoerg checkCallingConvention(CallingConv CC)7147330f729Sjoerg CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 7157330f729Sjoerg switch (CC) { 7167330f729Sjoerg case CC_C: 7177330f729Sjoerg case CC_Swift: 7187330f729Sjoerg case CC_X86VectorCall: 7197330f729Sjoerg case CC_IntelOclBicc: 7207330f729Sjoerg case CC_Win64: 7217330f729Sjoerg case CC_PreserveMost: 7227330f729Sjoerg case CC_PreserveAll: 7237330f729Sjoerg case CC_X86RegCall: 7247330f729Sjoerg case CC_OpenCLKernel: 7257330f729Sjoerg return CCCR_OK; 7267330f729Sjoerg default: 7277330f729Sjoerg return CCCR_Warning; 7287330f729Sjoerg } 7297330f729Sjoerg } 7307330f729Sjoerg getDefaultCallingConv()7317330f729Sjoerg CallingConv getDefaultCallingConv() const override { 7327330f729Sjoerg return CC_C; 7337330f729Sjoerg } 7347330f729Sjoerg 7357330f729Sjoerg // for x32 we need it here explicitly hasInt128Type()7367330f729Sjoerg bool hasInt128Type() const override { return true; } 7377330f729Sjoerg getUnwindWordWidth()7387330f729Sjoerg unsigned getUnwindWordWidth() const override { return 64; } 7397330f729Sjoerg getRegisterWidth()7407330f729Sjoerg unsigned getRegisterWidth() const override { return 64; } 7417330f729Sjoerg validateGlobalRegisterVariable(StringRef RegName,unsigned RegSize,bool & HasSizeMismatch)7427330f729Sjoerg bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize, 7437330f729Sjoerg bool &HasSizeMismatch) const override { 7447330f729Sjoerg // rsp and rbp are the only 64-bit registers the x86 backend can currently 7457330f729Sjoerg // handle. 7467330f729Sjoerg if (RegName.equals("rsp") || RegName.equals("rbp")) { 7477330f729Sjoerg // Check that the register size is 64-bit. 7487330f729Sjoerg HasSizeMismatch = RegSize != 64; 7497330f729Sjoerg return true; 7507330f729Sjoerg } 7517330f729Sjoerg 7527330f729Sjoerg // Check if the register is a 32-bit register the backend can handle. 7537330f729Sjoerg return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize, 7547330f729Sjoerg HasSizeMismatch); 7557330f729Sjoerg } 7567330f729Sjoerg setMaxAtomicWidth()7577330f729Sjoerg void setMaxAtomicWidth() override { 7587330f729Sjoerg if (hasFeature("cx16")) 7597330f729Sjoerg MaxAtomicInlineWidth = 128; 7607330f729Sjoerg } 7617330f729Sjoerg 7627330f729Sjoerg ArrayRef<Builtin::Info> getTargetBuiltins() const override; 763*e038c9c4Sjoerg hasExtIntType()764*e038c9c4Sjoerg bool hasExtIntType() const override { return true; } 7657330f729Sjoerg }; 7667330f729Sjoerg 7677330f729Sjoerg // x86-64 Windows target 7687330f729Sjoerg class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo 7697330f729Sjoerg : public WindowsTargetInfo<X86_64TargetInfo> { 7707330f729Sjoerg public: WindowsX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)7717330f729Sjoerg WindowsX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 7727330f729Sjoerg : WindowsTargetInfo<X86_64TargetInfo>(Triple, Opts) { 7737330f729Sjoerg LongWidth = LongAlign = 32; 7747330f729Sjoerg DoubleAlign = LongLongAlign = 64; 7757330f729Sjoerg IntMaxType = SignedLongLong; 7767330f729Sjoerg Int64Type = SignedLongLong; 7777330f729Sjoerg SizeType = UnsignedLongLong; 7787330f729Sjoerg PtrDiffType = SignedLongLong; 7797330f729Sjoerg IntPtrType = SignedLongLong; 7807330f729Sjoerg } 7817330f729Sjoerg getBuiltinVaListKind()7827330f729Sjoerg BuiltinVaListKind getBuiltinVaListKind() const override { 7837330f729Sjoerg return TargetInfo::CharPtrBuiltinVaList; 7847330f729Sjoerg } 7857330f729Sjoerg checkCallingConvention(CallingConv CC)7867330f729Sjoerg CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 7877330f729Sjoerg switch (CC) { 7887330f729Sjoerg case CC_X86StdCall: 7897330f729Sjoerg case CC_X86ThisCall: 7907330f729Sjoerg case CC_X86FastCall: 7917330f729Sjoerg return CCCR_Ignore; 7927330f729Sjoerg case CC_C: 7937330f729Sjoerg case CC_X86VectorCall: 7947330f729Sjoerg case CC_IntelOclBicc: 7957330f729Sjoerg case CC_PreserveMost: 7967330f729Sjoerg case CC_PreserveAll: 7977330f729Sjoerg case CC_X86_64SysV: 7987330f729Sjoerg case CC_Swift: 7997330f729Sjoerg case CC_X86RegCall: 8007330f729Sjoerg case CC_OpenCLKernel: 8017330f729Sjoerg return CCCR_OK; 8027330f729Sjoerg default: 8037330f729Sjoerg return CCCR_Warning; 8047330f729Sjoerg } 8057330f729Sjoerg } 8067330f729Sjoerg }; 8077330f729Sjoerg 8087330f729Sjoerg // x86-64 Windows Visual Studio target 8097330f729Sjoerg class LLVM_LIBRARY_VISIBILITY MicrosoftX86_64TargetInfo 8107330f729Sjoerg : public WindowsX86_64TargetInfo { 8117330f729Sjoerg public: MicrosoftX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8127330f729Sjoerg MicrosoftX86_64TargetInfo(const llvm::Triple &Triple, 8137330f729Sjoerg const TargetOptions &Opts) 8147330f729Sjoerg : WindowsX86_64TargetInfo(Triple, Opts) { 8157330f729Sjoerg LongDoubleWidth = LongDoubleAlign = 64; 8167330f729Sjoerg LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 8177330f729Sjoerg } 8187330f729Sjoerg getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)8197330f729Sjoerg void getTargetDefines(const LangOptions &Opts, 8207330f729Sjoerg MacroBuilder &Builder) const override { 8217330f729Sjoerg WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder); 8227330f729Sjoerg Builder.defineMacro("_M_X64", "100"); 8237330f729Sjoerg Builder.defineMacro("_M_AMD64", "100"); 8247330f729Sjoerg } 8257330f729Sjoerg 8267330f729Sjoerg TargetInfo::CallingConvKind getCallingConvKind(bool ClangABICompat4)8277330f729Sjoerg getCallingConvKind(bool ClangABICompat4) const override { 8287330f729Sjoerg return CCK_MicrosoftWin64; 8297330f729Sjoerg } 8307330f729Sjoerg }; 8317330f729Sjoerg 8327330f729Sjoerg // x86-64 MinGW target 8337330f729Sjoerg class LLVM_LIBRARY_VISIBILITY MinGWX86_64TargetInfo 8347330f729Sjoerg : public WindowsX86_64TargetInfo { 8357330f729Sjoerg public: MinGWX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8367330f729Sjoerg MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 8377330f729Sjoerg : WindowsX86_64TargetInfo(Triple, Opts) { 8387330f729Sjoerg // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks 8397330f729Sjoerg // with x86 FP ops. Weird. 8407330f729Sjoerg LongDoubleWidth = LongDoubleAlign = 128; 8417330f729Sjoerg LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); 8427330f729Sjoerg HasFloat128 = true; 8437330f729Sjoerg } 8447330f729Sjoerg }; 8457330f729Sjoerg 8467330f729Sjoerg // x86-64 Cygwin target 8477330f729Sjoerg class LLVM_LIBRARY_VISIBILITY CygwinX86_64TargetInfo : public X86_64TargetInfo { 8487330f729Sjoerg public: CygwinX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8497330f729Sjoerg CygwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 8507330f729Sjoerg : X86_64TargetInfo(Triple, Opts) { 8517330f729Sjoerg this->WCharType = TargetInfo::UnsignedShort; 8527330f729Sjoerg TLSSupported = false; 8537330f729Sjoerg } 8547330f729Sjoerg getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder)8557330f729Sjoerg void getTargetDefines(const LangOptions &Opts, 8567330f729Sjoerg MacroBuilder &Builder) const override { 8577330f729Sjoerg X86_64TargetInfo::getTargetDefines(Opts, Builder); 8587330f729Sjoerg Builder.defineMacro("__x86_64__"); 8597330f729Sjoerg Builder.defineMacro("__CYGWIN__"); 8607330f729Sjoerg Builder.defineMacro("__CYGWIN64__"); 8617330f729Sjoerg addCygMingDefines(Opts, Builder); 8627330f729Sjoerg DefineStd(Builder, "unix", Opts); 8637330f729Sjoerg if (Opts.CPlusPlus) 8647330f729Sjoerg Builder.defineMacro("_GNU_SOURCE"); 8657330f729Sjoerg } 8667330f729Sjoerg }; 8677330f729Sjoerg 8687330f729Sjoerg class LLVM_LIBRARY_VISIBILITY DarwinX86_64TargetInfo 8697330f729Sjoerg : public DarwinTargetInfo<X86_64TargetInfo> { 8707330f729Sjoerg public: DarwinX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8717330f729Sjoerg DarwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 8727330f729Sjoerg : DarwinTargetInfo<X86_64TargetInfo>(Triple, Opts) { 8737330f729Sjoerg Int64Type = SignedLongLong; 8747330f729Sjoerg // The 64-bit iOS simulator uses the builtin bool type for Objective-C. 8757330f729Sjoerg llvm::Triple T = llvm::Triple(Triple); 8767330f729Sjoerg if (T.isiOS()) 8777330f729Sjoerg UseSignedCharForObjCBool = false; 8787330f729Sjoerg resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:" 879*e038c9c4Sjoerg "16:32:64-S128", "_"); 8807330f729Sjoerg } 8817330f729Sjoerg handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)8827330f729Sjoerg bool handleTargetFeatures(std::vector<std::string> &Features, 8837330f729Sjoerg DiagnosticsEngine &Diags) override { 8847330f729Sjoerg if (!DarwinTargetInfo<X86_64TargetInfo>::handleTargetFeatures(Features, 8857330f729Sjoerg Diags)) 8867330f729Sjoerg return false; 8877330f729Sjoerg // We now know the features we have: we can decide how to align vectors. 8887330f729Sjoerg MaxVectorAlign = 8897330f729Sjoerg hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128; 8907330f729Sjoerg return true; 8917330f729Sjoerg } 8927330f729Sjoerg }; 8937330f729Sjoerg 8947330f729Sjoerg class LLVM_LIBRARY_VISIBILITY OpenBSDX86_64TargetInfo 8957330f729Sjoerg : public OpenBSDTargetInfo<X86_64TargetInfo> { 8967330f729Sjoerg public: OpenBSDX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)8977330f729Sjoerg OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 8987330f729Sjoerg : OpenBSDTargetInfo<X86_64TargetInfo>(Triple, Opts) { 8997330f729Sjoerg IntMaxType = SignedLongLong; 9007330f729Sjoerg Int64Type = SignedLongLong; 9017330f729Sjoerg } 9027330f729Sjoerg }; 9037330f729Sjoerg 9047330f729Sjoerg // x86_32 Android target 9057330f729Sjoerg class LLVM_LIBRARY_VISIBILITY AndroidX86_32TargetInfo 9067330f729Sjoerg : public LinuxTargetInfo<X86_32TargetInfo> { 9077330f729Sjoerg public: AndroidX86_32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)9087330f729Sjoerg AndroidX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 9097330f729Sjoerg : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) { 9107330f729Sjoerg SuitableAlign = 32; 9117330f729Sjoerg LongDoubleWidth = 64; 9127330f729Sjoerg LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 9137330f729Sjoerg } 9147330f729Sjoerg }; 9157330f729Sjoerg 9167330f729Sjoerg // x86_64 Android target 9177330f729Sjoerg class LLVM_LIBRARY_VISIBILITY AndroidX86_64TargetInfo 9187330f729Sjoerg : public LinuxTargetInfo<X86_64TargetInfo> { 9197330f729Sjoerg public: AndroidX86_64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)9207330f729Sjoerg AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 9217330f729Sjoerg : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) { 9227330f729Sjoerg LongDoubleFormat = &llvm::APFloat::IEEEquad(); 9237330f729Sjoerg } 9247330f729Sjoerg }; 9257330f729Sjoerg } // namespace targets 9267330f729Sjoerg } // namespace clang 9277330f729Sjoerg #endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H 928