1e5dd7070Spatrick //===--- X86.cpp - Implement X86 target feature support -------------------===// 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 implements X86 TargetInfo objects. 10e5dd7070Spatrick // 11e5dd7070Spatrick //===----------------------------------------------------------------------===// 12e5dd7070Spatrick 13e5dd7070Spatrick #include "X86.h" 14e5dd7070Spatrick #include "clang/Basic/Builtins.h" 15e5dd7070Spatrick #include "clang/Basic/Diagnostic.h" 16e5dd7070Spatrick #include "clang/Basic/TargetBuiltins.h" 17e5dd7070Spatrick #include "llvm/ADT/StringExtras.h" 18e5dd7070Spatrick #include "llvm/ADT/StringRef.h" 19e5dd7070Spatrick #include "llvm/ADT/StringSwitch.h" 20*ec727ea7Spatrick #include "llvm/Support/X86TargetParser.h" 21e5dd7070Spatrick 22e5dd7070Spatrick namespace clang { 23e5dd7070Spatrick namespace targets { 24e5dd7070Spatrick 25e5dd7070Spatrick const Builtin::Info BuiltinInfoX86[] = { 26e5dd7070Spatrick #define BUILTIN(ID, TYPE, ATTRS) \ 27e5dd7070Spatrick {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 28e5dd7070Spatrick #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ 29e5dd7070Spatrick {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, 30e5dd7070Spatrick #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 31e5dd7070Spatrick {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, 32e5dd7070Spatrick #include "clang/Basic/BuiltinsX86.def" 33e5dd7070Spatrick 34e5dd7070Spatrick #define BUILTIN(ID, TYPE, ATTRS) \ 35e5dd7070Spatrick {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, 36e5dd7070Spatrick #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ 37e5dd7070Spatrick {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, 38e5dd7070Spatrick #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 39e5dd7070Spatrick {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, 40e5dd7070Spatrick #include "clang/Basic/BuiltinsX86_64.def" 41e5dd7070Spatrick }; 42e5dd7070Spatrick 43e5dd7070Spatrick static const char *const GCCRegNames[] = { 44e5dd7070Spatrick "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", 45e5dd7070Spatrick "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", 46e5dd7070Spatrick "argp", "flags", "fpcr", "fpsr", "dirflag", "frame", "xmm0", "xmm1", 47e5dd7070Spatrick "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "mm0", "mm1", 48e5dd7070Spatrick "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "r8", "r9", 49e5dd7070Spatrick "r10", "r11", "r12", "r13", "r14", "r15", "xmm8", "xmm9", 50e5dd7070Spatrick "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", "ymm0", "ymm1", 51e5dd7070Spatrick "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", 52e5dd7070Spatrick "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15", "xmm16", "xmm17", 53e5dd7070Spatrick "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23", "xmm24", "xmm25", 54e5dd7070Spatrick "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31", "ymm16", "ymm17", 55e5dd7070Spatrick "ymm18", "ymm19", "ymm20", "ymm21", "ymm22", "ymm23", "ymm24", "ymm25", 56e5dd7070Spatrick "ymm26", "ymm27", "ymm28", "ymm29", "ymm30", "ymm31", "zmm0", "zmm1", 57e5dd7070Spatrick "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", "zmm7", "zmm8", "zmm9", 58e5dd7070Spatrick "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", "zmm16", "zmm17", 59e5dd7070Spatrick "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", "zmm24", "zmm25", 60e5dd7070Spatrick "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31", "k0", "k1", 61e5dd7070Spatrick "k2", "k3", "k4", "k5", "k6", "k7", 62e5dd7070Spatrick "cr0", "cr2", "cr3", "cr4", "cr8", 63e5dd7070Spatrick "dr0", "dr1", "dr2", "dr3", "dr6", "dr7", 64e5dd7070Spatrick "bnd0", "bnd1", "bnd2", "bnd3", 65*ec727ea7Spatrick "tmm0", "tmm1", "tmm2", "tmm3", "tmm4", "tmm5", "tmm6", "tmm7", 66e5dd7070Spatrick }; 67e5dd7070Spatrick 68e5dd7070Spatrick const TargetInfo::AddlRegName AddlRegNames[] = { 69e5dd7070Spatrick {{"al", "ah", "eax", "rax"}, 0}, 70e5dd7070Spatrick {{"bl", "bh", "ebx", "rbx"}, 3}, 71e5dd7070Spatrick {{"cl", "ch", "ecx", "rcx"}, 2}, 72e5dd7070Spatrick {{"dl", "dh", "edx", "rdx"}, 1}, 73e5dd7070Spatrick {{"esi", "rsi"}, 4}, 74e5dd7070Spatrick {{"edi", "rdi"}, 5}, 75e5dd7070Spatrick {{"esp", "rsp"}, 7}, 76e5dd7070Spatrick {{"ebp", "rbp"}, 6}, 77e5dd7070Spatrick {{"r8d", "r8w", "r8b"}, 38}, 78e5dd7070Spatrick {{"r9d", "r9w", "r9b"}, 39}, 79e5dd7070Spatrick {{"r10d", "r10w", "r10b"}, 40}, 80e5dd7070Spatrick {{"r11d", "r11w", "r11b"}, 41}, 81e5dd7070Spatrick {{"r12d", "r12w", "r12b"}, 42}, 82e5dd7070Spatrick {{"r13d", "r13w", "r13b"}, 43}, 83e5dd7070Spatrick {{"r14d", "r14w", "r14b"}, 44}, 84e5dd7070Spatrick {{"r15d", "r15w", "r15b"}, 45}, 85e5dd7070Spatrick }; 86e5dd7070Spatrick 87e5dd7070Spatrick } // namespace targets 88e5dd7070Spatrick } // namespace clang 89e5dd7070Spatrick 90e5dd7070Spatrick using namespace clang; 91e5dd7070Spatrick using namespace clang::targets; 92e5dd7070Spatrick 93e5dd7070Spatrick bool X86TargetInfo::setFPMath(StringRef Name) { 94e5dd7070Spatrick if (Name == "387") { 95e5dd7070Spatrick FPMath = FP_387; 96e5dd7070Spatrick return true; 97e5dd7070Spatrick } 98e5dd7070Spatrick if (Name == "sse") { 99e5dd7070Spatrick FPMath = FP_SSE; 100e5dd7070Spatrick return true; 101e5dd7070Spatrick } 102e5dd7070Spatrick return false; 103e5dd7070Spatrick } 104e5dd7070Spatrick 105e5dd7070Spatrick bool X86TargetInfo::initFeatureMap( 106e5dd7070Spatrick llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, 107e5dd7070Spatrick const std::vector<std::string> &FeaturesVec) const { 108e5dd7070Spatrick // FIXME: This *really* should not be here. 109e5dd7070Spatrick // X86_64 always has SSE2. 110e5dd7070Spatrick if (getTriple().getArch() == llvm::Triple::x86_64) 111*ec727ea7Spatrick setFeatureEnabled(Features, "sse2", true); 112e5dd7070Spatrick 113*ec727ea7Spatrick using namespace llvm::X86; 114e5dd7070Spatrick 115*ec727ea7Spatrick SmallVector<StringRef, 16> CPUFeatures; 116*ec727ea7Spatrick getFeaturesForCPU(CPU, CPUFeatures); 117*ec727ea7Spatrick for (auto &F : CPUFeatures) 118*ec727ea7Spatrick setFeatureEnabled(Features, F, true); 119e5dd7070Spatrick 120e5dd7070Spatrick if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec)) 121e5dd7070Spatrick return false; 122e5dd7070Spatrick 123e5dd7070Spatrick // Can't do this earlier because we need to be able to explicitly enable 124e5dd7070Spatrick // or disable these features and the things that they depend upon. 125e5dd7070Spatrick 126e5dd7070Spatrick // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled. 127e5dd7070Spatrick auto I = Features.find("sse4.2"); 128e5dd7070Spatrick if (I != Features.end() && I->getValue() && 129e5dd7070Spatrick llvm::find(FeaturesVec, "-popcnt") == FeaturesVec.end()) 130e5dd7070Spatrick Features["popcnt"] = true; 131e5dd7070Spatrick 132e5dd7070Spatrick // Additionally, if SSE is enabled and mmx is not explicitly disabled, 133e5dd7070Spatrick // then enable MMX. 134e5dd7070Spatrick I = Features.find("sse"); 135e5dd7070Spatrick if (I != Features.end() && I->getValue() && 136e5dd7070Spatrick llvm::find(FeaturesVec, "-mmx") == FeaturesVec.end()) 137e5dd7070Spatrick Features["mmx"] = true; 138e5dd7070Spatrick 139*ec727ea7Spatrick // Enable xsave if avx is enabled and xsave is not explicitly disabled. 140*ec727ea7Spatrick I = Features.find("avx"); 141*ec727ea7Spatrick if (I != Features.end() && I->getValue() && 142*ec727ea7Spatrick llvm::find(FeaturesVec, "-xsave") == FeaturesVec.end()) 143*ec727ea7Spatrick Features["xsave"] = true; 144*ec727ea7Spatrick 145e5dd7070Spatrick return true; 146e5dd7070Spatrick } 147e5dd7070Spatrick 148*ec727ea7Spatrick void X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, 149*ec727ea7Spatrick StringRef Name, bool Enabled) const { 150*ec727ea7Spatrick if (Name == "sse4") { 151e5dd7070Spatrick // We can get here via the __target__ attribute since that's not controlled 152e5dd7070Spatrick // via the -msse4/-mno-sse4 command line alias. Handle this the same way 153e5dd7070Spatrick // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if 154e5dd7070Spatrick // disabled. 155e5dd7070Spatrick if (Enabled) 156*ec727ea7Spatrick Name = "sse4.2"; 157e5dd7070Spatrick else 158*ec727ea7Spatrick Name = "sse4.1"; 159e5dd7070Spatrick } 160*ec727ea7Spatrick 161*ec727ea7Spatrick Features[Name] = Enabled; 162*ec727ea7Spatrick 163*ec727ea7Spatrick SmallVector<StringRef, 8> ImpliedFeatures; 164*ec727ea7Spatrick llvm::X86::getImpliedFeatures(Name, Enabled, ImpliedFeatures); 165*ec727ea7Spatrick for (const auto &F : ImpliedFeatures) 166*ec727ea7Spatrick Features[F] = Enabled; 167e5dd7070Spatrick } 168e5dd7070Spatrick 169e5dd7070Spatrick /// handleTargetFeatures - Perform initialization based on the user 170e5dd7070Spatrick /// configured set of features. 171e5dd7070Spatrick bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, 172e5dd7070Spatrick DiagnosticsEngine &Diags) { 173e5dd7070Spatrick for (const auto &Feature : Features) { 174e5dd7070Spatrick if (Feature[0] != '+') 175e5dd7070Spatrick continue; 176e5dd7070Spatrick 177e5dd7070Spatrick if (Feature == "+aes") { 178e5dd7070Spatrick HasAES = true; 179e5dd7070Spatrick } else if (Feature == "+vaes") { 180e5dd7070Spatrick HasVAES = true; 181e5dd7070Spatrick } else if (Feature == "+pclmul") { 182e5dd7070Spatrick HasPCLMUL = true; 183e5dd7070Spatrick } else if (Feature == "+vpclmulqdq") { 184e5dd7070Spatrick HasVPCLMULQDQ = true; 185e5dd7070Spatrick } else if (Feature == "+lzcnt") { 186e5dd7070Spatrick HasLZCNT = true; 187e5dd7070Spatrick } else if (Feature == "+rdrnd") { 188e5dd7070Spatrick HasRDRND = true; 189e5dd7070Spatrick } else if (Feature == "+fsgsbase") { 190e5dd7070Spatrick HasFSGSBASE = true; 191e5dd7070Spatrick } else if (Feature == "+bmi") { 192e5dd7070Spatrick HasBMI = true; 193e5dd7070Spatrick } else if (Feature == "+bmi2") { 194e5dd7070Spatrick HasBMI2 = true; 195e5dd7070Spatrick } else if (Feature == "+popcnt") { 196e5dd7070Spatrick HasPOPCNT = true; 197e5dd7070Spatrick } else if (Feature == "+rtm") { 198e5dd7070Spatrick HasRTM = true; 199e5dd7070Spatrick } else if (Feature == "+prfchw") { 200e5dd7070Spatrick HasPRFCHW = true; 201e5dd7070Spatrick } else if (Feature == "+rdseed") { 202e5dd7070Spatrick HasRDSEED = true; 203e5dd7070Spatrick } else if (Feature == "+adx") { 204e5dd7070Spatrick HasADX = true; 205e5dd7070Spatrick } else if (Feature == "+tbm") { 206e5dd7070Spatrick HasTBM = true; 207e5dd7070Spatrick } else if (Feature == "+lwp") { 208e5dd7070Spatrick HasLWP = true; 209e5dd7070Spatrick } else if (Feature == "+fma") { 210e5dd7070Spatrick HasFMA = true; 211e5dd7070Spatrick } else if (Feature == "+f16c") { 212e5dd7070Spatrick HasF16C = true; 213e5dd7070Spatrick } else if (Feature == "+gfni") { 214e5dd7070Spatrick HasGFNI = true; 215e5dd7070Spatrick } else if (Feature == "+avx512cd") { 216e5dd7070Spatrick HasAVX512CD = true; 217e5dd7070Spatrick } else if (Feature == "+avx512vpopcntdq") { 218e5dd7070Spatrick HasAVX512VPOPCNTDQ = true; 219e5dd7070Spatrick } else if (Feature == "+avx512vnni") { 220e5dd7070Spatrick HasAVX512VNNI = true; 221e5dd7070Spatrick } else if (Feature == "+avx512bf16") { 222e5dd7070Spatrick HasAVX512BF16 = true; 223e5dd7070Spatrick } else if (Feature == "+avx512er") { 224e5dd7070Spatrick HasAVX512ER = true; 225e5dd7070Spatrick } else if (Feature == "+avx512pf") { 226e5dd7070Spatrick HasAVX512PF = true; 227e5dd7070Spatrick } else if (Feature == "+avx512dq") { 228e5dd7070Spatrick HasAVX512DQ = true; 229e5dd7070Spatrick } else if (Feature == "+avx512bitalg") { 230e5dd7070Spatrick HasAVX512BITALG = true; 231e5dd7070Spatrick } else if (Feature == "+avx512bw") { 232e5dd7070Spatrick HasAVX512BW = true; 233e5dd7070Spatrick } else if (Feature == "+avx512vl") { 234e5dd7070Spatrick HasAVX512VL = true; 235e5dd7070Spatrick } else if (Feature == "+avx512vbmi") { 236e5dd7070Spatrick HasAVX512VBMI = true; 237e5dd7070Spatrick } else if (Feature == "+avx512vbmi2") { 238e5dd7070Spatrick HasAVX512VBMI2 = true; 239e5dd7070Spatrick } else if (Feature == "+avx512ifma") { 240e5dd7070Spatrick HasAVX512IFMA = true; 241e5dd7070Spatrick } else if (Feature == "+avx512vp2intersect") { 242e5dd7070Spatrick HasAVX512VP2INTERSECT = true; 243e5dd7070Spatrick } else if (Feature == "+sha") { 244e5dd7070Spatrick HasSHA = true; 245e5dd7070Spatrick } else if (Feature == "+shstk") { 246e5dd7070Spatrick HasSHSTK = true; 247e5dd7070Spatrick } else if (Feature == "+movbe") { 248e5dd7070Spatrick HasMOVBE = true; 249e5dd7070Spatrick } else if (Feature == "+sgx") { 250e5dd7070Spatrick HasSGX = true; 251e5dd7070Spatrick } else if (Feature == "+cx8") { 252e5dd7070Spatrick HasCX8 = true; 253e5dd7070Spatrick } else if (Feature == "+cx16") { 254e5dd7070Spatrick HasCX16 = true; 255e5dd7070Spatrick } else if (Feature == "+fxsr") { 256e5dd7070Spatrick HasFXSR = true; 257e5dd7070Spatrick } else if (Feature == "+xsave") { 258e5dd7070Spatrick HasXSAVE = true; 259e5dd7070Spatrick } else if (Feature == "+xsaveopt") { 260e5dd7070Spatrick HasXSAVEOPT = true; 261e5dd7070Spatrick } else if (Feature == "+xsavec") { 262e5dd7070Spatrick HasXSAVEC = true; 263e5dd7070Spatrick } else if (Feature == "+xsaves") { 264e5dd7070Spatrick HasXSAVES = true; 265e5dd7070Spatrick } else if (Feature == "+mwaitx") { 266e5dd7070Spatrick HasMWAITX = true; 267e5dd7070Spatrick } else if (Feature == "+pku") { 268e5dd7070Spatrick HasPKU = true; 269e5dd7070Spatrick } else if (Feature == "+clflushopt") { 270e5dd7070Spatrick HasCLFLUSHOPT = true; 271e5dd7070Spatrick } else if (Feature == "+clwb") { 272e5dd7070Spatrick HasCLWB = true; 273e5dd7070Spatrick } else if (Feature == "+wbnoinvd") { 274e5dd7070Spatrick HasWBNOINVD = true; 275e5dd7070Spatrick } else if (Feature == "+prefetchwt1") { 276e5dd7070Spatrick HasPREFETCHWT1 = true; 277e5dd7070Spatrick } else if (Feature == "+clzero") { 278e5dd7070Spatrick HasCLZERO = true; 279e5dd7070Spatrick } else if (Feature == "+cldemote") { 280e5dd7070Spatrick HasCLDEMOTE = true; 281e5dd7070Spatrick } else if (Feature == "+rdpid") { 282e5dd7070Spatrick HasRDPID = true; 283e5dd7070Spatrick } else if (Feature == "+retpoline-external-thunk") { 284e5dd7070Spatrick HasRetpolineExternalThunk = true; 285e5dd7070Spatrick } else if (Feature == "+sahf") { 286e5dd7070Spatrick HasLAHFSAHF = true; 287e5dd7070Spatrick } else if (Feature == "+waitpkg") { 288e5dd7070Spatrick HasWAITPKG = true; 289e5dd7070Spatrick } else if (Feature == "+movdiri") { 290e5dd7070Spatrick HasMOVDIRI = true; 291e5dd7070Spatrick } else if (Feature == "+movdir64b") { 292e5dd7070Spatrick HasMOVDIR64B = true; 293e5dd7070Spatrick } else if (Feature == "+pconfig") { 294e5dd7070Spatrick HasPCONFIG = true; 295e5dd7070Spatrick } else if (Feature == "+ptwrite") { 296e5dd7070Spatrick HasPTWRITE = true; 297e5dd7070Spatrick } else if (Feature == "+invpcid") { 298e5dd7070Spatrick HasINVPCID = true; 299e5dd7070Spatrick } else if (Feature == "+enqcmd") { 300e5dd7070Spatrick HasENQCMD = true; 301*ec727ea7Spatrick } else if (Feature == "+amx-bf16") { 302*ec727ea7Spatrick HasAMXBF16 = true; 303*ec727ea7Spatrick } else if (Feature == "+amx-int8") { 304*ec727ea7Spatrick HasAMXINT8 = true; 305*ec727ea7Spatrick } else if (Feature == "+amx-tile") { 306*ec727ea7Spatrick HasAMXTILE = true; 307*ec727ea7Spatrick } else if (Feature == "+serialize") { 308*ec727ea7Spatrick HasSERIALIZE = true; 309*ec727ea7Spatrick } else if (Feature == "+tsxldtrk") { 310*ec727ea7Spatrick HasTSXLDTRK = true; 311e5dd7070Spatrick } 312e5dd7070Spatrick 313e5dd7070Spatrick X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) 314e5dd7070Spatrick .Case("+avx512f", AVX512F) 315e5dd7070Spatrick .Case("+avx2", AVX2) 316e5dd7070Spatrick .Case("+avx", AVX) 317e5dd7070Spatrick .Case("+sse4.2", SSE42) 318e5dd7070Spatrick .Case("+sse4.1", SSE41) 319e5dd7070Spatrick .Case("+ssse3", SSSE3) 320e5dd7070Spatrick .Case("+sse3", SSE3) 321e5dd7070Spatrick .Case("+sse2", SSE2) 322e5dd7070Spatrick .Case("+sse", SSE1) 323e5dd7070Spatrick .Default(NoSSE); 324e5dd7070Spatrick SSELevel = std::max(SSELevel, Level); 325e5dd7070Spatrick 326e5dd7070Spatrick MMX3DNowEnum ThreeDNowLevel = llvm::StringSwitch<MMX3DNowEnum>(Feature) 327e5dd7070Spatrick .Case("+3dnowa", AMD3DNowAthlon) 328e5dd7070Spatrick .Case("+3dnow", AMD3DNow) 329e5dd7070Spatrick .Case("+mmx", MMX) 330e5dd7070Spatrick .Default(NoMMX3DNow); 331e5dd7070Spatrick MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel); 332e5dd7070Spatrick 333e5dd7070Spatrick XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature) 334e5dd7070Spatrick .Case("+xop", XOP) 335e5dd7070Spatrick .Case("+fma4", FMA4) 336e5dd7070Spatrick .Case("+sse4a", SSE4A) 337e5dd7070Spatrick .Default(NoXOP); 338e5dd7070Spatrick XOPLevel = std::max(XOPLevel, XLevel); 339e5dd7070Spatrick } 340e5dd7070Spatrick 341e5dd7070Spatrick // LLVM doesn't have a separate switch for fpmath, so only accept it if it 342e5dd7070Spatrick // matches the selected sse level. 343e5dd7070Spatrick if ((FPMath == FP_SSE && SSELevel < SSE1) || 344e5dd7070Spatrick (FPMath == FP_387 && SSELevel >= SSE1)) { 345e5dd7070Spatrick Diags.Report(diag::err_target_unsupported_fpmath) 346e5dd7070Spatrick << (FPMath == FP_SSE ? "sse" : "387"); 347e5dd7070Spatrick return false; 348e5dd7070Spatrick } 349e5dd7070Spatrick 350e5dd7070Spatrick SimdDefaultAlign = 351e5dd7070Spatrick hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128; 352e5dd7070Spatrick return true; 353e5dd7070Spatrick } 354e5dd7070Spatrick 355e5dd7070Spatrick /// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro 356e5dd7070Spatrick /// definitions for this particular subtarget. 357e5dd7070Spatrick void X86TargetInfo::getTargetDefines(const LangOptions &Opts, 358e5dd7070Spatrick MacroBuilder &Builder) const { 359e5dd7070Spatrick // Inline assembly supports X86 flag outputs. 360e5dd7070Spatrick Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__"); 361e5dd7070Spatrick 362e5dd7070Spatrick std::string CodeModel = getTargetOpts().CodeModel; 363e5dd7070Spatrick if (CodeModel == "default") 364e5dd7070Spatrick CodeModel = "small"; 365*ec727ea7Spatrick Builder.defineMacro("__code_model_" + CodeModel + "__"); 366e5dd7070Spatrick 367e5dd7070Spatrick // Target identification. 368e5dd7070Spatrick if (getTriple().getArch() == llvm::Triple::x86_64) { 369e5dd7070Spatrick Builder.defineMacro("__amd64__"); 370e5dd7070Spatrick Builder.defineMacro("__amd64"); 371e5dd7070Spatrick Builder.defineMacro("__x86_64"); 372e5dd7070Spatrick Builder.defineMacro("__x86_64__"); 373e5dd7070Spatrick if (getTriple().getArchName() == "x86_64h") { 374e5dd7070Spatrick Builder.defineMacro("__x86_64h"); 375e5dd7070Spatrick Builder.defineMacro("__x86_64h__"); 376e5dd7070Spatrick } 377e5dd7070Spatrick } else { 378e5dd7070Spatrick DefineStd(Builder, "i386", Opts); 379e5dd7070Spatrick } 380e5dd7070Spatrick 381e5dd7070Spatrick Builder.defineMacro("__SEG_GS"); 382e5dd7070Spatrick Builder.defineMacro("__SEG_FS"); 383e5dd7070Spatrick Builder.defineMacro("__seg_gs", "__attribute__((address_space(256)))"); 384e5dd7070Spatrick Builder.defineMacro("__seg_fs", "__attribute__((address_space(257)))"); 385e5dd7070Spatrick 386e5dd7070Spatrick // Subtarget options. 387e5dd7070Spatrick // FIXME: We are hard-coding the tune parameters based on the CPU, but they 388e5dd7070Spatrick // truly should be based on -mtune options. 389*ec727ea7Spatrick using namespace llvm::X86; 390e5dd7070Spatrick switch (CPU) { 391*ec727ea7Spatrick case CK_None: 392e5dd7070Spatrick break; 393e5dd7070Spatrick case CK_i386: 394e5dd7070Spatrick // The rest are coming from the i386 define above. 395e5dd7070Spatrick Builder.defineMacro("__tune_i386__"); 396e5dd7070Spatrick break; 397e5dd7070Spatrick case CK_i486: 398e5dd7070Spatrick case CK_WinChipC6: 399e5dd7070Spatrick case CK_WinChip2: 400e5dd7070Spatrick case CK_C3: 401e5dd7070Spatrick defineCPUMacros(Builder, "i486"); 402e5dd7070Spatrick break; 403e5dd7070Spatrick case CK_PentiumMMX: 404e5dd7070Spatrick Builder.defineMacro("__pentium_mmx__"); 405e5dd7070Spatrick Builder.defineMacro("__tune_pentium_mmx__"); 406e5dd7070Spatrick LLVM_FALLTHROUGH; 407e5dd7070Spatrick case CK_i586: 408e5dd7070Spatrick case CK_Pentium: 409e5dd7070Spatrick defineCPUMacros(Builder, "i586"); 410e5dd7070Spatrick defineCPUMacros(Builder, "pentium"); 411e5dd7070Spatrick break; 412e5dd7070Spatrick case CK_Pentium3: 413e5dd7070Spatrick case CK_PentiumM: 414e5dd7070Spatrick Builder.defineMacro("__tune_pentium3__"); 415e5dd7070Spatrick LLVM_FALLTHROUGH; 416e5dd7070Spatrick case CK_Pentium2: 417e5dd7070Spatrick case CK_C3_2: 418e5dd7070Spatrick Builder.defineMacro("__tune_pentium2__"); 419e5dd7070Spatrick LLVM_FALLTHROUGH; 420e5dd7070Spatrick case CK_PentiumPro: 421e5dd7070Spatrick case CK_i686: 422e5dd7070Spatrick defineCPUMacros(Builder, "i686"); 423e5dd7070Spatrick defineCPUMacros(Builder, "pentiumpro"); 424e5dd7070Spatrick break; 425e5dd7070Spatrick case CK_Pentium4: 426e5dd7070Spatrick defineCPUMacros(Builder, "pentium4"); 427e5dd7070Spatrick break; 428e5dd7070Spatrick case CK_Yonah: 429e5dd7070Spatrick case CK_Prescott: 430e5dd7070Spatrick case CK_Nocona: 431e5dd7070Spatrick defineCPUMacros(Builder, "nocona"); 432e5dd7070Spatrick break; 433e5dd7070Spatrick case CK_Core2: 434e5dd7070Spatrick case CK_Penryn: 435e5dd7070Spatrick defineCPUMacros(Builder, "core2"); 436e5dd7070Spatrick break; 437e5dd7070Spatrick case CK_Bonnell: 438e5dd7070Spatrick defineCPUMacros(Builder, "atom"); 439e5dd7070Spatrick break; 440e5dd7070Spatrick case CK_Silvermont: 441e5dd7070Spatrick defineCPUMacros(Builder, "slm"); 442e5dd7070Spatrick break; 443e5dd7070Spatrick case CK_Goldmont: 444e5dd7070Spatrick defineCPUMacros(Builder, "goldmont"); 445e5dd7070Spatrick break; 446e5dd7070Spatrick case CK_GoldmontPlus: 447e5dd7070Spatrick defineCPUMacros(Builder, "goldmont_plus"); 448e5dd7070Spatrick break; 449e5dd7070Spatrick case CK_Tremont: 450e5dd7070Spatrick defineCPUMacros(Builder, "tremont"); 451e5dd7070Spatrick break; 452e5dd7070Spatrick case CK_Nehalem: 453e5dd7070Spatrick case CK_Westmere: 454e5dd7070Spatrick case CK_SandyBridge: 455e5dd7070Spatrick case CK_IvyBridge: 456e5dd7070Spatrick case CK_Haswell: 457e5dd7070Spatrick case CK_Broadwell: 458e5dd7070Spatrick case CK_SkylakeClient: 459e5dd7070Spatrick case CK_SkylakeServer: 460e5dd7070Spatrick case CK_Cascadelake: 461e5dd7070Spatrick case CK_Cooperlake: 462e5dd7070Spatrick case CK_Cannonlake: 463e5dd7070Spatrick case CK_IcelakeClient: 464e5dd7070Spatrick case CK_IcelakeServer: 465e5dd7070Spatrick case CK_Tigerlake: 466e5dd7070Spatrick // FIXME: Historically, we defined this legacy name, it would be nice to 467e5dd7070Spatrick // remove it at some point. We've never exposed fine-grained names for 468e5dd7070Spatrick // recent primary x86 CPUs, and we should keep it that way. 469e5dd7070Spatrick defineCPUMacros(Builder, "corei7"); 470e5dd7070Spatrick break; 471e5dd7070Spatrick case CK_KNL: 472e5dd7070Spatrick defineCPUMacros(Builder, "knl"); 473e5dd7070Spatrick break; 474e5dd7070Spatrick case CK_KNM: 475e5dd7070Spatrick break; 476e5dd7070Spatrick case CK_Lakemont: 477e5dd7070Spatrick defineCPUMacros(Builder, "i586", /*Tuning*/false); 478e5dd7070Spatrick defineCPUMacros(Builder, "pentium", /*Tuning*/false); 479e5dd7070Spatrick Builder.defineMacro("__tune_lakemont__"); 480e5dd7070Spatrick break; 481e5dd7070Spatrick case CK_K6_2: 482e5dd7070Spatrick Builder.defineMacro("__k6_2__"); 483e5dd7070Spatrick Builder.defineMacro("__tune_k6_2__"); 484e5dd7070Spatrick LLVM_FALLTHROUGH; 485e5dd7070Spatrick case CK_K6_3: 486e5dd7070Spatrick if (CPU != CK_K6_2) { // In case of fallthrough 487e5dd7070Spatrick // FIXME: GCC may be enabling these in cases where some other k6 488e5dd7070Spatrick // architecture is specified but -m3dnow is explicitly provided. The 489e5dd7070Spatrick // exact semantics need to be determined and emulated here. 490e5dd7070Spatrick Builder.defineMacro("__k6_3__"); 491e5dd7070Spatrick Builder.defineMacro("__tune_k6_3__"); 492e5dd7070Spatrick } 493e5dd7070Spatrick LLVM_FALLTHROUGH; 494e5dd7070Spatrick case CK_K6: 495e5dd7070Spatrick defineCPUMacros(Builder, "k6"); 496e5dd7070Spatrick break; 497e5dd7070Spatrick case CK_Athlon: 498e5dd7070Spatrick case CK_AthlonXP: 499e5dd7070Spatrick defineCPUMacros(Builder, "athlon"); 500e5dd7070Spatrick if (SSELevel != NoSSE) { 501e5dd7070Spatrick Builder.defineMacro("__athlon_sse__"); 502e5dd7070Spatrick Builder.defineMacro("__tune_athlon_sse__"); 503e5dd7070Spatrick } 504e5dd7070Spatrick break; 505e5dd7070Spatrick case CK_K8: 506e5dd7070Spatrick case CK_K8SSE3: 507e5dd7070Spatrick case CK_x86_64: 508e5dd7070Spatrick defineCPUMacros(Builder, "k8"); 509e5dd7070Spatrick break; 510e5dd7070Spatrick case CK_AMDFAM10: 511e5dd7070Spatrick defineCPUMacros(Builder, "amdfam10"); 512e5dd7070Spatrick break; 513e5dd7070Spatrick case CK_BTVER1: 514e5dd7070Spatrick defineCPUMacros(Builder, "btver1"); 515e5dd7070Spatrick break; 516e5dd7070Spatrick case CK_BTVER2: 517e5dd7070Spatrick defineCPUMacros(Builder, "btver2"); 518e5dd7070Spatrick break; 519e5dd7070Spatrick case CK_BDVER1: 520e5dd7070Spatrick defineCPUMacros(Builder, "bdver1"); 521e5dd7070Spatrick break; 522e5dd7070Spatrick case CK_BDVER2: 523e5dd7070Spatrick defineCPUMacros(Builder, "bdver2"); 524e5dd7070Spatrick break; 525e5dd7070Spatrick case CK_BDVER3: 526e5dd7070Spatrick defineCPUMacros(Builder, "bdver3"); 527e5dd7070Spatrick break; 528e5dd7070Spatrick case CK_BDVER4: 529e5dd7070Spatrick defineCPUMacros(Builder, "bdver4"); 530e5dd7070Spatrick break; 531e5dd7070Spatrick case CK_ZNVER1: 532e5dd7070Spatrick defineCPUMacros(Builder, "znver1"); 533e5dd7070Spatrick break; 534e5dd7070Spatrick case CK_ZNVER2: 535e5dd7070Spatrick defineCPUMacros(Builder, "znver2"); 536e5dd7070Spatrick break; 537e5dd7070Spatrick case CK_Geode: 538e5dd7070Spatrick defineCPUMacros(Builder, "geode"); 539e5dd7070Spatrick break; 540e5dd7070Spatrick } 541e5dd7070Spatrick 542e5dd7070Spatrick // Target properties. 543e5dd7070Spatrick Builder.defineMacro("__REGISTER_PREFIX__", ""); 544e5dd7070Spatrick 545e5dd7070Spatrick // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline 546e5dd7070Spatrick // functions in glibc header files that use FP Stack inline asm which the 547e5dd7070Spatrick // backend can't deal with (PR879). 548e5dd7070Spatrick Builder.defineMacro("__NO_MATH_INLINES"); 549e5dd7070Spatrick 550e5dd7070Spatrick if (HasAES) 551e5dd7070Spatrick Builder.defineMacro("__AES__"); 552e5dd7070Spatrick 553e5dd7070Spatrick if (HasVAES) 554e5dd7070Spatrick Builder.defineMacro("__VAES__"); 555e5dd7070Spatrick 556e5dd7070Spatrick if (HasPCLMUL) 557e5dd7070Spatrick Builder.defineMacro("__PCLMUL__"); 558e5dd7070Spatrick 559e5dd7070Spatrick if (HasVPCLMULQDQ) 560e5dd7070Spatrick Builder.defineMacro("__VPCLMULQDQ__"); 561e5dd7070Spatrick 562e5dd7070Spatrick if (HasLZCNT) 563e5dd7070Spatrick Builder.defineMacro("__LZCNT__"); 564e5dd7070Spatrick 565e5dd7070Spatrick if (HasRDRND) 566e5dd7070Spatrick Builder.defineMacro("__RDRND__"); 567e5dd7070Spatrick 568e5dd7070Spatrick if (HasFSGSBASE) 569e5dd7070Spatrick Builder.defineMacro("__FSGSBASE__"); 570e5dd7070Spatrick 571e5dd7070Spatrick if (HasBMI) 572e5dd7070Spatrick Builder.defineMacro("__BMI__"); 573e5dd7070Spatrick 574e5dd7070Spatrick if (HasBMI2) 575e5dd7070Spatrick Builder.defineMacro("__BMI2__"); 576e5dd7070Spatrick 577e5dd7070Spatrick if (HasPOPCNT) 578e5dd7070Spatrick Builder.defineMacro("__POPCNT__"); 579e5dd7070Spatrick 580e5dd7070Spatrick if (HasRTM) 581e5dd7070Spatrick Builder.defineMacro("__RTM__"); 582e5dd7070Spatrick 583e5dd7070Spatrick if (HasPRFCHW) 584e5dd7070Spatrick Builder.defineMacro("__PRFCHW__"); 585e5dd7070Spatrick 586e5dd7070Spatrick if (HasRDSEED) 587e5dd7070Spatrick Builder.defineMacro("__RDSEED__"); 588e5dd7070Spatrick 589e5dd7070Spatrick if (HasADX) 590e5dd7070Spatrick Builder.defineMacro("__ADX__"); 591e5dd7070Spatrick 592e5dd7070Spatrick if (HasTBM) 593e5dd7070Spatrick Builder.defineMacro("__TBM__"); 594e5dd7070Spatrick 595e5dd7070Spatrick if (HasLWP) 596e5dd7070Spatrick Builder.defineMacro("__LWP__"); 597e5dd7070Spatrick 598e5dd7070Spatrick if (HasMWAITX) 599e5dd7070Spatrick Builder.defineMacro("__MWAITX__"); 600e5dd7070Spatrick 601e5dd7070Spatrick if (HasMOVBE) 602e5dd7070Spatrick Builder.defineMacro("__MOVBE__"); 603e5dd7070Spatrick 604e5dd7070Spatrick switch (XOPLevel) { 605e5dd7070Spatrick case XOP: 606e5dd7070Spatrick Builder.defineMacro("__XOP__"); 607e5dd7070Spatrick LLVM_FALLTHROUGH; 608e5dd7070Spatrick case FMA4: 609e5dd7070Spatrick Builder.defineMacro("__FMA4__"); 610e5dd7070Spatrick LLVM_FALLTHROUGH; 611e5dd7070Spatrick case SSE4A: 612e5dd7070Spatrick Builder.defineMacro("__SSE4A__"); 613e5dd7070Spatrick LLVM_FALLTHROUGH; 614e5dd7070Spatrick case NoXOP: 615e5dd7070Spatrick break; 616e5dd7070Spatrick } 617e5dd7070Spatrick 618e5dd7070Spatrick if (HasFMA) 619e5dd7070Spatrick Builder.defineMacro("__FMA__"); 620e5dd7070Spatrick 621e5dd7070Spatrick if (HasF16C) 622e5dd7070Spatrick Builder.defineMacro("__F16C__"); 623e5dd7070Spatrick 624e5dd7070Spatrick if (HasGFNI) 625e5dd7070Spatrick Builder.defineMacro("__GFNI__"); 626e5dd7070Spatrick 627e5dd7070Spatrick if (HasAVX512CD) 628e5dd7070Spatrick Builder.defineMacro("__AVX512CD__"); 629e5dd7070Spatrick if (HasAVX512VPOPCNTDQ) 630e5dd7070Spatrick Builder.defineMacro("__AVX512VPOPCNTDQ__"); 631e5dd7070Spatrick if (HasAVX512VNNI) 632e5dd7070Spatrick Builder.defineMacro("__AVX512VNNI__"); 633e5dd7070Spatrick if (HasAVX512BF16) 634e5dd7070Spatrick Builder.defineMacro("__AVX512BF16__"); 635e5dd7070Spatrick if (HasAVX512ER) 636e5dd7070Spatrick Builder.defineMacro("__AVX512ER__"); 637e5dd7070Spatrick if (HasAVX512PF) 638e5dd7070Spatrick Builder.defineMacro("__AVX512PF__"); 639e5dd7070Spatrick if (HasAVX512DQ) 640e5dd7070Spatrick Builder.defineMacro("__AVX512DQ__"); 641e5dd7070Spatrick if (HasAVX512BITALG) 642e5dd7070Spatrick Builder.defineMacro("__AVX512BITALG__"); 643e5dd7070Spatrick if (HasAVX512BW) 644e5dd7070Spatrick Builder.defineMacro("__AVX512BW__"); 645e5dd7070Spatrick if (HasAVX512VL) 646e5dd7070Spatrick Builder.defineMacro("__AVX512VL__"); 647e5dd7070Spatrick if (HasAVX512VBMI) 648e5dd7070Spatrick Builder.defineMacro("__AVX512VBMI__"); 649e5dd7070Spatrick if (HasAVX512VBMI2) 650e5dd7070Spatrick Builder.defineMacro("__AVX512VBMI2__"); 651e5dd7070Spatrick if (HasAVX512IFMA) 652e5dd7070Spatrick Builder.defineMacro("__AVX512IFMA__"); 653e5dd7070Spatrick if (HasAVX512VP2INTERSECT) 654e5dd7070Spatrick Builder.defineMacro("__AVX512VP2INTERSECT__"); 655e5dd7070Spatrick if (HasSHA) 656e5dd7070Spatrick Builder.defineMacro("__SHA__"); 657e5dd7070Spatrick 658e5dd7070Spatrick if (HasFXSR) 659e5dd7070Spatrick Builder.defineMacro("__FXSR__"); 660e5dd7070Spatrick if (HasXSAVE) 661e5dd7070Spatrick Builder.defineMacro("__XSAVE__"); 662e5dd7070Spatrick if (HasXSAVEOPT) 663e5dd7070Spatrick Builder.defineMacro("__XSAVEOPT__"); 664e5dd7070Spatrick if (HasXSAVEC) 665e5dd7070Spatrick Builder.defineMacro("__XSAVEC__"); 666e5dd7070Spatrick if (HasXSAVES) 667e5dd7070Spatrick Builder.defineMacro("__XSAVES__"); 668e5dd7070Spatrick if (HasPKU) 669e5dd7070Spatrick Builder.defineMacro("__PKU__"); 670e5dd7070Spatrick if (HasCLFLUSHOPT) 671e5dd7070Spatrick Builder.defineMacro("__CLFLUSHOPT__"); 672e5dd7070Spatrick if (HasCLWB) 673e5dd7070Spatrick Builder.defineMacro("__CLWB__"); 674e5dd7070Spatrick if (HasWBNOINVD) 675e5dd7070Spatrick Builder.defineMacro("__WBNOINVD__"); 676e5dd7070Spatrick if (HasSHSTK) 677e5dd7070Spatrick Builder.defineMacro("__SHSTK__"); 678e5dd7070Spatrick if (HasSGX) 679e5dd7070Spatrick Builder.defineMacro("__SGX__"); 680e5dd7070Spatrick if (HasPREFETCHWT1) 681e5dd7070Spatrick Builder.defineMacro("__PREFETCHWT1__"); 682e5dd7070Spatrick if (HasCLZERO) 683e5dd7070Spatrick Builder.defineMacro("__CLZERO__"); 684e5dd7070Spatrick if (HasRDPID) 685e5dd7070Spatrick Builder.defineMacro("__RDPID__"); 686e5dd7070Spatrick if (HasCLDEMOTE) 687e5dd7070Spatrick Builder.defineMacro("__CLDEMOTE__"); 688e5dd7070Spatrick if (HasWAITPKG) 689e5dd7070Spatrick Builder.defineMacro("__WAITPKG__"); 690e5dd7070Spatrick if (HasMOVDIRI) 691e5dd7070Spatrick Builder.defineMacro("__MOVDIRI__"); 692e5dd7070Spatrick if (HasMOVDIR64B) 693e5dd7070Spatrick Builder.defineMacro("__MOVDIR64B__"); 694e5dd7070Spatrick if (HasPCONFIG) 695e5dd7070Spatrick Builder.defineMacro("__PCONFIG__"); 696e5dd7070Spatrick if (HasPTWRITE) 697e5dd7070Spatrick Builder.defineMacro("__PTWRITE__"); 698e5dd7070Spatrick if (HasINVPCID) 699e5dd7070Spatrick Builder.defineMacro("__INVPCID__"); 700e5dd7070Spatrick if (HasENQCMD) 701e5dd7070Spatrick Builder.defineMacro("__ENQCMD__"); 702*ec727ea7Spatrick if (HasAMXTILE) 703*ec727ea7Spatrick Builder.defineMacro("__AMXTILE__"); 704*ec727ea7Spatrick if (HasAMXINT8) 705*ec727ea7Spatrick Builder.defineMacro("__AMXINT8__"); 706*ec727ea7Spatrick if (HasAMXBF16) 707*ec727ea7Spatrick Builder.defineMacro("__AMXBF16__"); 708*ec727ea7Spatrick if (HasSERIALIZE) 709*ec727ea7Spatrick Builder.defineMacro("__SERIALIZE__"); 710*ec727ea7Spatrick if (HasTSXLDTRK) 711*ec727ea7Spatrick Builder.defineMacro("__TSXLDTRK__"); 712e5dd7070Spatrick 713e5dd7070Spatrick // Each case falls through to the previous one here. 714e5dd7070Spatrick switch (SSELevel) { 715e5dd7070Spatrick case AVX512F: 716e5dd7070Spatrick Builder.defineMacro("__AVX512F__"); 717e5dd7070Spatrick LLVM_FALLTHROUGH; 718e5dd7070Spatrick case AVX2: 719e5dd7070Spatrick Builder.defineMacro("__AVX2__"); 720e5dd7070Spatrick LLVM_FALLTHROUGH; 721e5dd7070Spatrick case AVX: 722e5dd7070Spatrick Builder.defineMacro("__AVX__"); 723e5dd7070Spatrick LLVM_FALLTHROUGH; 724e5dd7070Spatrick case SSE42: 725e5dd7070Spatrick Builder.defineMacro("__SSE4_2__"); 726e5dd7070Spatrick LLVM_FALLTHROUGH; 727e5dd7070Spatrick case SSE41: 728e5dd7070Spatrick Builder.defineMacro("__SSE4_1__"); 729e5dd7070Spatrick LLVM_FALLTHROUGH; 730e5dd7070Spatrick case SSSE3: 731e5dd7070Spatrick Builder.defineMacro("__SSSE3__"); 732e5dd7070Spatrick LLVM_FALLTHROUGH; 733e5dd7070Spatrick case SSE3: 734e5dd7070Spatrick Builder.defineMacro("__SSE3__"); 735e5dd7070Spatrick LLVM_FALLTHROUGH; 736e5dd7070Spatrick case SSE2: 737e5dd7070Spatrick Builder.defineMacro("__SSE2__"); 738e5dd7070Spatrick Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied. 739e5dd7070Spatrick LLVM_FALLTHROUGH; 740e5dd7070Spatrick case SSE1: 741e5dd7070Spatrick Builder.defineMacro("__SSE__"); 742e5dd7070Spatrick Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied. 743e5dd7070Spatrick LLVM_FALLTHROUGH; 744e5dd7070Spatrick case NoSSE: 745e5dd7070Spatrick break; 746e5dd7070Spatrick } 747e5dd7070Spatrick 748e5dd7070Spatrick if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) { 749e5dd7070Spatrick switch (SSELevel) { 750e5dd7070Spatrick case AVX512F: 751e5dd7070Spatrick case AVX2: 752e5dd7070Spatrick case AVX: 753e5dd7070Spatrick case SSE42: 754e5dd7070Spatrick case SSE41: 755e5dd7070Spatrick case SSSE3: 756e5dd7070Spatrick case SSE3: 757e5dd7070Spatrick case SSE2: 758e5dd7070Spatrick Builder.defineMacro("_M_IX86_FP", Twine(2)); 759e5dd7070Spatrick break; 760e5dd7070Spatrick case SSE1: 761e5dd7070Spatrick Builder.defineMacro("_M_IX86_FP", Twine(1)); 762e5dd7070Spatrick break; 763e5dd7070Spatrick default: 764e5dd7070Spatrick Builder.defineMacro("_M_IX86_FP", Twine(0)); 765e5dd7070Spatrick break; 766e5dd7070Spatrick } 767e5dd7070Spatrick } 768e5dd7070Spatrick 769e5dd7070Spatrick // Each case falls through to the previous one here. 770e5dd7070Spatrick switch (MMX3DNowLevel) { 771e5dd7070Spatrick case AMD3DNowAthlon: 772e5dd7070Spatrick Builder.defineMacro("__3dNOW_A__"); 773e5dd7070Spatrick LLVM_FALLTHROUGH; 774e5dd7070Spatrick case AMD3DNow: 775e5dd7070Spatrick Builder.defineMacro("__3dNOW__"); 776e5dd7070Spatrick LLVM_FALLTHROUGH; 777e5dd7070Spatrick case MMX: 778e5dd7070Spatrick Builder.defineMacro("__MMX__"); 779e5dd7070Spatrick LLVM_FALLTHROUGH; 780e5dd7070Spatrick case NoMMX3DNow: 781e5dd7070Spatrick break; 782e5dd7070Spatrick } 783e5dd7070Spatrick 784*ec727ea7Spatrick if (CPU >= CK_i486 || CPU == CK_None) { 785e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 786e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 787e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 788e5dd7070Spatrick } 789e5dd7070Spatrick if (HasCX8) 790e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 791e5dd7070Spatrick if (HasCX16 && getTriple().getArch() == llvm::Triple::x86_64) 792e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16"); 793e5dd7070Spatrick 794e5dd7070Spatrick if (HasFloat128) 795e5dd7070Spatrick Builder.defineMacro("__SIZEOF_FLOAT128__", "16"); 796e5dd7070Spatrick } 797e5dd7070Spatrick 798e5dd7070Spatrick bool X86TargetInfo::isValidFeatureName(StringRef Name) const { 799e5dd7070Spatrick return llvm::StringSwitch<bool>(Name) 800e5dd7070Spatrick .Case("3dnow", true) 801e5dd7070Spatrick .Case("3dnowa", true) 802e5dd7070Spatrick .Case("adx", true) 803e5dd7070Spatrick .Case("aes", true) 804*ec727ea7Spatrick .Case("amx-bf16", true) 805*ec727ea7Spatrick .Case("amx-int8", true) 806*ec727ea7Spatrick .Case("amx-tile", true) 807e5dd7070Spatrick .Case("avx", true) 808e5dd7070Spatrick .Case("avx2", true) 809e5dd7070Spatrick .Case("avx512f", true) 810e5dd7070Spatrick .Case("avx512cd", true) 811e5dd7070Spatrick .Case("avx512vpopcntdq", true) 812e5dd7070Spatrick .Case("avx512vnni", true) 813e5dd7070Spatrick .Case("avx512bf16", true) 814e5dd7070Spatrick .Case("avx512er", true) 815e5dd7070Spatrick .Case("avx512pf", true) 816e5dd7070Spatrick .Case("avx512dq", true) 817e5dd7070Spatrick .Case("avx512bitalg", true) 818e5dd7070Spatrick .Case("avx512bw", true) 819e5dd7070Spatrick .Case("avx512vl", true) 820e5dd7070Spatrick .Case("avx512vbmi", true) 821e5dd7070Spatrick .Case("avx512vbmi2", true) 822e5dd7070Spatrick .Case("avx512ifma", true) 823e5dd7070Spatrick .Case("avx512vp2intersect", true) 824e5dd7070Spatrick .Case("bmi", true) 825e5dd7070Spatrick .Case("bmi2", true) 826e5dd7070Spatrick .Case("cldemote", true) 827e5dd7070Spatrick .Case("clflushopt", true) 828e5dd7070Spatrick .Case("clwb", true) 829e5dd7070Spatrick .Case("clzero", true) 830e5dd7070Spatrick .Case("cx16", true) 831e5dd7070Spatrick .Case("enqcmd", true) 832e5dd7070Spatrick .Case("f16c", true) 833e5dd7070Spatrick .Case("fma", true) 834e5dd7070Spatrick .Case("fma4", true) 835e5dd7070Spatrick .Case("fsgsbase", true) 836e5dd7070Spatrick .Case("fxsr", true) 837e5dd7070Spatrick .Case("gfni", true) 838e5dd7070Spatrick .Case("invpcid", true) 839e5dd7070Spatrick .Case("lwp", true) 840e5dd7070Spatrick .Case("lzcnt", true) 841e5dd7070Spatrick .Case("mmx", true) 842e5dd7070Spatrick .Case("movbe", true) 843e5dd7070Spatrick .Case("movdiri", true) 844e5dd7070Spatrick .Case("movdir64b", true) 845e5dd7070Spatrick .Case("mwaitx", true) 846e5dd7070Spatrick .Case("pclmul", true) 847e5dd7070Spatrick .Case("pconfig", true) 848e5dd7070Spatrick .Case("pku", true) 849e5dd7070Spatrick .Case("popcnt", true) 850e5dd7070Spatrick .Case("prefetchwt1", true) 851e5dd7070Spatrick .Case("prfchw", true) 852e5dd7070Spatrick .Case("ptwrite", true) 853e5dd7070Spatrick .Case("rdpid", true) 854e5dd7070Spatrick .Case("rdrnd", true) 855e5dd7070Spatrick .Case("rdseed", true) 856e5dd7070Spatrick .Case("rtm", true) 857e5dd7070Spatrick .Case("sahf", true) 858*ec727ea7Spatrick .Case("serialize", true) 859e5dd7070Spatrick .Case("sgx", true) 860e5dd7070Spatrick .Case("sha", true) 861e5dd7070Spatrick .Case("shstk", true) 862e5dd7070Spatrick .Case("sse", true) 863e5dd7070Spatrick .Case("sse2", true) 864e5dd7070Spatrick .Case("sse3", true) 865e5dd7070Spatrick .Case("ssse3", true) 866e5dd7070Spatrick .Case("sse4", true) 867e5dd7070Spatrick .Case("sse4.1", true) 868e5dd7070Spatrick .Case("sse4.2", true) 869e5dd7070Spatrick .Case("sse4a", true) 870e5dd7070Spatrick .Case("tbm", true) 871*ec727ea7Spatrick .Case("tsxldtrk", true) 872e5dd7070Spatrick .Case("vaes", true) 873e5dd7070Spatrick .Case("vpclmulqdq", true) 874e5dd7070Spatrick .Case("wbnoinvd", true) 875e5dd7070Spatrick .Case("waitpkg", true) 876e5dd7070Spatrick .Case("x87", true) 877e5dd7070Spatrick .Case("xop", true) 878e5dd7070Spatrick .Case("xsave", true) 879e5dd7070Spatrick .Case("xsavec", true) 880e5dd7070Spatrick .Case("xsaves", true) 881e5dd7070Spatrick .Case("xsaveopt", true) 882e5dd7070Spatrick .Default(false); 883e5dd7070Spatrick } 884e5dd7070Spatrick 885e5dd7070Spatrick bool X86TargetInfo::hasFeature(StringRef Feature) const { 886e5dd7070Spatrick return llvm::StringSwitch<bool>(Feature) 887e5dd7070Spatrick .Case("adx", HasADX) 888e5dd7070Spatrick .Case("aes", HasAES) 889*ec727ea7Spatrick .Case("amx-bf16", HasAMXBF16) 890*ec727ea7Spatrick .Case("amx-int8", HasAMXINT8) 891*ec727ea7Spatrick .Case("amx-tile", HasAMXTILE) 892e5dd7070Spatrick .Case("avx", SSELevel >= AVX) 893e5dd7070Spatrick .Case("avx2", SSELevel >= AVX2) 894e5dd7070Spatrick .Case("avx512f", SSELevel >= AVX512F) 895e5dd7070Spatrick .Case("avx512cd", HasAVX512CD) 896e5dd7070Spatrick .Case("avx512vpopcntdq", HasAVX512VPOPCNTDQ) 897e5dd7070Spatrick .Case("avx512vnni", HasAVX512VNNI) 898e5dd7070Spatrick .Case("avx512bf16", HasAVX512BF16) 899e5dd7070Spatrick .Case("avx512er", HasAVX512ER) 900e5dd7070Spatrick .Case("avx512pf", HasAVX512PF) 901e5dd7070Spatrick .Case("avx512dq", HasAVX512DQ) 902e5dd7070Spatrick .Case("avx512bitalg", HasAVX512BITALG) 903e5dd7070Spatrick .Case("avx512bw", HasAVX512BW) 904e5dd7070Spatrick .Case("avx512vl", HasAVX512VL) 905e5dd7070Spatrick .Case("avx512vbmi", HasAVX512VBMI) 906e5dd7070Spatrick .Case("avx512vbmi2", HasAVX512VBMI2) 907e5dd7070Spatrick .Case("avx512ifma", HasAVX512IFMA) 908e5dd7070Spatrick .Case("avx512vp2intersect", HasAVX512VP2INTERSECT) 909e5dd7070Spatrick .Case("bmi", HasBMI) 910e5dd7070Spatrick .Case("bmi2", HasBMI2) 911e5dd7070Spatrick .Case("cldemote", HasCLDEMOTE) 912e5dd7070Spatrick .Case("clflushopt", HasCLFLUSHOPT) 913e5dd7070Spatrick .Case("clwb", HasCLWB) 914e5dd7070Spatrick .Case("clzero", HasCLZERO) 915e5dd7070Spatrick .Case("cx8", HasCX8) 916e5dd7070Spatrick .Case("cx16", HasCX16) 917e5dd7070Spatrick .Case("enqcmd", HasENQCMD) 918e5dd7070Spatrick .Case("f16c", HasF16C) 919e5dd7070Spatrick .Case("fma", HasFMA) 920e5dd7070Spatrick .Case("fma4", XOPLevel >= FMA4) 921e5dd7070Spatrick .Case("fsgsbase", HasFSGSBASE) 922e5dd7070Spatrick .Case("fxsr", HasFXSR) 923e5dd7070Spatrick .Case("gfni", HasGFNI) 924e5dd7070Spatrick .Case("invpcid", HasINVPCID) 925e5dd7070Spatrick .Case("lwp", HasLWP) 926e5dd7070Spatrick .Case("lzcnt", HasLZCNT) 927e5dd7070Spatrick .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow) 928e5dd7070Spatrick .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon) 929e5dd7070Spatrick .Case("mmx", MMX3DNowLevel >= MMX) 930e5dd7070Spatrick .Case("movbe", HasMOVBE) 931e5dd7070Spatrick .Case("movdiri", HasMOVDIRI) 932e5dd7070Spatrick .Case("movdir64b", HasMOVDIR64B) 933e5dd7070Spatrick .Case("mwaitx", HasMWAITX) 934e5dd7070Spatrick .Case("pclmul", HasPCLMUL) 935e5dd7070Spatrick .Case("pconfig", HasPCONFIG) 936e5dd7070Spatrick .Case("pku", HasPKU) 937e5dd7070Spatrick .Case("popcnt", HasPOPCNT) 938e5dd7070Spatrick .Case("prefetchwt1", HasPREFETCHWT1) 939e5dd7070Spatrick .Case("prfchw", HasPRFCHW) 940e5dd7070Spatrick .Case("ptwrite", HasPTWRITE) 941e5dd7070Spatrick .Case("rdpid", HasRDPID) 942e5dd7070Spatrick .Case("rdrnd", HasRDRND) 943e5dd7070Spatrick .Case("rdseed", HasRDSEED) 944e5dd7070Spatrick .Case("retpoline-external-thunk", HasRetpolineExternalThunk) 945e5dd7070Spatrick .Case("rtm", HasRTM) 946e5dd7070Spatrick .Case("sahf", HasLAHFSAHF) 947*ec727ea7Spatrick .Case("serialize", HasSERIALIZE) 948e5dd7070Spatrick .Case("sgx", HasSGX) 949e5dd7070Spatrick .Case("sha", HasSHA) 950e5dd7070Spatrick .Case("shstk", HasSHSTK) 951e5dd7070Spatrick .Case("sse", SSELevel >= SSE1) 952e5dd7070Spatrick .Case("sse2", SSELevel >= SSE2) 953e5dd7070Spatrick .Case("sse3", SSELevel >= SSE3) 954e5dd7070Spatrick .Case("ssse3", SSELevel >= SSSE3) 955e5dd7070Spatrick .Case("sse4.1", SSELevel >= SSE41) 956e5dd7070Spatrick .Case("sse4.2", SSELevel >= SSE42) 957e5dd7070Spatrick .Case("sse4a", XOPLevel >= SSE4A) 958e5dd7070Spatrick .Case("tbm", HasTBM) 959*ec727ea7Spatrick .Case("tsxldtrk", HasTSXLDTRK) 960e5dd7070Spatrick .Case("vaes", HasVAES) 961e5dd7070Spatrick .Case("vpclmulqdq", HasVPCLMULQDQ) 962e5dd7070Spatrick .Case("wbnoinvd", HasWBNOINVD) 963e5dd7070Spatrick .Case("waitpkg", HasWAITPKG) 964e5dd7070Spatrick .Case("x86", true) 965e5dd7070Spatrick .Case("x86_32", getTriple().getArch() == llvm::Triple::x86) 966e5dd7070Spatrick .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64) 967e5dd7070Spatrick .Case("xop", XOPLevel >= XOP) 968e5dd7070Spatrick .Case("xsave", HasXSAVE) 969e5dd7070Spatrick .Case("xsavec", HasXSAVEC) 970e5dd7070Spatrick .Case("xsaves", HasXSAVES) 971e5dd7070Spatrick .Case("xsaveopt", HasXSAVEOPT) 972e5dd7070Spatrick .Default(false); 973e5dd7070Spatrick } 974e5dd7070Spatrick 975e5dd7070Spatrick // We can't use a generic validation scheme for the features accepted here 976e5dd7070Spatrick // versus subtarget features accepted in the target attribute because the 977e5dd7070Spatrick // bitfield structure that's initialized in the runtime only supports the 978e5dd7070Spatrick // below currently rather than the full range of subtarget features. (See 979e5dd7070Spatrick // X86TargetInfo::hasFeature for a somewhat comprehensive list). 980e5dd7070Spatrick bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const { 981e5dd7070Spatrick return llvm::StringSwitch<bool>(FeatureStr) 982*ec727ea7Spatrick #define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, true) 983e5dd7070Spatrick #include "llvm/Support/X86TargetParser.def" 984e5dd7070Spatrick .Default(false); 985e5dd7070Spatrick } 986e5dd7070Spatrick 987e5dd7070Spatrick static llvm::X86::ProcessorFeatures getFeature(StringRef Name) { 988e5dd7070Spatrick return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name) 989*ec727ea7Spatrick #define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, llvm::X86::FEATURE_##ENUM) 990e5dd7070Spatrick #include "llvm/Support/X86TargetParser.def" 991e5dd7070Spatrick ; 992e5dd7070Spatrick // Note, this function should only be used after ensuring the value is 993e5dd7070Spatrick // correct, so it asserts if the value is out of range. 994e5dd7070Spatrick } 995e5dd7070Spatrick 996e5dd7070Spatrick static unsigned getFeaturePriority(llvm::X86::ProcessorFeatures Feat) { 997e5dd7070Spatrick enum class FeatPriority { 998e5dd7070Spatrick #define FEATURE(FEAT) FEAT, 999e5dd7070Spatrick #include "clang/Basic/X86Target.def" 1000e5dd7070Spatrick }; 1001e5dd7070Spatrick switch (Feat) { 1002e5dd7070Spatrick #define FEATURE(FEAT) \ 1003e5dd7070Spatrick case llvm::X86::FEAT: \ 1004e5dd7070Spatrick return static_cast<unsigned>(FeatPriority::FEAT); 1005e5dd7070Spatrick #include "clang/Basic/X86Target.def" 1006e5dd7070Spatrick default: 1007e5dd7070Spatrick llvm_unreachable("No Feature Priority for non-CPUSupports Features"); 1008e5dd7070Spatrick } 1009e5dd7070Spatrick } 1010e5dd7070Spatrick 1011e5dd7070Spatrick unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const { 1012e5dd7070Spatrick // Valid CPUs have a 'key feature' that compares just better than its key 1013e5dd7070Spatrick // feature. 1014*ec727ea7Spatrick using namespace llvm::X86; 1015*ec727ea7Spatrick CPUKind Kind = parseArchX86(Name); 1016*ec727ea7Spatrick if (Kind != CK_None) { 1017*ec727ea7Spatrick ProcessorFeatures KeyFeature = getKeyFeature(Kind); 1018*ec727ea7Spatrick return (getFeaturePriority(KeyFeature) << 1) + 1; 1019e5dd7070Spatrick } 1020e5dd7070Spatrick 1021e5dd7070Spatrick // Now we know we have a feature, so get its priority and shift it a few so 1022e5dd7070Spatrick // that we have sufficient room for the CPUs (above). 1023e5dd7070Spatrick return getFeaturePriority(getFeature(Name)) << 1; 1024e5dd7070Spatrick } 1025e5dd7070Spatrick 1026e5dd7070Spatrick bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const { 1027e5dd7070Spatrick return llvm::StringSwitch<bool>(Name) 1028e5dd7070Spatrick #define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, true) 1029e5dd7070Spatrick #define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, true) 1030e5dd7070Spatrick #include "clang/Basic/X86Target.def" 1031e5dd7070Spatrick .Default(false); 1032e5dd7070Spatrick } 1033e5dd7070Spatrick 1034e5dd7070Spatrick static StringRef CPUSpecificCPUDispatchNameDealias(StringRef Name) { 1035e5dd7070Spatrick return llvm::StringSwitch<StringRef>(Name) 1036e5dd7070Spatrick #define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, NAME) 1037e5dd7070Spatrick #include "clang/Basic/X86Target.def" 1038e5dd7070Spatrick .Default(Name); 1039e5dd7070Spatrick } 1040e5dd7070Spatrick 1041e5dd7070Spatrick char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const { 1042e5dd7070Spatrick return llvm::StringSwitch<char>(CPUSpecificCPUDispatchNameDealias(Name)) 1043e5dd7070Spatrick #define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, MANGLING) 1044e5dd7070Spatrick #include "clang/Basic/X86Target.def" 1045e5dd7070Spatrick .Default(0); 1046e5dd7070Spatrick } 1047e5dd7070Spatrick 1048e5dd7070Spatrick void X86TargetInfo::getCPUSpecificCPUDispatchFeatures( 1049e5dd7070Spatrick StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const { 1050e5dd7070Spatrick StringRef WholeList = 1051e5dd7070Spatrick llvm::StringSwitch<StringRef>(CPUSpecificCPUDispatchNameDealias(Name)) 1052e5dd7070Spatrick #define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, FEATURES) 1053e5dd7070Spatrick #include "clang/Basic/X86Target.def" 1054e5dd7070Spatrick .Default(""); 1055e5dd7070Spatrick WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false); 1056e5dd7070Spatrick } 1057e5dd7070Spatrick 1058e5dd7070Spatrick // We can't use a generic validation scheme for the cpus accepted here 1059e5dd7070Spatrick // versus subtarget cpus accepted in the target attribute because the 1060e5dd7070Spatrick // variables intitialized by the runtime only support the below currently 1061e5dd7070Spatrick // rather than the full range of cpus. 1062e5dd7070Spatrick bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const { 1063e5dd7070Spatrick return llvm::StringSwitch<bool>(FeatureStr) 1064e5dd7070Spatrick #define X86_VENDOR(ENUM, STRING) .Case(STRING, true) 1065*ec727ea7Spatrick #define X86_CPU_TYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true) 1066*ec727ea7Spatrick #define X86_CPU_TYPE(ENUM, STR) .Case(STR, true) 1067*ec727ea7Spatrick #define X86_CPU_SUBTYPE(ENUM, STR) .Case(STR, true) 1068e5dd7070Spatrick #include "llvm/Support/X86TargetParser.def" 1069e5dd7070Spatrick .Default(false); 1070e5dd7070Spatrick } 1071e5dd7070Spatrick 1072e5dd7070Spatrick static unsigned matchAsmCCConstraint(const char *&Name) { 1073e5dd7070Spatrick auto RV = llvm::StringSwitch<unsigned>(Name) 1074e5dd7070Spatrick .Case("@cca", 4) 1075e5dd7070Spatrick .Case("@ccae", 5) 1076e5dd7070Spatrick .Case("@ccb", 4) 1077e5dd7070Spatrick .Case("@ccbe", 5) 1078e5dd7070Spatrick .Case("@ccc", 4) 1079e5dd7070Spatrick .Case("@cce", 4) 1080e5dd7070Spatrick .Case("@ccz", 4) 1081e5dd7070Spatrick .Case("@ccg", 4) 1082e5dd7070Spatrick .Case("@ccge", 5) 1083e5dd7070Spatrick .Case("@ccl", 4) 1084e5dd7070Spatrick .Case("@ccle", 5) 1085e5dd7070Spatrick .Case("@ccna", 5) 1086e5dd7070Spatrick .Case("@ccnae", 6) 1087e5dd7070Spatrick .Case("@ccnb", 5) 1088e5dd7070Spatrick .Case("@ccnbe", 6) 1089e5dd7070Spatrick .Case("@ccnc", 5) 1090e5dd7070Spatrick .Case("@ccne", 5) 1091e5dd7070Spatrick .Case("@ccnz", 5) 1092e5dd7070Spatrick .Case("@ccng", 5) 1093e5dd7070Spatrick .Case("@ccnge", 6) 1094e5dd7070Spatrick .Case("@ccnl", 5) 1095e5dd7070Spatrick .Case("@ccnle", 6) 1096e5dd7070Spatrick .Case("@ccno", 5) 1097e5dd7070Spatrick .Case("@ccnp", 5) 1098e5dd7070Spatrick .Case("@ccns", 5) 1099e5dd7070Spatrick .Case("@cco", 4) 1100e5dd7070Spatrick .Case("@ccp", 4) 1101e5dd7070Spatrick .Case("@ccs", 4) 1102e5dd7070Spatrick .Default(0); 1103e5dd7070Spatrick return RV; 1104e5dd7070Spatrick } 1105e5dd7070Spatrick 1106e5dd7070Spatrick bool X86TargetInfo::validateAsmConstraint( 1107e5dd7070Spatrick const char *&Name, TargetInfo::ConstraintInfo &Info) const { 1108e5dd7070Spatrick switch (*Name) { 1109e5dd7070Spatrick default: 1110e5dd7070Spatrick return false; 1111e5dd7070Spatrick // Constant constraints. 1112e5dd7070Spatrick case 'e': // 32-bit signed integer constant for use with sign-extending x86_64 1113e5dd7070Spatrick // instructions. 1114e5dd7070Spatrick case 'Z': // 32-bit unsigned integer constant for use with zero-extending 1115e5dd7070Spatrick // x86_64 instructions. 1116e5dd7070Spatrick case 's': 1117e5dd7070Spatrick Info.setRequiresImmediate(); 1118e5dd7070Spatrick return true; 1119e5dd7070Spatrick case 'I': 1120e5dd7070Spatrick Info.setRequiresImmediate(0, 31); 1121e5dd7070Spatrick return true; 1122e5dd7070Spatrick case 'J': 1123e5dd7070Spatrick Info.setRequiresImmediate(0, 63); 1124e5dd7070Spatrick return true; 1125e5dd7070Spatrick case 'K': 1126e5dd7070Spatrick Info.setRequiresImmediate(-128, 127); 1127e5dd7070Spatrick return true; 1128e5dd7070Spatrick case 'L': 1129e5dd7070Spatrick Info.setRequiresImmediate({int(0xff), int(0xffff), int(0xffffffff)}); 1130e5dd7070Spatrick return true; 1131e5dd7070Spatrick case 'M': 1132e5dd7070Spatrick Info.setRequiresImmediate(0, 3); 1133e5dd7070Spatrick return true; 1134e5dd7070Spatrick case 'N': 1135e5dd7070Spatrick Info.setRequiresImmediate(0, 255); 1136e5dd7070Spatrick return true; 1137e5dd7070Spatrick case 'O': 1138e5dd7070Spatrick Info.setRequiresImmediate(0, 127); 1139e5dd7070Spatrick return true; 1140e5dd7070Spatrick // Register constraints. 1141e5dd7070Spatrick case 'Y': // 'Y' is the first character for several 2-character constraints. 1142e5dd7070Spatrick // Shift the pointer to the second character of the constraint. 1143e5dd7070Spatrick Name++; 1144e5dd7070Spatrick switch (*Name) { 1145e5dd7070Spatrick default: 1146e5dd7070Spatrick return false; 1147*ec727ea7Spatrick case 'z': // First SSE register. 1148e5dd7070Spatrick case '2': 1149e5dd7070Spatrick case 't': // Any SSE register, when SSE2 is enabled. 1150e5dd7070Spatrick case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled. 1151e5dd7070Spatrick case 'm': // Any MMX register, when inter-unit moves enabled. 1152e5dd7070Spatrick case 'k': // AVX512 arch mask registers: k1-k7. 1153e5dd7070Spatrick Info.setAllowsRegister(); 1154e5dd7070Spatrick return true; 1155e5dd7070Spatrick } 1156e5dd7070Spatrick case 'f': // Any x87 floating point stack register. 1157e5dd7070Spatrick // Constraint 'f' cannot be used for output operands. 1158e5dd7070Spatrick if (Info.ConstraintStr[0] == '=') 1159e5dd7070Spatrick return false; 1160e5dd7070Spatrick Info.setAllowsRegister(); 1161e5dd7070Spatrick return true; 1162e5dd7070Spatrick case 'a': // eax. 1163e5dd7070Spatrick case 'b': // ebx. 1164e5dd7070Spatrick case 'c': // ecx. 1165e5dd7070Spatrick case 'd': // edx. 1166e5dd7070Spatrick case 'S': // esi. 1167e5dd7070Spatrick case 'D': // edi. 1168e5dd7070Spatrick case 'A': // edx:eax. 1169e5dd7070Spatrick case 't': // Top of floating point stack. 1170e5dd7070Spatrick case 'u': // Second from top of floating point stack. 1171e5dd7070Spatrick case 'q': // Any register accessible as [r]l: a, b, c, and d. 1172e5dd7070Spatrick case 'y': // Any MMX register. 1173e5dd7070Spatrick case 'v': // Any {X,Y,Z}MM register (Arch & context dependent) 1174e5dd7070Spatrick case 'x': // Any SSE register. 1175e5dd7070Spatrick case 'k': // Any AVX512 mask register (same as Yk, additionally allows k0 1176e5dd7070Spatrick // for intermideate k reg operations). 1177e5dd7070Spatrick case 'Q': // Any register accessible as [r]h: a, b, c, and d. 1178e5dd7070Spatrick case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp. 1179e5dd7070Spatrick case 'l': // "Index" registers: any general register that can be used as an 1180e5dd7070Spatrick // index in a base+index memory access. 1181e5dd7070Spatrick Info.setAllowsRegister(); 1182e5dd7070Spatrick return true; 1183e5dd7070Spatrick // Floating point constant constraints. 1184e5dd7070Spatrick case 'C': // SSE floating point constant. 1185e5dd7070Spatrick case 'G': // x87 floating point constant. 1186e5dd7070Spatrick return true; 1187e5dd7070Spatrick case '@': 1188e5dd7070Spatrick // CC condition changes. 1189e5dd7070Spatrick if (auto Len = matchAsmCCConstraint(Name)) { 1190e5dd7070Spatrick Name += Len - 1; 1191e5dd7070Spatrick Info.setAllowsRegister(); 1192e5dd7070Spatrick return true; 1193e5dd7070Spatrick } 1194e5dd7070Spatrick return false; 1195e5dd7070Spatrick } 1196e5dd7070Spatrick } 1197e5dd7070Spatrick 1198*ec727ea7Spatrick // Below is based on the following information: 1199*ec727ea7Spatrick // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1200*ec727ea7Spatrick // | Processor Name | Cache Line Size (Bytes) | Source | 1201*ec727ea7Spatrick // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1202*ec727ea7Spatrick // | i386 | 64 | https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf | 1203*ec727ea7Spatrick // | i486 | 16 | "four doublewords" (doubleword = 32 bits, 4 bits * 32 bits = 16 bytes) https://en.wikichip.org/w/images/d/d3/i486_MICROPROCESSOR_HARDWARE_REFERENCE_MANUAL_%281990%29.pdf and http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.126.4216&rep=rep1&type=pdf (page 29) | 1204*ec727ea7Spatrick // | i586/Pentium MMX | 32 | https://www.7-cpu.com/cpu/P-MMX.html | 1205*ec727ea7Spatrick // | i686/Pentium | 32 | https://www.7-cpu.com/cpu/P6.html | 1206*ec727ea7Spatrick // | Netburst/Pentium4 | 64 | https://www.7-cpu.com/cpu/P4-180.html | 1207*ec727ea7Spatrick // | Atom | 64 | https://www.7-cpu.com/cpu/Atom.html | 1208*ec727ea7Spatrick // | Westmere | 64 | https://en.wikichip.org/wiki/intel/microarchitectures/sandy_bridge_(client) "Cache Architecture" | 1209*ec727ea7Spatrick // | Sandy Bridge | 64 | https://en.wikipedia.org/wiki/Sandy_Bridge and https://www.7-cpu.com/cpu/SandyBridge.html | 1210*ec727ea7Spatrick // | Ivy Bridge | 64 | https://blog.stuffedcow.net/2013/01/ivb-cache-replacement/ and https://www.7-cpu.com/cpu/IvyBridge.html | 1211*ec727ea7Spatrick // | Haswell | 64 | https://www.7-cpu.com/cpu/Haswell.html | 1212*ec727ea7Spatrick // | Boadwell | 64 | https://www.7-cpu.com/cpu/Broadwell.html | 1213*ec727ea7Spatrick // | Skylake (including skylake-avx512) | 64 | https://www.nas.nasa.gov/hecc/support/kb/skylake-processors_550.html "Cache Hierarchy" | 1214*ec727ea7Spatrick // | Cascade Lake | 64 | https://www.nas.nasa.gov/hecc/support/kb/cascade-lake-processors_579.html "Cache Hierarchy" | 1215*ec727ea7Spatrick // | Skylake | 64 | https://en.wikichip.org/wiki/intel/microarchitectures/kaby_lake "Memory Hierarchy" | 1216*ec727ea7Spatrick // | Ice Lake | 64 | https://www.7-cpu.com/cpu/Ice_Lake.html | 1217*ec727ea7Spatrick // | Knights Landing | 64 | https://software.intel.com/en-us/articles/intel-xeon-phi-processor-7200-family-memory-management-optimizations "The Intel® Xeon Phi™ Processor Architecture" | 1218*ec727ea7Spatrick // | Knights Mill | 64 | https://software.intel.com/sites/default/files/managed/9e/bc/64-ia-32-architectures-optimization-manual.pdf?countrylabel=Colombia "2.5.5.2 L1 DCache " | 1219*ec727ea7Spatrick // +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1220*ec727ea7Spatrick Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const { 1221*ec727ea7Spatrick using namespace llvm::X86; 1222*ec727ea7Spatrick switch (CPU) { 1223*ec727ea7Spatrick // i386 1224*ec727ea7Spatrick case CK_i386: 1225*ec727ea7Spatrick // i486 1226*ec727ea7Spatrick case CK_i486: 1227*ec727ea7Spatrick case CK_WinChipC6: 1228*ec727ea7Spatrick case CK_WinChip2: 1229*ec727ea7Spatrick case CK_C3: 1230*ec727ea7Spatrick // Lakemont 1231*ec727ea7Spatrick case CK_Lakemont: 1232*ec727ea7Spatrick return 16; 1233*ec727ea7Spatrick 1234*ec727ea7Spatrick // i586 1235*ec727ea7Spatrick case CK_i586: 1236*ec727ea7Spatrick case CK_Pentium: 1237*ec727ea7Spatrick case CK_PentiumMMX: 1238*ec727ea7Spatrick // i686 1239*ec727ea7Spatrick case CK_PentiumPro: 1240*ec727ea7Spatrick case CK_i686: 1241*ec727ea7Spatrick case CK_Pentium2: 1242*ec727ea7Spatrick case CK_Pentium3: 1243*ec727ea7Spatrick case CK_PentiumM: 1244*ec727ea7Spatrick case CK_C3_2: 1245*ec727ea7Spatrick // K6 1246*ec727ea7Spatrick case CK_K6: 1247*ec727ea7Spatrick case CK_K6_2: 1248*ec727ea7Spatrick case CK_K6_3: 1249*ec727ea7Spatrick // Geode 1250*ec727ea7Spatrick case CK_Geode: 1251*ec727ea7Spatrick return 32; 1252*ec727ea7Spatrick 1253*ec727ea7Spatrick // Netburst 1254*ec727ea7Spatrick case CK_Pentium4: 1255*ec727ea7Spatrick case CK_Prescott: 1256*ec727ea7Spatrick case CK_Nocona: 1257*ec727ea7Spatrick // Atom 1258*ec727ea7Spatrick case CK_Bonnell: 1259*ec727ea7Spatrick case CK_Silvermont: 1260*ec727ea7Spatrick case CK_Goldmont: 1261*ec727ea7Spatrick case CK_GoldmontPlus: 1262*ec727ea7Spatrick case CK_Tremont: 1263*ec727ea7Spatrick 1264*ec727ea7Spatrick case CK_Westmere: 1265*ec727ea7Spatrick case CK_SandyBridge: 1266*ec727ea7Spatrick case CK_IvyBridge: 1267*ec727ea7Spatrick case CK_Haswell: 1268*ec727ea7Spatrick case CK_Broadwell: 1269*ec727ea7Spatrick case CK_SkylakeClient: 1270*ec727ea7Spatrick case CK_SkylakeServer: 1271*ec727ea7Spatrick case CK_Cascadelake: 1272*ec727ea7Spatrick case CK_Nehalem: 1273*ec727ea7Spatrick case CK_Cooperlake: 1274*ec727ea7Spatrick case CK_Cannonlake: 1275*ec727ea7Spatrick case CK_Tigerlake: 1276*ec727ea7Spatrick case CK_IcelakeClient: 1277*ec727ea7Spatrick case CK_IcelakeServer: 1278*ec727ea7Spatrick case CK_KNL: 1279*ec727ea7Spatrick case CK_KNM: 1280*ec727ea7Spatrick // K7 1281*ec727ea7Spatrick case CK_Athlon: 1282*ec727ea7Spatrick case CK_AthlonXP: 1283*ec727ea7Spatrick // K8 1284*ec727ea7Spatrick case CK_K8: 1285*ec727ea7Spatrick case CK_K8SSE3: 1286*ec727ea7Spatrick case CK_AMDFAM10: 1287*ec727ea7Spatrick // Bobcat 1288*ec727ea7Spatrick case CK_BTVER1: 1289*ec727ea7Spatrick case CK_BTVER2: 1290*ec727ea7Spatrick // Bulldozer 1291*ec727ea7Spatrick case CK_BDVER1: 1292*ec727ea7Spatrick case CK_BDVER2: 1293*ec727ea7Spatrick case CK_BDVER3: 1294*ec727ea7Spatrick case CK_BDVER4: 1295*ec727ea7Spatrick // Zen 1296*ec727ea7Spatrick case CK_ZNVER1: 1297*ec727ea7Spatrick case CK_ZNVER2: 1298*ec727ea7Spatrick // Deprecated 1299*ec727ea7Spatrick case CK_x86_64: 1300*ec727ea7Spatrick case CK_Yonah: 1301*ec727ea7Spatrick case CK_Penryn: 1302*ec727ea7Spatrick case CK_Core2: 1303*ec727ea7Spatrick return 64; 1304*ec727ea7Spatrick 1305*ec727ea7Spatrick // The following currently have unknown cache line sizes (but they are probably all 64): 1306*ec727ea7Spatrick // Core 1307*ec727ea7Spatrick case CK_None: 1308*ec727ea7Spatrick return None; 1309*ec727ea7Spatrick } 1310*ec727ea7Spatrick llvm_unreachable("Unknown CPU kind"); 1311*ec727ea7Spatrick } 1312*ec727ea7Spatrick 1313e5dd7070Spatrick bool X86TargetInfo::validateOutputSize(const llvm::StringMap<bool> &FeatureMap, 1314e5dd7070Spatrick StringRef Constraint, 1315e5dd7070Spatrick unsigned Size) const { 1316e5dd7070Spatrick // Strip off constraint modifiers. 1317e5dd7070Spatrick while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&') 1318e5dd7070Spatrick Constraint = Constraint.substr(1); 1319e5dd7070Spatrick 1320e5dd7070Spatrick return validateOperandSize(FeatureMap, Constraint, Size); 1321e5dd7070Spatrick } 1322e5dd7070Spatrick 1323e5dd7070Spatrick bool X86TargetInfo::validateInputSize(const llvm::StringMap<bool> &FeatureMap, 1324e5dd7070Spatrick StringRef Constraint, 1325e5dd7070Spatrick unsigned Size) const { 1326e5dd7070Spatrick return validateOperandSize(FeatureMap, Constraint, Size); 1327e5dd7070Spatrick } 1328e5dd7070Spatrick 1329e5dd7070Spatrick bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap, 1330e5dd7070Spatrick StringRef Constraint, 1331e5dd7070Spatrick unsigned Size) const { 1332e5dd7070Spatrick switch (Constraint[0]) { 1333e5dd7070Spatrick default: 1334e5dd7070Spatrick break; 1335e5dd7070Spatrick case 'k': 1336e5dd7070Spatrick // Registers k0-k7 (AVX512) size limit is 64 bit. 1337e5dd7070Spatrick case 'y': 1338e5dd7070Spatrick return Size <= 64; 1339e5dd7070Spatrick case 'f': 1340e5dd7070Spatrick case 't': 1341e5dd7070Spatrick case 'u': 1342e5dd7070Spatrick return Size <= 128; 1343e5dd7070Spatrick case 'Y': 1344e5dd7070Spatrick // 'Y' is the first character for several 2-character constraints. 1345e5dd7070Spatrick switch (Constraint[1]) { 1346e5dd7070Spatrick default: 1347e5dd7070Spatrick return false; 1348e5dd7070Spatrick case 'm': 1349e5dd7070Spatrick // 'Ym' is synonymous with 'y'. 1350e5dd7070Spatrick case 'k': 1351e5dd7070Spatrick return Size <= 64; 1352e5dd7070Spatrick case 'z': 1353*ec727ea7Spatrick // XMM0/YMM/ZMM0 1354*ec727ea7Spatrick if (FeatureMap.lookup("avx512f")) 1355*ec727ea7Spatrick // ZMM0 can be used if target supports AVX512F. 1356*ec727ea7Spatrick return Size <= 512U; 1357*ec727ea7Spatrick else if (FeatureMap.lookup("avx")) 1358*ec727ea7Spatrick // YMM0 can be used if target supports AVX. 1359*ec727ea7Spatrick return Size <= 256U; 1360*ec727ea7Spatrick else if (FeatureMap.lookup("sse")) 1361e5dd7070Spatrick return Size <= 128U; 1362e5dd7070Spatrick return false; 1363e5dd7070Spatrick case 'i': 1364e5dd7070Spatrick case 't': 1365e5dd7070Spatrick case '2': 1366e5dd7070Spatrick // 'Yi','Yt','Y2' are synonymous with 'x' when SSE2 is enabled. 1367e5dd7070Spatrick if (SSELevel < SSE2) 1368e5dd7070Spatrick return false; 1369e5dd7070Spatrick break; 1370e5dd7070Spatrick } 1371*ec727ea7Spatrick break; 1372e5dd7070Spatrick case 'v': 1373e5dd7070Spatrick case 'x': 1374e5dd7070Spatrick if (FeatureMap.lookup("avx512f")) 1375e5dd7070Spatrick // 512-bit zmm registers can be used if target supports AVX512F. 1376e5dd7070Spatrick return Size <= 512U; 1377e5dd7070Spatrick else if (FeatureMap.lookup("avx")) 1378e5dd7070Spatrick // 256-bit ymm registers can be used if target supports AVX. 1379e5dd7070Spatrick return Size <= 256U; 1380e5dd7070Spatrick return Size <= 128U; 1381e5dd7070Spatrick 1382e5dd7070Spatrick } 1383e5dd7070Spatrick 1384e5dd7070Spatrick return true; 1385e5dd7070Spatrick } 1386e5dd7070Spatrick 1387e5dd7070Spatrick std::string X86TargetInfo::convertConstraint(const char *&Constraint) const { 1388e5dd7070Spatrick switch (*Constraint) { 1389e5dd7070Spatrick case '@': 1390e5dd7070Spatrick if (auto Len = matchAsmCCConstraint(Constraint)) { 1391e5dd7070Spatrick std::string Converted = "{" + std::string(Constraint, Len) + "}"; 1392e5dd7070Spatrick Constraint += Len - 1; 1393e5dd7070Spatrick return Converted; 1394e5dd7070Spatrick } 1395e5dd7070Spatrick return std::string(1, *Constraint); 1396e5dd7070Spatrick case 'a': 1397e5dd7070Spatrick return std::string("{ax}"); 1398e5dd7070Spatrick case 'b': 1399e5dd7070Spatrick return std::string("{bx}"); 1400e5dd7070Spatrick case 'c': 1401e5dd7070Spatrick return std::string("{cx}"); 1402e5dd7070Spatrick case 'd': 1403e5dd7070Spatrick return std::string("{dx}"); 1404e5dd7070Spatrick case 'S': 1405e5dd7070Spatrick return std::string("{si}"); 1406e5dd7070Spatrick case 'D': 1407e5dd7070Spatrick return std::string("{di}"); 1408e5dd7070Spatrick case 'p': // address 1409e5dd7070Spatrick return std::string("im"); 1410e5dd7070Spatrick case 't': // top of floating point stack. 1411e5dd7070Spatrick return std::string("{st}"); 1412e5dd7070Spatrick case 'u': // second from top of floating point stack. 1413e5dd7070Spatrick return std::string("{st(1)}"); // second from top of floating point stack. 1414e5dd7070Spatrick case 'Y': 1415e5dd7070Spatrick switch (Constraint[1]) { 1416e5dd7070Spatrick default: 1417e5dd7070Spatrick // Break from inner switch and fall through (copy single char), 1418e5dd7070Spatrick // continue parsing after copying the current constraint into 1419e5dd7070Spatrick // the return string. 1420e5dd7070Spatrick break; 1421e5dd7070Spatrick case 'k': 1422e5dd7070Spatrick case 'm': 1423e5dd7070Spatrick case 'i': 1424e5dd7070Spatrick case 't': 1425e5dd7070Spatrick case 'z': 1426e5dd7070Spatrick case '2': 1427e5dd7070Spatrick // "^" hints llvm that this is a 2 letter constraint. 1428e5dd7070Spatrick // "Constraint++" is used to promote the string iterator 1429e5dd7070Spatrick // to the next constraint. 1430e5dd7070Spatrick return std::string("^") + std::string(Constraint++, 2); 1431e5dd7070Spatrick } 1432e5dd7070Spatrick LLVM_FALLTHROUGH; 1433e5dd7070Spatrick default: 1434e5dd7070Spatrick return std::string(1, *Constraint); 1435e5dd7070Spatrick } 1436e5dd7070Spatrick } 1437e5dd7070Spatrick 1438e5dd7070Spatrick void X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { 1439*ec727ea7Spatrick bool Only64Bit = getTriple().getArch() != llvm::Triple::x86; 1440*ec727ea7Spatrick llvm::X86::fillValidCPUArchList(Values, Only64Bit); 1441e5dd7070Spatrick } 1442e5dd7070Spatrick 1443e5dd7070Spatrick ArrayRef<const char *> X86TargetInfo::getGCCRegNames() const { 1444e5dd7070Spatrick return llvm::makeArrayRef(GCCRegNames); 1445e5dd7070Spatrick } 1446e5dd7070Spatrick 1447e5dd7070Spatrick ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const { 1448e5dd7070Spatrick return llvm::makeArrayRef(AddlRegNames); 1449e5dd7070Spatrick } 1450e5dd7070Spatrick 1451e5dd7070Spatrick ArrayRef<Builtin::Info> X86_32TargetInfo::getTargetBuiltins() const { 1452e5dd7070Spatrick return llvm::makeArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin - 1453e5dd7070Spatrick Builtin::FirstTSBuiltin + 1); 1454e5dd7070Spatrick } 1455e5dd7070Spatrick 1456e5dd7070Spatrick ArrayRef<Builtin::Info> X86_64TargetInfo::getTargetBuiltins() const { 1457e5dd7070Spatrick return llvm::makeArrayRef(BuiltinInfoX86, 1458e5dd7070Spatrick X86::LastTSBuiltin - Builtin::FirstTSBuiltin); 1459e5dd7070Spatrick } 1460