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