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