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 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"); 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: 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 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 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 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,6 +893,9 @@ defineCPUMacros(Builder, "k8"); break; case CK_AMDFAM10: + case CK_Barcelona: + case CK_Shanghai: + case CK_Istanbul: defineCPUMacros(Builder, "amdfam10"); break; case CK_BTVER1: @@ -894,6 +904,7 @@ 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 X86TargetInfo::CpuIsVendor(StringRef Str) const { + return llvm::StringSwitch>(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 +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 +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(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(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: 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(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/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 &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: 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"