erichkeane created this revision.

In anticipation of multiversioned target support (and just for
code sanity), this patch extracts as much of the X86 TargetInfo
CPU values into its own file, unifying the support.

This has the side-effect of being a touch more liberal in what it
accepts than GCC, though will normalize all values to the backend
to a much smaller list.

Note that this depends on a llvm change to 86.td that Craig promises
he'll do in the near future.


https://reviews.llvm.org/D39521

Files:
  include/clang/Basic/TargetInfo.h
  include/clang/Basic/X86Target.def
  lib/Basic/Targets/X86.cpp
  lib/Basic/Targets/X86.h
  lib/CodeGen/CGBuiltin.cpp
  lib/CodeGen/CGCall.cpp
  test/CodeGen/attr-target-x86.c

Index: test/CodeGen/attr-target-x86.c
===================================================================
--- test/CodeGen/attr-target-x86.c
+++ test/CodeGen/attr-target-x86.c
@@ -36,11 +36,12 @@
 // CHECK: qax{{.*}} #5
 // CHECK: qq{{.*}} #6
 // CHECK: lake{{.*}} #7
-// CHECK: #0 = {{.*}}"target-cpu"="i686" "target-features"="+x87"
+// The below check issues pentiumpro instead of i686, because they have been dealiased.
+// CHECK: #0 = {{.*}}"target-cpu"="pentiumpro" "target-features"="+x87"
 // CHECK: #1 = {{.*}}"target-cpu"="ivybridge" "target-features"="+aes,+avx,+cx16,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"
-// CHECK: #2 = {{.*}}"target-cpu"="i686" "target-features"="+x87,-aes,-avx,-avx2,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vl,-avx512vpopcntdq,-f16c,-fma,-fma4,-pclmul,-sha,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-xop,-xsave,-xsaveopt"
-// CHECK: #3 = {{.*}}"target-cpu"="i686" "target-features"="+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"
-// CHECK: #4 = {{.*}}"target-cpu"="i686" "target-features"="+x87,-avx,-avx2,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vl,-avx512vpopcntdq,-f16c,-fma,-fma4,-sse4.1,-sse4.2,-xop,-xsave,-xsaveopt"
+// CHECK: #2 = {{.*}}"target-cpu"="pentiumpro" "target-features"="+x87,-aes,-avx,-avx2,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vl,-avx512vpopcntdq,-f16c,-fma,-fma4,-pclmul,-sha,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-xop,-xsave,-xsaveopt"
+// CHECK: #3 = {{.*}}"target-cpu"="pentiumpro" "target-features"="+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"
+// CHECK: #4 = {{.*}}"target-cpu"="pentiumpro" "target-features"="+x87,-avx,-avx2,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vl,-avx512vpopcntdq,-f16c,-fma,-fma4,-sse4.1,-sse4.2,-xop,-xsave,-xsaveopt"
 // CHECK: #5 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes"
-// CHECK: #6 = {{.*}}"target-cpu"="i686" "target-features"="+x87,-3dnow,-3dnowa,-mmx"
+// CHECK: #6 = {{.*}}"target-cpu"="pentiumpro" "target-features"="+x87,-3dnow,-3dnowa,-mmx"
 // CHECK: #7 = {{.*}}"target-cpu"="lakemont" "target-features"="+mmx"
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1889,7 +1889,8 @@
           getTarget().isValidCPUName(ParsedAttr.Architecture))
         TargetCPU = ParsedAttr.Architecture;
       if (TargetCPU != "")
