diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic/Targets/X86.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Targets/X86.cpp | 202 | 
1 files changed, 190 insertions, 12 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/X86.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/X86.cpp index 8251e6abd649..7ae0696ce7e7 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/X86.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/X86.cpp @@ -15,8 +15,10 @@  #include "clang/Basic/Builtins.h"  #include "clang/Basic/Diagnostic.h"  #include "clang/Basic/TargetBuiltins.h" +#include "llvm/ADT/StringExtras.h"  #include "llvm/ADT/StringRef.h"  #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/TargetParser.h"  namespace clang {  namespace targets { @@ -131,7 +133,11 @@ bool X86TargetInfo::initFeatureMap(      setFeatureEnabledImpl(Features, "mmx", true);      break; -  case CK_Icelake: +  case CK_IcelakeServer: +    setFeatureEnabledImpl(Features, "pconfig", true); +    setFeatureEnabledImpl(Features, "wbnoinvd", true); +    LLVM_FALLTHROUGH; +  case CK_IcelakeClient:      setFeatureEnabledImpl(Features, "vaes", true);      setFeatureEnabledImpl(Features, "gfni", true);      setFeatureEnabledImpl(Features, "vpclmulqdq", true); @@ -139,6 +145,7 @@ bool X86TargetInfo::initFeatureMap(      setFeatureEnabledImpl(Features, "avx512vnni", true);      setFeatureEnabledImpl(Features, "avx512vbmi2", true);      setFeatureEnabledImpl(Features, "avx512vpopcntdq", true); +    setFeatureEnabledImpl(Features, "rdpid", true);      LLVM_FALLTHROUGH;    case CK_Cannonlake:      setFeatureEnabledImpl(Features, "avx512ifma", true); @@ -159,7 +166,8 @@ bool X86TargetInfo::initFeatureMap(      setFeatureEnabledImpl(Features, "xsavec", true);      setFeatureEnabledImpl(Features, "xsaves", true);      setFeatureEnabledImpl(Features, "mpx", true); -    setFeatureEnabledImpl(Features, "sgx", true); +    if (Kind != CK_SkylakeServer) // SKX inherits all SKL features, except SGX +      setFeatureEnabledImpl(Features, "sgx", true);      setFeatureEnabledImpl(Features, "clflushopt", true);      setFeatureEnabledImpl(Features, "rtm", true);      LLVM_FALLTHROUGH; @@ -174,6 +182,7 @@ bool X86TargetInfo::initFeatureMap(      setFeatureEnabledImpl(Features, "bmi", true);      setFeatureEnabledImpl(Features, "bmi2", true);      setFeatureEnabledImpl(Features, "fma", true); +    setFeatureEnabledImpl(Features, "invpcid", true);      setFeatureEnabledImpl(Features, "movbe", true);      LLVM_FALLTHROUGH;    case CK_IvyBridge: @@ -217,9 +226,20 @@ bool X86TargetInfo::initFeatureMap(      setFeatureEnabledImpl(Features, "fxsr", true);      break; +  case CK_Tremont: +    setFeatureEnabledImpl(Features, "cldemote", true); +    setFeatureEnabledImpl(Features, "movdiri", true); +    setFeatureEnabledImpl(Features, "movdir64b", true); +    setFeatureEnabledImpl(Features, "gfni", true); +    setFeatureEnabledImpl(Features, "waitpkg", true); +    LLVM_FALLTHROUGH; +  case CK_GoldmontPlus: +    setFeatureEnabledImpl(Features, "ptwrite", true); +    setFeatureEnabledImpl(Features, "rdpid", true); +    setFeatureEnabledImpl(Features, "sgx", true); +    LLVM_FALLTHROUGH;    case CK_Goldmont:      setFeatureEnabledImpl(Features, "sha", true); -    setFeatureEnabledImpl(Features, "rdrnd", true);      setFeatureEnabledImpl(Features, "rdseed", true);      setFeatureEnabledImpl(Features, "xsave", true);      setFeatureEnabledImpl(Features, "xsaveopt", true); @@ -230,6 +250,7 @@ bool X86TargetInfo::initFeatureMap(      setFeatureEnabledImpl(Features, "fsgsbase", true);      LLVM_FALLTHROUGH;    case CK_Silvermont: +    setFeatureEnabledImpl(Features, "rdrnd", true);      setFeatureEnabledImpl(Features, "aes", true);      setFeatureEnabledImpl(Features, "pclmul", true);      setFeatureEnabledImpl(Features, "sse4.2", true); @@ -741,8 +762,6 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,        HasMPX = true;      } else if (Feature == "+shstk") {        HasSHSTK = true; -    } else if (Feature == "+ibt") { -      HasIBT = true;      } else if (Feature == "+movbe") {        HasMOVBE = true;      } else if (Feature == "+sgx") { @@ -767,16 +786,34 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,        HasCLFLUSHOPT = true;      } else if (Feature == "+clwb") {        HasCLWB = true; +    } else if (Feature == "+wbnoinvd") { +      HasWBNOINVD = true;      } else if (Feature == "+prefetchwt1") {        HasPREFETCHWT1 = true;      } else if (Feature == "+clzero") {        HasCLZERO = true; +    } else if (Feature == "+cldemote") { +      HasCLDEMOTE = true; +    } else if (Feature == "+rdpid") { +      HasRDPID = true;      } else if (Feature == "+retpoline") {        HasRetpoline = true;      } else if (Feature == "+retpoline-external-thunk") {        HasRetpolineExternalThunk = true;      } else if (Feature == "+sahf") {        HasLAHFSAHF = true; +    } else if (Feature == "+waitpkg") { +      HasWAITPKG = true; +    } else if (Feature == "+movdiri") { +      HasMOVDIRI = true; +    } else if (Feature == "+movdir64b") { +      HasMOVDIR64B = true; +    } else if (Feature == "+pconfig") { +      HasPCONFIG = true; +    } else if (Feature == "+ptwrite") { +      HasPTWRITE = true; +    } else if (Feature == "+invpcid") { +      HasINVPCID = true;      }      X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) @@ -897,6 +934,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,    case CK_Goldmont:      defineCPUMacros(Builder, "goldmont");      break; +  case CK_GoldmontPlus: +    defineCPUMacros(Builder, "goldmont_plus"); +    break; +  case CK_Tremont: +    defineCPUMacros(Builder, "tremont"); +    break;    case CK_Nehalem:    case CK_Westmere:    case CK_SandyBridge: @@ -906,7 +949,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,    case CK_SkylakeClient:    case CK_SkylakeServer:    case CK_Cannonlake: -  case CK_Icelake: +  case CK_IcelakeClient: +  case CK_IcelakeServer:      // FIXME: Historically, we defined this legacy name, it would be nice to      // remove it at some point. We've never exposed fine-grained names for      // recent primary x86 CPUs, and we should keep it that way. @@ -1102,12 +1146,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,      Builder.defineMacro("__XSAVES__");    if (HasPKU)      Builder.defineMacro("__PKU__"); -  if (HasCX16) -    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");    if (HasCLFLUSHOPT)      Builder.defineMacro("__CLFLUSHOPT__");    if (HasCLWB)      Builder.defineMacro("__CLWB__"); +  if (HasWBNOINVD) +    Builder.defineMacro("__WBNOINVD__");    if (HasMPX)      Builder.defineMacro("__MPX__");    if (HasSHSTK) @@ -1118,6 +1162,22 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,      Builder.defineMacro("__PREFETCHWT1__");    if (HasCLZERO)      Builder.defineMacro("__CLZERO__"); +  if (HasRDPID) +    Builder.defineMacro("__RDPID__"); +  if (HasCLDEMOTE) +    Builder.defineMacro("__CLDEMOTE__"); +  if (HasWAITPKG) +    Builder.defineMacro("__WAITPKG__"); +  if (HasMOVDIRI) +    Builder.defineMacro("__MOVDIRI__"); +  if (HasMOVDIR64B) +    Builder.defineMacro("__MOVDIR64B__"); +  if (HasPCONFIG) +    Builder.defineMacro("__PCONFIG__"); +  if (HasPTWRITE) +    Builder.defineMacro("__PTWRITE__"); +  if (HasINVPCID) +    Builder.defineMacro("__INVPCID__");    // Each case falls through to the previous one here.    switch (SSELevel) { @@ -1197,6 +1257,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,    }    if (CPU >= CK_i586)      Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); +  if (HasCX16) +    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");    if (HasFloat128)      Builder.defineMacro("__SIZEOF_FLOAT128__", "16"); @@ -1225,6 +1287,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {        .Case("avx512ifma", true)        .Case("bmi", true)        .Case("bmi2", true) +      .Case("cldemote", true)        .Case("clflushopt", true)        .Case("clwb", true)        .Case("clzero", true) @@ -1235,17 +1298,23 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {        .Case("fsgsbase", true)        .Case("fxsr", true)        .Case("gfni", true) +      .Case("invpcid", true)        .Case("lwp", true)        .Case("lzcnt", true)        .Case("mmx", true)        .Case("movbe", true) +      .Case("movdiri", true) +      .Case("movdir64b", true)        .Case("mpx", true)        .Case("mwaitx", true)        .Case("pclmul", true) +      .Case("pconfig", true)        .Case("pku", true)        .Case("popcnt", true)        .Case("prefetchwt1", true)        .Case("prfchw", true) +      .Case("ptwrite", true) +      .Case("rdpid", true)        .Case("rdrnd", true)        .Case("rdseed", true)        .Case("rtm", true) @@ -1264,6 +1333,8 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {        .Case("tbm", true)        .Case("vaes", true)        .Case("vpclmulqdq", true) +      .Case("wbnoinvd", true) +      .Case("waitpkg", true)        .Case("x87", true)        .Case("xop", true)        .Case("xsave", true) @@ -1294,6 +1365,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {        .Case("avx512ifma", HasAVX512IFMA)        .Case("bmi", HasBMI)        .Case("bmi2", HasBMI2) +      .Case("cldemote", HasCLDEMOTE)        .Case("clflushopt", HasCLFLUSHOPT)        .Case("clwb", HasCLWB)        .Case("clzero", HasCLZERO) @@ -1304,20 +1376,25 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {        .Case("fsgsbase", HasFSGSBASE)        .Case("fxsr", HasFXSR)        .Case("gfni", HasGFNI) -      .Case("ibt", HasIBT) +      .Case("invpcid", HasINVPCID)        .Case("lwp", HasLWP)        .Case("lzcnt", HasLZCNT)        .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)        .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)        .Case("mmx", MMX3DNowLevel >= MMX)        .Case("movbe", HasMOVBE) +      .Case("movdiri", HasMOVDIRI) +      .Case("movdir64b", HasMOVDIR64B)        .Case("mpx", HasMPX)        .Case("mwaitx", HasMWAITX)        .Case("pclmul", HasPCLMUL) +      .Case("pconfig", HasPCONFIG)        .Case("pku", HasPKU)        .Case("popcnt", HasPOPCNT)        .Case("prefetchwt1", HasPREFETCHWT1)        .Case("prfchw", HasPRFCHW) +      .Case("ptwrite", HasPTWRITE) +      .Case("rdpid", HasRDPID)        .Case("rdrnd", HasRDRND)        .Case("rdseed", HasRDSEED)        .Case("retpoline", HasRetpoline) @@ -1337,6 +1414,8 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {        .Case("tbm", HasTBM)        .Case("vaes", HasVAES)        .Case("vpclmulqdq", HasVPCLMULQDQ) +      .Case("wbnoinvd", HasWBNOINVD) +      .Case("waitpkg", HasWAITPKG)        .Case("x86", true)        .Case("x86_32", getTriple().getArch() == llvm::Triple::x86)        .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64) @@ -1360,6 +1439,95 @@ bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const {        .Default(false);  } +static llvm::X86::ProcessorFeatures getFeature(StringRef Name) { +  return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name) +#define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, llvm::X86::ENUM) +#include "llvm/Support/X86TargetParser.def" +      ; +  // Note, this function should only be used after ensuring the value is +  // correct, so it asserts if the value is out of range. +} + +static unsigned getFeaturePriority(llvm::X86::ProcessorFeatures Feat) { +  enum class FeatPriority { +#define FEATURE(FEAT) FEAT, +#include "clang/Basic/X86Target.def" +  }; +  switch (Feat) { +#define FEATURE(FEAT)                                                          \ +  case llvm::X86::FEAT:                                                        \ +    return static_cast<unsigned>(FeatPriority::FEAT); +#include "clang/Basic/X86Target.def" +  default: +    llvm_unreachable("No Feature Priority for non-CPUSupports Features"); +  } +} + +unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const { +  // Valid CPUs have a 'key feature' that compares just better than its key +  // feature. +  CPUKind Kind = getCPUKind(Name); +  if (Kind != CK_Generic) { +    switch (Kind) { +    default: +      llvm_unreachable( +          "CPU Type without a key feature used in 'target' attribute"); +#define PROC_WITH_FEAT(ENUM, STR, IS64, KEY_FEAT)                              \ +  case CK_##ENUM:                                                              \ +    return (getFeaturePriority(llvm::X86::KEY_FEAT) << 1) + 1; +#include "clang/Basic/X86Target.def" +    } +  } + +  // Now we know we have a feature, so get its priority and shift it a few so +  // that we have sufficient room for the CPUs (above). +  return getFeaturePriority(getFeature(Name)) << 1; +} + +bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const { +  return llvm::StringSwitch<bool>(Name) +#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, true) +#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, true) +#include "clang/Basic/X86Target.def" +      .Default(false); +} + +static StringRef CPUSpecificCPUDispatchNameDealias(StringRef Name) { +  return llvm::StringSwitch<StringRef>(Name) +#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, NAME) +#include "clang/Basic/X86Target.def" +      .Default(Name); +} + +char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const { +  return llvm::StringSwitch<char>(CPUSpecificCPUDispatchNameDealias(Name)) +#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, MANGLING) +#include "clang/Basic/X86Target.def" +      .Default(0); +} + +void X86TargetInfo::getCPUSpecificCPUDispatchFeatures( +    StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const { +  StringRef WholeList = +      llvm::StringSwitch<StringRef>(CPUSpecificCPUDispatchNameDealias(Name)) +#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, FEATURES) +#include "clang/Basic/X86Target.def" +          .Default(""); +  WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false); +} + +std::string X86TargetInfo::getCPUKindCanonicalName(CPUKind Kind) const { +  switch (Kind) { +  case CK_Generic: +    return ""; +#define PROC(ENUM, STRING, IS64BIT)                                            \ +  case CK_##ENUM:                                                              \ +    return STRING; +#include "clang/Basic/X86Target.def" +  } +  llvm_unreachable("Invalid CPUKind"); +} +  // We can't use a generic validation scheme for the cpus accepted here  // versus subtarget cpus accepted in the target attribute because the  // variables intitialized by the runtime only support the below currently @@ -1445,7 +1613,7 @@ bool X86TargetInfo::validateAsmConstraint(    case 'y': // Any MMX register.    case 'v': // Any {X,Y,Z}MM register (Arch & context dependent)    case 'x': // Any SSE register. -  case 'k': // Any AVX512 mask register (same as Yk, additionaly allows k0 +  case 'k': // Any AVX512 mask register (same as Yk, additionally allows k0              // for intermideate k reg operations).    case 'Q': // Any register accessible as [r]h: a, b, c, and d.    case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp. @@ -1573,8 +1741,6 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {  bool X86TargetInfo::checkCPUKind(CPUKind Kind) const {    // Perform any per-CPU checks necessary to determine if this CPU is    // acceptable. -  // FIXME: This results in terrible diagnostics. Clang just says the CPU is -  // invalid without explaining *why*.    switch (Kind) {    case CK_Generic:      // No processor selected! @@ -1587,6 +1753,18 @@ bool X86TargetInfo::checkCPUKind(CPUKind Kind) const {    llvm_unreachable("Unhandled CPU kind");  } +void X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { +#define PROC(ENUM, STRING, IS64BIT)                                            \ +  if (IS64BIT || getTriple().getArch() == llvm::Triple::x86)                   \ +    Values.emplace_back(STRING); +  // Go through CPUKind checking to ensure that the alias is de-aliased and  +  // 64 bit-ness is checked. +#define PROC_ALIAS(ENUM, ALIAS)                                                \ +  if (checkCPUKind(getCPUKind(ALIAS)))                                         \ +    Values.emplace_back(ALIAS); +#include "clang/Basic/X86Target.def" +} +  X86TargetInfo::CPUKind X86TargetInfo::getCPUKind(StringRef CPU) const {    return llvm::StringSwitch<CPUKind>(CPU)  #define PROC(ENUM, STRING, IS64BIT) .Case(STRING, CK_##ENUM)  | 
