aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp153
1 files changed, 124 insertions, 29 deletions
diff --git a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp
index 94a53f9d9e46..53e26a9f8e22 100644
--- a/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp
+++ b/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/X86.cpp
@@ -11,16 +11,17 @@
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
-#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/Option/ArgList.h"
-#include "llvm/Support/Host.h"
+#include "llvm/TargetParser/Host.h"
using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
-std::string x86::getX86TargetCPU(const ArgList &Args,
+std::string x86::getX86TargetCPU(const Driver &D, const ArgList &Args,
const llvm::Triple &Triple) {
if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
StringRef CPU = A->getValue();
@@ -29,37 +30,39 @@ std::string x86::getX86TargetCPU(const ArgList &Args,
// FIXME: Reject attempts to use -march=native unless the target matches
// the host.
- //
- // FIXME: We should also incorporate the detected target features for use
- // with -native.
CPU = llvm::sys::getHostCPUName();
if (!CPU.empty() && CPU != "generic")
return std::string(CPU);
}
- if (const Arg *A = Args.getLastArgNoClaim(options::OPT__SLASH_arch)) {
+ if (const Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
// Mapping built by looking at lib/Basic's X86TargetInfo::initFeatureMap().
- StringRef Arch = A->getValue();
- StringRef CPU;
- if (Triple.getArch() == llvm::Triple::x86) { // 32-bit-only /arch: flags.
- CPU = llvm::StringSwitch<StringRef>(Arch)
- .Case("IA32", "i386")
- .Case("SSE", "pentium3")
- .Case("SSE2", "pentium4")
- .Default("");
+ // The keys are case-sensitive; this matches link.exe.
+ // 32-bit and 64-bit /arch: flags.
+ llvm::StringMap<StringRef> ArchMap({
+ {"AVX", "sandybridge"},
+ {"AVX2", "haswell"},
+ {"AVX512F", "knl"},
+ {"AVX512", "skylake-avx512"},
+ });
+ if (Triple.getArch() == llvm::Triple::x86) {
+ // 32-bit-only /arch: flags.
+ ArchMap.insert({
+ {"IA32", "i386"},
+ {"SSE", "pentium3"},
+ {"SSE2", "pentium4"},
+ });
}
- if (CPU.empty()) { // 32-bit and 64-bit /arch: flags.
- CPU = llvm::StringSwitch<StringRef>(Arch)
- .Case("AVX", "sandybridge")
- .Case("AVX2", "haswell")
- .Case("AVX512F", "knl")
- .Case("AVX512", "skylake-avx512")
- .Default("");
- }
- if (!CPU.empty()) {
- A->claim();
- return std::string(CPU);
+ StringRef CPU = ArchMap.lookup(A->getValue());
+ if (CPU.empty()) {
+ std::vector<StringRef> ValidArchs{ArchMap.keys().begin(),
+ ArchMap.keys().end()};
+ sort(ValidArchs);
+ D.Diag(diag::warn_drv_invalid_arch_name_with_suggestion)
+ << A->getValue() << (Triple.getArch() == llvm::Triple::x86)
+ << join(ValidArchs, ", ");
}
+ return std::string(CPU);
}
// Select the default CPU if none was given (or detection failed).
@@ -77,13 +80,19 @@ std::string x86::getX86TargetCPU(const ArgList &Args,
// Simulators can still run on 10.11 though, like Xcode.
if (Triple.isMacOSX() && !Triple.isOSVersionLT(10, 12))
return "penryn";
+
+ if (Triple.isDriverKit())
+ return "nehalem";
+
// The oldest x86_64 Macs have core2/Merom; the oldest x86 Macs have Yonah.
return Is64Bit ? "core2" : "yonah";
}
- // Set up default CPU name for PS4 compilers.
- if (Triple.isPS4CPU())
+ // Set up default CPU name for PS4/PS5 compilers.
+ if (Triple.isPS4())
return "btver2";
+ if (Triple.isPS5())
+ return "znver2";
// On Android use targets compatible with gcc
if (Triple.isAndroid())
@@ -110,6 +119,15 @@ std::string x86::getX86TargetCPU(const ArgList &Args,
void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args,
std::vector<StringRef> &Features) {
+ // Claim and report unsupported -mabi=. Note: we don't support "sysv_abi" or
+ // "ms_abi" as default function attributes.
+ if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mabi_EQ)) {
+ StringRef DefaultAbi = Triple.isOSWindows() ? "ms" : "sysv";
+ if (A->getValue() != DefaultAbi)
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << A->getSpelling() << Triple.getTriple();
+ }
+
// If -march=native, autodetect the feature list.
if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
if (StringRef(A->getValue()) == "native") {
@@ -211,7 +229,84 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
<< D.getOpts().getOptionName(LVIOpt);
}
+ for (const Arg *A : Args.filtered(options::OPT_m_x86_AVX10_Features_Group)) {
+ StringRef Name = A->getOption().getName();
+ A->claim();
+
+ // Skip over "-m".
+ assert(Name.starts_with("m") && "Invalid feature name.");
+ Name = Name.substr(1);
+
+ bool IsNegative = Name.consume_front("no-");
+
+#ifndef NDEBUG
+ assert(Name.starts_with("avx10.") && "Invalid AVX10 feature name.");
+ StringRef Version, Width;
+ std::tie(Version, Width) = Name.substr(6).split('-');
+ assert(Version == "1" && "Invalid AVX10 feature name.");
+ assert((Width == "256" || Width == "512") && "Invalid AVX10 feature name.");
+#endif
+
+ Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
+ }
+
// Now add any that the user explicitly requested on the command line,
// which may override the defaults.
- handleTargetFeaturesGroup(Args, Features, options::OPT_m_x86_Features_Group);
+ for (const Arg *A : Args.filtered(options::OPT_m_x86_Features_Group,
+ options::OPT_mgeneral_regs_only)) {
+ StringRef Name = A->getOption().getName();
+ A->claim();
+
+ // Skip over "-m".
+ assert(Name.starts_with("m") && "Invalid feature name.");
+ Name = Name.substr(1);
+
+ // Replace -mgeneral-regs-only with -x87, -mmx, -sse
+ if (A->getOption().getID() == options::OPT_mgeneral_regs_only) {
+ Features.insert(Features.end(), {"-x87", "-mmx", "-sse"});
+ continue;
+ }
+
+ bool IsNegative = Name.starts_with("no-");
+ if (A->getOption().matches(options::OPT_mapx_features_EQ) ||
+ A->getOption().matches(options::OPT_mno_apx_features_EQ)) {
+
+ for (StringRef Value : A->getValues()) {
+ if (Value == "egpr" || Value == "push2pop2" || Value == "ppx" ||
+ Value == "ndd" || Value == "ccmp" || Value == "cf") {
+ Features.push_back(
+ Args.MakeArgString((IsNegative ? "-" : "+") + Value));
+ continue;
+ }
+ D.Diag(clang::diag::err_drv_unsupported_option_argument)
+ << A->getSpelling() << Value;
+ }
+ continue;
+ }
+ if (IsNegative)
+ Name = Name.substr(3);
+ Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
+ }
+
+ // Enable/disable straight line speculation hardening.
+ if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
+ StringRef Scope = A->getValue();
+ if (Scope == "all") {
+ Features.push_back("+harden-sls-ijmp");
+ Features.push_back("+harden-sls-ret");
+ } else if (Scope == "return") {
+ Features.push_back("+harden-sls-ret");
+ } else if (Scope == "indirect-jmp") {
+ Features.push_back("+harden-sls-ijmp");
+ } else if (Scope != "none") {
+ D.Diag(diag::err_drv_unsupported_option_argument)
+ << A->getSpelling() << Scope;
+ }
+ }
+
+ // -mno-gather, -mno-scatter support
+ if (Args.hasArg(options::OPT_mno_gather))
+ Features.push_back("+prefer-no-gather");
+ if (Args.hasArg(options::OPT_mno_scatter))
+ Features.push_back("+prefer-no-scatter");
}