-         FuncAttrs.addAttribute("target-cpu", TargetCPU);
+        FuncAttrs.addAttribute("target-cpu",
+                               getTarget().normalizeCpuName(TargetCPU));
       if (!Features.empty()) {
         std::sort(Features.begin(), Features.end());
         FuncAttrs.addAttribute(
@@ -1901,7 +1902,8 @@
       // function.
       std::vector<std::string> &Features = getTarget().getTargetOpts().Features;
       if (TargetCPU != "")
-        FuncAttrs.addAttribute("target-cpu", TargetCPU);
+        FuncAttrs.addAttribute("target-cpu",
+                               getTarget().normalizeCpuName(TargetCPU));
       if (!Features.empty()) {
         std::sort(Features.begin(), Features.end());
         FuncAttrs.addAttribute(
Index: lib/CodeGen/CGBuiltin.cpp
===================================================================
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -7500,79 +7500,6 @@
 }
 
 Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) {
-
-  // This enum contains the vendor, type, and subtype enums from the
-  // runtime library concatenated together. The _START labels mark
-  // the start and are used to adjust the value into the correct
-  // encoding space.
-  enum X86CPUs {
-    INTEL = 1,
-    AMD,
-    CPU_TYPE_START,
-    INTEL_BONNELL,
-    INTEL_CORE2,
-    INTEL_COREI7,
-    AMDFAM10H,
-    AMDFAM15H,
-    INTEL_SILVERMONT,
-    INTEL_KNL,
-    AMD_BTVER1,
-    AMD_BTVER2,
-    AMDFAM17H,
-    CPU_SUBTYPE_START,
-    INTEL_COREI7_NEHALEM,
-    INTEL_COREI7_WESTMERE,
-    INTEL_COREI7_SANDYBRIDGE,
-    AMDFAM10H_BARCELONA,
-    AMDFAM10H_SHANGHAI,
-    AMDFAM10H_ISTANBUL,
-    AMDFAM15H_BDVER1,
-    AMDFAM15H_BDVER2,
-    AMDFAM15H_BDVER3,
-    AMDFAM15H_BDVER4,
-    AMDFAM17H_ZNVER1,
-    INTEL_COREI7_IVYBRIDGE,
-    INTEL_COREI7_HASWELL,
-    INTEL_COREI7_BROADWELL,
-    INTEL_COREI7_SKYLAKE,
-    INTEL_COREI7_SKYLAKE_AVX512,
-  };
-
-  X86CPUs CPU =
-    StringSwitch<X86CPUs>(CPUStr)
-      .Case("amd", AMD)
-      .Case("amdfam10h", AMDFAM10H)
-      .Case("amdfam10", AMDFAM10H)
-      .Case("amdfam15h", AMDFAM15H)
-      .Case("amdfam15", AMDFAM15H)
-      .Case("amdfam17h", AMDFAM17H)
-      .Case("atom", INTEL_BONNELL)
-      .Case("barcelona", AMDFAM10H_BARCELONA)
-      .Case("bdver1", AMDFAM15H_BDVER1)
-      .Case("bdver2", AMDFAM15H_BDVER2)
-      .Case("bdver3", AMDFAM15H_BDVER3)
-      .Case("bdver4", AMDFAM15H_BDVER4)
-      .Case("bonnell", INTEL_BONNELL)
-      .Case("broadwell", INTEL_COREI7_BROADWELL)
-      .Case("btver1", AMD_BTVER1)
-      .Case("btver2", AMD_BTVER2)
-      .Case("core2", INTEL_CORE2)
-      .Case("corei7", INTEL_COREI7)
-      .Case("haswell", INTEL_COREI7_HASWELL)
-      .Case("intel", INTEL)
-      .Case("istanbul", AMDFAM10H_ISTANBUL)
-      .Case("ivybridge", INTEL_COREI7_IVYBRIDGE)
-      .Case("knl", INTEL_KNL)
-      .Case("nehalem", INTEL_COREI7_NEHALEM)
-      .Case("sandybridge", INTEL_COREI7_SANDYBRIDGE)
-      .Case("shanghai", AMDFAM10H_SHANGHAI)
-      .Case("silvermont", INTEL_SILVERMONT)
-      .Case("skylake", INTEL_COREI7_SKYLAKE)
-      .Case("skylake-avx512", INTEL_COREI7_SKYLAKE_AVX512)
-      .Case("slm", INTEL_SILVERMONT)
-      .Case("westmere", INTEL_COREI7_WESTMERE)
-      .Case("znver1", AMDFAM17H_ZNVER1);
-
   llvm::Type *Int32Ty = Builder.getInt32Ty();
 
   // Matching the struct layout from the compiler-rt/libgcc structure that is
@@ -7591,16 +7518,8 @@
   // range. Also adjust the expected value.
   unsigned Index;
   unsigned Value;
-  if (CPU > CPU_SUBTYPE_START) {
-    Index = 2;
-    Value = CPU - CPU_SUBTYPE_START;
-  } else if (CPU > CPU_TYPE_START) {
-    Index = 1;
-    Value = CPU - CPU_TYPE_START;
-  } else {
-    Index = 0;
-    Value = CPU;
-  }
+  std::tie(Index, Value) = getTarget().getCpuIsCode(CPUStr);
+  assert(Value != 0 && "Invalid Cpu String given to EmitX86CpuIs");
 
   // Grab the appropriate field from __cpu_model.
   llvm::Value *Idxs[] = {
Index: lib/Basic/Targets/X86.h
===================================================================
--- lib/Basic/Targets/X86.h
+++ lib/Basic/Targets/X86.h
@@ -95,184 +95,40 @@
   /// loosely correspond to the options passed to '-march' or '-mtune' flags.
   enum CPUKind {
     CK_Generic,
-
-    /// \name i386
-    /// i386-generation processors.
-    //@{
-    CK_i386,
-    //@}
-
-    /// \name i486
-    /// i486-generation processors.
-    //@{
-    CK_i486,
-    CK_WinChipC6,
-    CK_WinChip2,
-    CK_C3,
-    //@}
-
-    /// \name i586
-    /// i586-generation processors, P5 microarchitecture based.
-    //@{
-    CK_i586,
-    CK_Pentium,
-    CK_PentiumMMX,
-    //@}
-
-    /// \name i686
-    /// i686-generation processors, P6 / Pentium M microarchitecture based.
-    //@{
-    CK_PentiumPro,
-    CK_Pentium2,
-    CK_Pentium3,
-    CK_PentiumM,
-    CK_C3_2,
-
-    /// This enumerator is a bit odd, as GCC no longer accepts -march=yonah.
-    /// Clang however has some logic to support this.
-    // FIXME: Warn, deprecate, and potentially remove this.
-    CK_Yonah,
-    //@}
-
-    /// \name Netburst
-    /// Netburst microarchitecture based processors.
-    //@{
-    CK_Pentium4,
-    CK_Prescott,
-    CK_Nocona,
-    //@}
-
-    /// \name Core
-    /// Core microarchitecture based processors.
-    //@{
-    CK_Core2,
-
-    /// This enumerator, like \see CK_Yonah, is a bit odd. It is another
-    /// codename which GCC no longer accepts as an option to -march, but Clang
-    /// has some logic for recognizing it.
-    // FIXME: Warn, deprecate, and potentially remove this.
-    CK_Penryn,
-    //@}
-
-    /// \name Atom
-    /// Atom processors
-    //@{
-    CK_Bonnell,
-    CK_Silvermont,
-    CK_Goldmont,
-    //@}
-
-    /// \name Nehalem
-    /// Nehalem microarchitecture based processors.
-    CK_Nehalem,
-
-    /// \name Westmere
-    /// Westmere microarchitecture based processors.
-    CK_Westmere,
-
-    /// \name Sandy Bridge
-    /// Sandy Bridge microarchitecture based processors.
-    CK_SandyBridge,
-
-    /// \name Ivy Bridge
-    /// Ivy Bridge microarchitecture based processors.
-    CK_IvyBridge,
-
-    /// \name Haswell
-    /// Haswell microarchitecture based processors.
-    CK_Haswell,
-
-    /// \name Broadwell
-    /// Broadwell microarchitecture based processors.
-    CK_Broadwell,
-
-    /// \name Skylake Client
-    /// Skylake client microarchitecture based processors.
-    CK_SkylakeClient,
-
-    /// \name Skylake Server
-    /// Skylake server microarchitecture based processors.
-    CK_SkylakeServer,
-
-    /// \name Cannonlake Client
-    /// Cannonlake client microarchitecture based processors.
-    CK_Cannonlake,
-
-    /// \name Knights Landing
-    /// Knights Landing processor.
-    CK_KNL,
-
-    /// \name Knights Mill
-    /// Knights Mill processor.
-    CK_KNM,
-
-    /// \name Lakemont
-    /// Lakemont microarchitecture based processors.
-    CK_Lakemont,
-
-    /// \name K6
-    /// K6 architecture processors.
-    //@{
-    CK_K6,
-    CK_K6_2,
-    CK_K6_3,
-    //@}
-
-    /// \name K7
-    /// K7 architecture processors.
-    //@{
-    CK_Athlon,
-    CK_AthlonXP,
-    //@}
-
-    /// \name K8
-    /// K8 architecture processors.
-    //@{
-    CK_K8,
-    CK_K8SSE3,
-    CK_AMDFAM10,
-    //@}
-
-    /// \name Bobcat
-    /// Bobcat architecture processors.
-    //@{
-    CK_BTVER1,
-    CK_BTVER2,
-    //@}
-
-    /// \name Bulldozer
-    /// Bulldozer architecture processors.
-    //@{
-    CK_BDVER1,
-    CK_BDVER2,
-    CK_BDVER3,
-    CK_BDVER4,
-    //@}
-
-    /// \name zen
-    /// Zen architecture processors.
-    //@{
-    CK_ZNVER1,
-    //@}
-
-    /// This specification is deprecated and will be removed in the future.
-    /// Users should prefer \see CK_K8.
-    // FIXME: Warn on this when the CPU is set to it.
-    //@{
-    CK_x86_64,
-    //@}
-
-    /// \name Geode
-    /// Geode processors.
-    //@{
-    CK_Geode
-    //@}
+#define IGNORE_ALIASES
+#define PROC_VENDOR(Name, String, CpuId)
+#define PROC_FAMILY(Name, String, Is64Bit, CpuId) CK_##Name,
+#define PROC(Name, String, Is64Bit, CpuId) CK_##Name,
+#include "clang/Basic/X86Target.def"
+#undef PROC_FAMILY
+#undef PROC
+#undef PROC_VENDOR
+#undef IGNORE_ALIASES
   } CPU = CK_Generic;
 
   bool checkCPUKind(CPUKind Kind) const;
 
   CPUKind getCPUKind(StringRef CPU) const;
 
+  // \brief Returns a pair of unsigned integers that contain the __cpu_model
+  // information required to identify the specified Processor Family/Processor.
+  // A valid Processor Family will return a 1 in the first value, and the 'type'
+  // identifier for the family in the second.  A valid Processor will return a 2
+  // in the first value, and the 'subtype' identifier for the processor in the
+  // second. If the value provided is not valid for cpu_is identification, will
+  // return a 0 in the second value.
+  std::tuple<unsigned, unsigned> IsValidCpuIsProc(CPUKind Kind) const;
+
+  // \brief Returns a pair of unsigned integers that contains the __cpu_model
+  // information required to identify the specified vendor.  If the vendor
+  // string is invalid, or not identifiable in a __cpu_model struct, returns the
+  // pair {0,0}.
+  std::tuple<unsigned, unsigned> CpuIsVendor(StringRef Str) const;
+
+  // \brief Converts a CPUKind to a string. This has the advantage of
+  // de-aliasing the CPUKind when combined with getCPUKind.
+  std::string getCpuKindName(CPUKind Kind) const;
+
   enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default;
 
 public:
@@ -296,6 +152,10 @@
 
   bool validateCpuSupports(StringRef Name) const override;
 
+  std::tuple<unsigned, unsigned> getCpuIsCode(StringRef Name) const override;
+
+  std::string normalizeCpuName(StringRef Name) const override;
+
   bool validateCpuIs(StringRef Name) const override;
 
   bool validateAsmConstraint(const char *&Name,
Index: lib/Basic/Targets/X86.cpp
===================================================================
--- lib/Basic/Targets/X86.cpp
+++ lib/Basic/Targets/X86.cpp
@@ -178,6 +178,7 @@
     setFeatureEnabledImpl(Features, "aes", true);
     setFeatureEnabledImpl(Features, "pclmul", true);
     LLVM_FALLTHROUGH;
+  case CK_CoreI7:
   case CK_Nehalem:
     setFeatureEnabledImpl(Features, "sse4.2", true);
     LLVM_FALLTHROUGH;
@@ -265,6 +266,9 @@
     break;
 
   case CK_AMDFAM10:
+  case CK_Barcelona:
+  case CK_Shanghai:
+  case CK_Istanbul:
     setFeatureEnabledImpl(Features, "sse4a", true);
     setFeatureEnabledImpl(Features, "lzcnt", true);
     setFeatureEnabledImpl(Features, "popcnt", true);
@@ -303,6 +307,7 @@
     setFeatureEnabledImpl(Features, "fxsr", true);
     break;
 
+  case CK_AMDFAM17:
   case CK_ZNVER1:
     setFeatureEnabledImpl(Features, "adx", true);
     setFeatureEnabledImpl(Features, "aes", true);
@@ -347,6 +352,7 @@
     setFeatureEnabledImpl(Features, "f16c", true);
     setFeatureEnabledImpl(Features, "tbm", true);
     LLVM_FALLTHROUGH;
+  case CK_AMDFAM15:
   case CK_BDVER1:
     // xop implies avx, sse4a and fma4.
     setFeatureEnabledImpl(Features, "xop", true);
@@ -829,6 +835,7 @@
   case CK_Goldmont:
     defineCPUMacros(Builder, "goldmont");
     break;
+  case CK_CoreI7:
   case CK_Nehalem:
   case CK_Westmere:
   case CK_SandyBridge:
@@ -886,14 +893,18 @@
     defineCPUMacros(Builder, "k8");
     break;
   case CK_AMDFAM10:
+  case CK_Barcelona:
+  case CK_Shanghai:
+  case CK_Istanbul:
     defineCPUMacros(Builder, "amdfam10");
     break;
   case CK_BTVER1:
     defineCPUMacros(Builder, "btver1");
     break;
   case CK_BTVER2:
     defineCPUMacros(Builder, "btver2");
     break;
+  case CK_AMDFAM15:
   case CK_BDVER1:
     defineCPUMacros(Builder, "bdver1");
     break;
@@ -906,6 +917,7 @@
   case CK_BDVER4:
     defineCPUMacros(Builder, "bdver4");
     break;
+  case CK_AMDFAM17:
   case CK_ZNVER1:
     defineCPUMacros(Builder, "znver1");
     break;
@@ -1283,43 +1295,80 @@
       .Default(false);
 }
 
+std::tuple<unsigned, unsigned> X86TargetInfo::CpuIsVendor(StringRef Str) const {
+  return llvm::StringSwitch<std::tuple<unsigned, unsigned>>(Str)
+#define IGNORE_ALIASES
+#define PROC_VENDOR(Name, String, CpuId) .Case(String, {0, CpuId})
+#define PROC_FAMILY(Name, String, Proc64, CpuId)
+#define PROC(Name, String, Proc64, CpuId)
+#include "clang/Basic/X86Target.def"
+#undef PROC_VENDOR
+#undef PROC_FAMILY
+#undef PROC
+#undef IGNORE_ALIASES
+      .Default({});
+}
+// TODO: DoC: Takes "Kind" because aliases
+std::tuple<unsigned, unsigned>
+X86TargetInfo::IsValidCpuIsProc(CPUKind Kind) const {
+  switch (Kind) {
+#define IGNORE_ALIASES
+#define PROC_VENDOR(Name, String, CpuId)
+#define PROC_FAMILY(Name, String, Proc64, CpuId)                               \
+  case CK_##Name:                                                              \
+    return {1, CpuId};
+#define PROC(Name, String, Proc64, CpuId)                                      \
+  case CK_##Name:                                                              \
+    return {2, CpuId};
+#include "clang/Basic/X86Target.def"
+#undef PROC_VENDOR
+#undef PROC_FAMILY
+#undef PROC
+#undef IGNORE_ALIASES
+  case CK_Generic:
+    return {};
+  }
+  return {};
+}
+
+std::string X86TargetInfo::getCpuKindName(CPUKind Kind) const {
+  switch (Kind) {
+#define IGNORE_ALIASES
+#define PROC_VENDOR(Name, String, CpuId)
+#define PROC_FAMILY(Name, String, Proc64, CpuId)                               \
+  case CK_##Name:                                                              \
+    return String;
+#define PROC(Name, String, Proc64, CpuId)                                      \
+  case CK_##Name:                                                              \
+    return String;
+#include "clang/Basic/X86Target.def"
+#undef PROC_VENDOR
+#undef PROC_FAMILY
+#undef PROC
+#undef IGNORE_ALIASES
+  case CK_Generic: return "";
+  }
+  llvm_unreachable("Unhandled CPU kind");
+}
+
+std::tuple<unsigned, unsigned>
+X86TargetInfo::getCpuIsCode(StringRef Name) const {
+  auto Vendor = CpuIsVendor(Name);
+  if (std::get<1>(Vendor) != 0)
+    return Vendor;
+  return IsValidCpuIsProc(getCPUKind(Name));
+}
+std::string X86TargetInfo::normalizeCpuName(StringRef Name) const {
+  return getCpuKindName(getCPUKind(Name));
+
+}
+
 // 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
-// rather than the full range of cpus.
+// variables intitialized by the runtime only support a smaller list of
+// processors.
 bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const {
-  return llvm::StringSwitch<bool>(FeatureStr)
-      .Case("amd", true)
-      .Case("amdfam10h", true)
-      .Case("amdfam15h", true)
-      .Case("amdfam17h", true)
-      .Case("atom", true)
-      .Case("barcelona", true)
-      .Case("bdver1", true)
-      .Case("bdver2", true)
-      .Case("bdver3", true)
-      .Case("bdver4", true)
-      .Case("bonnell", true)
-      .Case("broadwell", true)
-      .Case("btver1", true)
-      .Case("btver2", true)
-      .Case("core2", true)
-      .Case("corei7", true)
-      .Case("haswell", true)
-      .Case("intel", true)
-      .Case("istanbul", true)
-      .Case("ivybridge", true)
-      .Case("knl", true)
-      .Case("nehalem", true)
-      .Case("sandybridge", true)
-      .Case("shanghai", true)
-      .Case("silvermont", true)
-      .Case("skylake", true)
-      .Case("skylake-avx512", true)
-      .Case("slm", true)
-      .Case("westmere", true)
-      .Case("znver1", true)
-      .Default(false);
+  return std::get<1>(getCpuIsCode(FeatureStr)) != 0;
 }
 
 bool X86TargetInfo::validateAsmConstraint(
@@ -1522,125 +1571,44 @@
   // acceptable.
   // FIXME: This results in terrible diagnostics. Clang just says the CPU is
   // invalid without explaining *why*.
+  bool Is64BitProc = false;
   switch (Kind) {
   case CK_Generic:
     // No processor selected!
     return false;
-
-  case CK_i386:
-  case CK_i486:
-  case CK_WinChipC6:
-  case CK_WinChip2:
-  case CK_C3:
-  case CK_i586:
-  case CK_Pentium:
-  case CK_PentiumMMX:
-  case CK_PentiumPro:
-  case CK_Pentium2:
-  case CK_Pentium3:
-  case CK_PentiumM:
-  case CK_Yonah:
-  case CK_C3_2:
-  case CK_Pentium4:
-  case CK_Lakemont:
-  case CK_Prescott:
-  case CK_K6:
-  case CK_K6_2:
-  case CK_K6_3:
-  case CK_Athlon:
-  case CK_AthlonXP:
-  case CK_Geode:
-    // Only accept certain architectures when compiling in 32-bit mode.
-    if (getTriple().getArch() != llvm::Triple::x86)
-      return false;
-
-    LLVM_FALLTHROUGH;
-  case CK_Nocona:
-  case CK_Core2:
-  case CK_Penryn:
-  case CK_Bonnell:
-  case CK_Silvermont:
-  case CK_Goldmont:
-  case CK_Nehalem:
-  case CK_Westmere:
-  case CK_SandyBridge:
-  case CK_IvyBridge:
-  case CK_Haswell:
-  case CK_Broadwell:
-  case CK_SkylakeClient:
-  case CK_SkylakeServer:
-  case CK_Cannonlake:
-  case CK_KNL:
-  case CK_KNM:
-  case CK_K8:
-  case CK_K8SSE3:
-  case CK_AMDFAM10:
-  case CK_BTVER1:
-  case CK_BTVER2:
-  case CK_BDVER1:
-  case CK_BDVER2:
-  case CK_BDVER3:
-  case CK_BDVER4:
-  case CK_ZNVER1:
-  case CK_x86_64:
-    return true;
+#define PROC_VENDOR(Name, String, CpuId)
+#define IGNORE_ALIASES
+#define PROC_FAMILY(Name, String, Proc64, CpuId)                               \
+  case CK_##Name:                                                              \
+    Is64BitProc = Proc64;                                                      \
+    break;
+#define PROC(Name, String, Proc64, CpuId)                                      \
+  case CK_##Name:                                                              \
+    Is64BitProc = Proc64;                                                      \
+    break;
+#include "clang/Basic/X86Target.def"
+#undef PROC
+#undef PROC_FAMILY
+#undef IGNORE_ALIASES
+#undef PROC_VENDOR
   }
-  llvm_unreachable("Unhandled CPU kind");
+  // Only accept certain architectures when compiling in 32-bit mode.
+  return Is64BitProc || getTriple().getArch() == llvm::Triple::x86;
 }
 
 X86TargetInfo::CPUKind X86TargetInfo::getCPUKind(StringRef CPU) const {
   return llvm::StringSwitch<CPUKind>(CPU)
-      .Case("i386", CK_i386)
-      .Case("i486", CK_i486)
-      .Case("winchip-c6", CK_WinChipC6)
-      .Case("winchip2", CK_WinChip2)
-      .Case("c3", CK_C3)
-      .Case("i586", CK_i586)
-      .Case("pentium", CK_Pentium)
-      .Case("pentium-mmx", CK_PentiumMMX)
-      .Cases("i686", "pentiumpro", CK_PentiumPro)
-      .Case("pentium2", CK_Pentium2)
-      .Cases("pentium3", "pentium3m", CK_Pentium3)
-      .Case("pentium-m", CK_PentiumM)
-      .Case("c3-2", CK_C3_2)
-      .Case("yonah", CK_Yonah)
-      .Cases("pentium4", "pentium4m", CK_Pentium4)
-      .Case("prescott", CK_Prescott)
-      .Case("nocona", CK_Nocona)
-      .Case("core2", CK_Core2)
-      .Case("penryn", CK_Penryn)
-      .Cases("bonnell", "atom", CK_Bonnell)
-      .Cases("silvermont", "slm", CK_Silvermont)
-      .Case("goldmont", CK_Goldmont)
-      .Cases("nehalem", "corei7", CK_Nehalem)
-      .Case("westmere", CK_Westmere)
-      .Cases("sandybridge", "corei7-avx", CK_SandyBridge)
-      .Cases("ivybridge", "core-avx-i", CK_IvyBridge)
-      .Cases("haswell", "core-avx2", CK_Haswell)
-      .Case("broadwell", CK_Broadwell)
-      .Case("skylake", CK_SkylakeClient)
-      .Cases("skylake-avx512", "skx", CK_SkylakeServer)
-      .Case("cannonlake", CK_Cannonlake)
-      .Case("knl", CK_KNL)
-      .Case("knm", CK_KNM)
-      .Case("lakemont", CK_Lakemont)
-      .Case("k6", CK_K6)
-      .Case("k6-2", CK_K6_2)
-      .Case("k6-3", CK_K6_3)
-      .Cases("athlon", "athlon-tbird", CK_Athlon)
-      .Cases("athlon-xp", "athlon-mp", "athlon-4", CK_AthlonXP)
-      .Cases("k8", "athlon64", "athlon-fx", "opteron", CK_K8)
-      .Cases("k8-sse3", "athlon64-sse3", "opteron-sse3", CK_K8SSE3)
-      .Cases("amdfam10", "barcelona", CK_AMDFAM10)
-      .Case("btver1", CK_BTVER1)
-      .Case("btver2", CK_BTVER2)
-      .Case("bdver1", CK_BDVER1)
-      .Case("bdver2", CK_BDVER2)
-      .Case("bdver3", CK_BDVER3)
-      .Case("bdver4", CK_BDVER4)
-      .Case("znver1", CK_ZNVER1)
-      .Case("x86-64", CK_x86_64)
-      .Case("geode", CK_Geode)
+#define PROC_VENDOR(Name, String, CpuId)
+#define PROC_FAMILY(Name, String, Proc64, CpuId) .Case(String, CK_##Name)
+#define PROC_FAMILY_ALIAS(Name, String) .Case(String, CK_##Name)
+#define PROC(Name, String, Proc64, CpuId) .Case(String, CK_##Name)
+#define PROC_ALIAS(Name, String) .Case(String, CK_##Name)
+#include "clang/Basic/X86Target.def"
+#undef PROC_VENDOR
+#undef PROC_FAMILY
+#undef PROC_FAMILY_ALIAS
+#undef PROC
+#undef PROC_ALIAS
       .Default(CK_Generic);
 }
 
Index: include/clang/Basic/X86Target.def
===================================================================
--- /dev/null
+++ include/clang/Basic/X86Target.def
@@ -0,0 +1,217 @@
+//===--- X86.def - X86 Feature/Processor Database ------ --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the X86-specific Features and Processors, as used by
+// the X86 Targets.
+//
+//===----------------------------------------------------------------------===//
+
+// IGNORE_ALIASES: Define this value to force this document to not emit
+// processor family and processor aliases.
+
+// PROC_VENDOR(Name, Spelling, Cpuid)
+//   Specifies a processor vendor, as detectible by the __builtin_cpu_is. This
+//   will be used as by the __builtin_cpu_is field to detect the vendor of the
+//   executing processor.
+// Name: An identifer unique to other 'Name' fields in this
+// document that can be used to identify this vendor internally.
+// Spelling: A string that the programmer can use to identify this vendor.
+// Cpuid: A numeric value that matches the __cpu_vendor value of __cpu_model, or
+//   0 if it is not supported.
+
+// PROC_FAMILY(Name, Spelling, ProcKind, Cpuid)
+//   Specifies a family of processors, as detectible by the __builtin_cpu_is.
+//   This will be used both as a configurable -march value as well as for
+//   anything that uses the __builtin_cpu_is functionality, such as attribute
+//   'target'.
+// Name: An identifer unique to other 'Name' fields in this
+//   document that can be used to identify this family internally.
+// Spelling: A string that the programmer can use to identify this family. Note
+//   that this must also be unique among processors as well as families.
+// ProcKind: Either PROC_64_BIT or PROC_32_BIT, indentifying whether this is a
+//   64 or 32 bit processor family, respectively.
+// Cpuid: A numeric value that matches the __cpu_type value of __cpu_model, or 0
+//   if it is not supported.
+
+// PROC(Name, Spelling, ProcKind, Cpuid)
+//   Specifies a processor, as detectible by the __builtin_cpu_is.
+//   This will be used both as a configurable -march value as well as for
+//   anything that uses the __builtin_cpu_is functionality, such as attribute
+//   'target'. Note that the difference between this and a PROC_FAMILY is that
+//   this checks against a separate section of the __cpu_model struct.
+// Name: An identifer unique to other 'Name' fields in this
+//   document that can be used to identify this processor internally.
+// Spelling: A string that the programmer can use to identify this processor.
+//   Note that this must also be unique among processors as well as families.
+// ProcKind: Either PROC_64_BIT or PROC_32_BIT, indentifying whether this is a
+//   64 or 32 bit processor, respectively.
+// Cpuid: A numeric value that matches the __cpu_subtype value of __cpu_model,
+//   or 0 if it is not supported.
+
+// PROC_FAMILY_ALIAS(Name, Spelling)
+//   Provides an alternate spelling for a processor family.
+// Name: The identifier used for the Name field in the original PROC_FAMILY
+//   macro.
+// Spelling: A string containing the new alternative spelling of this processor
+//   family.
+
+// PROC_ALIAS(Name, Spelling)
+//   Provides an alternate spelling for a processor.
+// Name: The identifier used for the Name field in the original PROC macro.
+// Spelling: A string containing the new alternative spelling of this processor.
+
+#ifdef IGNORE_ALIASES
+#define PROC_FAMILY_ALIAS(Name, Spelling)
+#define PROC_ALIAS(Name, Spelling)
+#endif
+
+#ifndef PROC_64_BIT
+#define PROC_64_BIT true
+#define PROC_32_BIT false
+#define DEFINED_PROC_BIT_CONSTANTS
+#endif
+
+PROC_VENDOR(Intel, "intel", 1)
+PROC_VENDOR(AMD, "amd", 2)
+
+
+PROC_FAMILY(Bonnell, "bonnell", PROC_64_BIT, 1)
+PROC_FAMILY_ALIAS(Bonnell, "atom")
+
+PROC_FAMILY(Core2, "core2", PROC_64_BIT, 2)
+
+PROC_FAMILY(CoreI7, "corei7", PROC_64_BIT, 3)
+PROC(Nehalem, "nehalem", PROC_64_BIT, 1)
+PROC(Westmere, "westmere", PROC_64_BIT, 2)
+PROC(SandyBridge, "sandybridge", PROC_64_BIT, 3)
+PROC_ALIAS(SandyBridge, "corei7-avx")
+PROC(IvyBridge, "ivybridge", PROC_64_BIT, 12)
+PROC_ALIAS(IvyBridge, "core-avx-i")
+PROC(Haswell, "haswell", PROC_64_BIT, 13)
+PROC_ALIAS(Haswell, "core-avx2")
+PROC(Broadwell, "broadwell", PROC_64_BIT, 14)
+PROC(SkylakeClient, "skylake", PROC_64_BIT, 15)
+PROC(SkylakeServer, "skylake-avx512", PROC_64_BIT, 16)
+PROC_ALIAS(SkylakeServer, "skx")
+
+PROC_FAMILY(AMDFAM10, "amdfam10", PROC_64_BIT, 4)
+PROC_FAMILY_ALIAS(AMDFAM10, "amdfam10h")
+PROC(Barcelona, "barcelona", PROC_64_BIT, 4)
+PROC(Shanghai, "shanghai", PROC_64_BIT, 5)
+PROC(Istanbul, "istanbul", PROC_64_BIT, 6)
+
+PROC_FAMILY(AMDFAM15, "amdfam15", PROC_64_BIT, 5)
+PROC_FAMILY_ALIAS(AMDFAM15, "amdfam15h")
+PROC(BDVER1, "bdver1", PROC_64_BIT, 7)
+PROC(BDVER2, "bdver2", PROC_64_BIT, 8)
+PROC(BDVER3, "bdver3", PROC_64_BIT, 9)
+PROC(BDVER4, "bdver4", PROC_64_BIT, 10)
+
+PROC_FAMILY(Silvermont, "silvermont", PROC_64_BIT, 6)
+PROC_FAMILY_ALIAS(Silvermont, "slm")
+
+PROC_FAMILY(KNL, "knl", PROC_64_BIT, 7)
+
+PROC_FAMILY(BTVER1, "btver1", PROC_64_BIT, 8)
+
+PROC_FAMILY(BTVER2, "btver2", PROC_64_BIT, 9)
+
+PROC_FAMILY(AMDFAM17, "amdfam17", PROC_64_BIT, 10)
+PROC_FAMILY_ALIAS(AMDFAM17, "amdfam17h")
+PROC(ZNVER1, "znver1", PROC_64_BIT, 11)
+
+
+// Processors that are not a CPUIs Type, unassociated with others.
+/// \name i386
+/// i386-generation processors.
+PROC(i386, "i386", PROC_32_BIT, 0)
+/// \name i486
+/// i486-generation processors.
+PROC(i486, "i486", PROC_32_BIT, 0)
+/// \name i486
+/// i486-generation processors.
+PROC(WinChipC6, "winchip-c6", PROC_32_BIT, 0)
+PROC(WinChip2, "winchip2", PROC_32_BIT, 0)
+PROC(C3, "c3", PROC_32_BIT, 0)
+/// \name i586
+/// i586-generation processors, P5 microarchitecture based.
+PROC(i586, "i586", PROC_32_BIT, 0)
+PROC(Pentium, "pentium", PROC_32_BIT, 0)
+PROC(PentiumMMX, "pentium-mmx", PROC_32_BIT, 0)
+PROC(PentiumPro, "pentiumpro", PROC_32_BIT, 0)
+PROC_ALIAS(PentiumPro, "i686")
+PROC(Pentium2, "pentium2", PROC_32_BIT, 0)
+PROC(Pentium3, "pentium3", PROC_32_BIT, 0)
+PROC_ALIAS(Pentium3, "pentium3m")
+PROC(PentiumM, "pentium-m", PROC_32_BIT, 0)
+PROC(C3_2, "c3-2", PROC_32_BIT, 0)
+/// This enumerator is a bit odd, as GCC no longer accepts -march=yonah.
+/// Clang however has some logic to support this.
+// FIXME: Warn, deprecate, and potentially remove this.
+PROC(Yonah, "yonah", PROC_32_BIT, 0)
+/// \name Netburst
+/// Netburst microarchitecture based processors.
+PROC(Pentium4, "pentium4", PROC_32_BIT, 0)
+PROC_ALIAS(Pentium4, "pentium4m")
+PROC(Prescott, "prescott", PROC_32_BIT, 0)
+PROC(Nocona, "nocona", PROC_64_BIT, 0)
+/// \name Core
+/// Core microarchitecture based processors.
+PROC(Penryn, "penryn", PROC_64_BIT, 0)
+/// \name Atom
+/// Atom processors
+PROC(Goldmont, "goldmont", PROC_64_BIT, 0)
+/// \name Cannonlake Client
+/// Cannonlake client microarchitecture based processors.
+PROC(Cannonlake, "cannonlake", PROC_64_BIT, 0)
+/// \name Knights Mill
+/// Knights Mill processor.
+PROC(KNM, "knm", PROC_64_BIT, 0)
+/// \name Lakemont
+/// Lakemont microarchitecture based processors.
+PROC(Lakemont, "lakemont", PROC_32_BIT, 0)
+/// \name K6
+/// K6 architecture processors.
+PROC(K6, "k6", PROC_32_BIT, 0)
+PROC(K6_2, "k6-2", PROC_32_BIT, 0)
+PROC(K6_3, "k6-3", PROC_32_BIT, 0)
+/// \name K7
+/// K7 architecture processors.
+PROC(Athlon, "athlon", PROC_32_BIT, 0)
+PROC_ALIAS(Athlon, "athlon-tbird")
+PROC(AthlonXP, "athlon-xp", PROC_32_BIT, 0)
+PROC_ALIAS(AthlonXP, "athlon-mp")
+PROC_ALIAS(AthlonXP, "athlon-4")
+/// \name K8
+/// K8 architecture processors.
+PROC(K8, "k8", PROC_64_BIT, 0)
+PROC_ALIAS(K8, "athlon64")
+PROC_ALIAS(K8, "athlon-fx")
+PROC_ALIAS(K8, "opteron")
+PROC(K8SSE3, "k8-sse3", PROC_64_BIT, 0)
+PROC_ALIAS(K8SSE3, "athlon64-sse3")
+PROC_ALIAS(K8SSE3, "opteron-sse3")
+/// This specification is deprecated and will be removed in the future.
+/// Users should prefer \see CK_K8.
+// FIXME: Warn on this when the CPU is set to it.
+PROC(x86_64, "x86-64", PROC_64_BIT, 0)
+/// \name Geode
+/// Geode processors.
+PROC(Geode, "geode", PROC_32_BIT, 0)
+
+#ifdef DEFINED_PROC_BIT_CONSTANTS
+#undef PROC_64_BIT
+#undef PROC_32_BIT
+#undef DEFINED_PROC_BIT_CONSTANTS
+#endif
+
+#ifdef IGNORE_ALIASES
+#undef PROC_FAMILY_ALIAS
+#undef PROC_ALIAS
+#endif
Index: include/clang/Basic/TargetInfo.h
===================================================================
--- include/clang/Basic/TargetInfo.h
+++ include/clang/Basic/TargetInfo.h
@@ -920,6 +920,18 @@
   // argument.
   virtual bool validateCpuIs(StringRef Name) const { return false; }
 
+  // \brief Return the code of the CPU that is used  for __builtin_cpu_is(const
+  // char*).
+  virtual std::tuple<unsigned, unsigned> getCpuIsCode(StringRef Name) const {
+    return {};
+  }
+
+  // \brief Normalizes the CPU name to be passed to the back end.  This can
+  // handle aliases and other necessary translations.
+  virtual std::string normalizeCpuName(StringRef Name) const {
+    return Name;
+  }
+
   // \brief Returns maximal number of args passed in registers.
   unsigned getRegParmMax() const {
     assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle");
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D39521: [... Erich Keane via Phabricator via cfe-commits

Reply via email to