diff options
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.cpp | 153 |
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"); } |