aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Driver/Tools.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Driver/Tools.cpp')
-rw-r--r--clang/lib/Driver/Tools.cpp1416
1 files changed, 33 insertions, 1383 deletions
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 339f697..01f2efd 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -53,7 +53,7 @@ using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
-static void handleTargetFeaturesGroup(const ArgList &Args,
+void tools::handleTargetFeaturesGroup(const ArgList &Args,
std::vector<StringRef> &Features,
OptSpecifier Group) {
for (const Arg *A : Args.filtered(Group)) {
@@ -71,44 +71,6 @@ static void handleTargetFeaturesGroup(const ArgList &Args,
}
}
-static const char *getSparcAsmModeForCPU(StringRef Name,
- const llvm::Triple &Triple) {
- if (Triple.getArch() == llvm::Triple::sparcv9) {
- return llvm::StringSwitch<const char *>(Name)
- .Case("niagara", "-Av9b")
- .Case("niagara2", "-Av9b")
- .Case("niagara3", "-Av9d")
- .Case("niagara4", "-Av9d")
- .Default("-Av9");
- } else {
- return llvm::StringSwitch<const char *>(Name)
- .Case("v8", "-Av8")
- .Case("supersparc", "-Av8")
- .Case("sparclite", "-Asparclite")
- .Case("f934", "-Asparclite")
- .Case("hypersparc", "-Av8")
- .Case("sparclite86x", "-Asparclite")
- .Case("sparclet", "-Asparclet")
- .Case("tsc701", "-Asparclet")
- .Case("v9", "-Av8plus")
- .Case("ultrasparc", "-Av8plus")
- .Case("ultrasparc3", "-Av8plus")
- .Case("niagara", "-Av8plusb")
- .Case("niagara2", "-Av8plusb")
- .Case("niagara3", "-Av8plusd")
- .Case("niagara4", "-Av8plusd")
- .Case("leon2", "-Av8")
- .Case("at697e", "-Av8")
- .Case("at697f", "-Av8")
- .Case("leon3", "-Av8")
- .Case("ut699", "-Av8")
- .Case("gr712rc", "-Av8")
- .Case("leon4", "-Av8")
- .Case("gr740", "-Av8")
- .Default("-Av8");
- }
-}
-
static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC)) {
if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_P) &&
@@ -789,432 +751,6 @@ static bool isNoCommonDefault(const llvm::Triple &Triple) {
}
}
-// ARM tools start.
-
-// Get SubArch (vN).
-static int getARMSubArchVersionNumber(const llvm::Triple &Triple) {
- llvm::StringRef Arch = Triple.getArchName();
- return llvm::ARM::parseArchVersion(Arch);
-}
-
-// True if M-profile.
-static bool isARMMProfile(const llvm::Triple &Triple) {
- llvm::StringRef Arch = Triple.getArchName();
- unsigned Profile = llvm::ARM::parseArchProfile(Arch);
- return Profile == llvm::ARM::PK_M;
-}
-
-// Get Arch/CPU from args.
-static void getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch,
- llvm::StringRef &CPU, bool FromAs = false) {
- if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
- CPU = A->getValue();
- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
- Arch = A->getValue();
- if (!FromAs)
- return;
-
- for (const Arg *A :
- Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
- StringRef Value = A->getValue();
- if (Value.startswith("-mcpu="))
- CPU = Value.substr(6);
- if (Value.startswith("-march="))
- Arch = Value.substr(7);
- }
-}
-
-// Handle -mhwdiv=.
-// FIXME: Use ARMTargetParser.
-static void getARMHWDivFeatures(const Driver &D, const Arg *A,
- const ArgList &Args, StringRef HWDiv,
- std::vector<StringRef> &Features) {
- unsigned HWDivID = llvm::ARM::parseHWDiv(HWDiv);
- if (!llvm::ARM::getHWDivFeatures(HWDivID, Features))
- D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
-}
-
-// Handle -mfpu=.
-static void getARMFPUFeatures(const Driver &D, const Arg *A,
- const ArgList &Args, StringRef FPU,
- std::vector<StringRef> &Features) {
- unsigned FPUID = llvm::ARM::parseFPU(FPU);
- if (!llvm::ARM::getFPUFeatures(FPUID, Features))
- D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
-}
-
-// Decode ARM features from string like +[no]featureA+[no]featureB+...
-static bool DecodeARMFeatures(const Driver &D, StringRef text,
- std::vector<StringRef> &Features) {
- SmallVector<StringRef, 8> Split;
- text.split(Split, StringRef("+"), -1, false);
-
- for (StringRef Feature : Split) {
- StringRef FeatureName = llvm::ARM::getArchExtFeature(Feature);
- if (!FeatureName.empty())
- Features.push_back(FeatureName);
- else
- return false;
- }
- return true;
-}
-
-// Check if -march is valid by checking if it can be canonicalised and parsed.
-// getARMArch is used here instead of just checking the -march value in order
-// to handle -march=native correctly.
-static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args,
- llvm::StringRef ArchName,
- std::vector<StringRef> &Features,
- const llvm::Triple &Triple) {
- std::pair<StringRef, StringRef> Split = ArchName.split("+");
-
- std::string MArch = arm::getARMArch(ArchName, Triple);
- if (llvm::ARM::parseArch(MArch) == llvm::ARM::AK_INVALID ||
- (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features)))
- D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
-}
-
-// Check -mcpu=. Needs ArchName to handle -mcpu=generic.
-static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args,
- llvm::StringRef CPUName, llvm::StringRef ArchName,
- std::vector<StringRef> &Features,
- const llvm::Triple &Triple) {
- std::pair<StringRef, StringRef> Split = CPUName.split("+");
-
- std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
- if (arm::getLLVMArchSuffixForARM(CPU, ArchName, Triple).empty() ||
- (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features)))
- D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
-}
-
-static bool useAAPCSForMachO(const llvm::Triple &T) {
- // The backend is hardwired to assume AAPCS for M-class processors, ensure
- // the frontend matches that.
- return T.getEnvironment() == llvm::Triple::EABI ||
- T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T);
-}
-
-// Select the float ABI as determined by -msoft-float, -mhard-float, and
-// -mfloat-abi=.
-arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) {
- const Driver &D = TC.getDriver();
- const llvm::Triple &Triple = TC.getEffectiveTriple();
- auto SubArch = getARMSubArchVersionNumber(Triple);
- arm::FloatABI ABI = FloatABI::Invalid;
- if (Arg *A =
- Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
- options::OPT_mfloat_abi_EQ)) {
- if (A->getOption().matches(options::OPT_msoft_float)) {
- ABI = FloatABI::Soft;
- } else if (A->getOption().matches(options::OPT_mhard_float)) {
- ABI = FloatABI::Hard;
- } else {
- ABI = llvm::StringSwitch<arm::FloatABI>(A->getValue())
- .Case("soft", FloatABI::Soft)
- .Case("softfp", FloatABI::SoftFP)
- .Case("hard", FloatABI::Hard)
- .Default(FloatABI::Invalid);
- if (ABI == FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
- D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
- ABI = FloatABI::Soft;
- }
- }
-
- // It is incorrect to select hard float ABI on MachO platforms if the ABI is
- // "apcs-gnu".
- if (Triple.isOSBinFormatMachO() && !useAAPCSForMachO(Triple) &&
- ABI == FloatABI::Hard) {
- D.Diag(diag::err_drv_unsupported_opt_for_target) << A->getAsString(Args)
- << Triple.getArchName();
- }
- }
-
- // If unspecified, choose the default based on the platform.
- if (ABI == FloatABI::Invalid) {
- switch (Triple.getOS()) {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- case llvm::Triple::TvOS: {
- // Darwin defaults to "softfp" for v6 and v7.
- ABI = (SubArch == 6 || SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
- ABI = Triple.isWatchABI() ? FloatABI::Hard : ABI;
- break;
- }
- case llvm::Triple::WatchOS:
- ABI = FloatABI::Hard;
- break;
-
- // FIXME: this is invalid for WindowsCE
- case llvm::Triple::Win32:
- ABI = FloatABI::Hard;
- break;
-
- case llvm::Triple::FreeBSD:
- switch (Triple.getEnvironment()) {
- case llvm::Triple::GNUEABIHF:
- ABI = FloatABI::Hard;
- break;
- default:
- // FreeBSD defaults to soft float
- ABI = FloatABI::Soft;
- break;
- }
- break;
-
- default:
- switch (Triple.getEnvironment()) {
- case llvm::Triple::GNUEABIHF:
- case llvm::Triple::MuslEABIHF:
- case llvm::Triple::EABIHF:
- ABI = FloatABI::Hard;
- break;
- case llvm::Triple::GNUEABI:
- case llvm::Triple::MuslEABI:
- case llvm::Triple::EABI:
- // EABI is always AAPCS, and if it was not marked 'hard', it's softfp
- ABI = FloatABI::SoftFP;
- break;
- case llvm::Triple::Android:
- ABI = (SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
- break;
- default:
- // Assume "soft", but warn the user we are guessing.
- if (Triple.isOSBinFormatMachO() &&
- Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em)
- ABI = FloatABI::Hard;
- else
- ABI = FloatABI::Soft;
-
- if (Triple.getOS() != llvm::Triple::UnknownOS ||
- !Triple.isOSBinFormatMachO())
- D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
- break;
- }
- }
- }
-
- assert(ABI != FloatABI::Invalid && "must select an ABI");
- return ABI;
-}
-
-static void getARMTargetFeatures(const ToolChain &TC,
- const llvm::Triple &Triple,
- const ArgList &Args,
- ArgStringList &CmdArgs,
- std::vector<StringRef> &Features,
- bool ForAS) {
- const Driver &D = TC.getDriver();
-
- bool KernelOrKext =
- Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
- arm::FloatABI ABI = arm::getARMFloatABI(TC, Args);
- const Arg *WaCPU = nullptr, *WaFPU = nullptr;
- const Arg *WaHDiv = nullptr, *WaArch = nullptr;
-
- if (!ForAS) {
- // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
- // yet (it uses the -mfloat-abi and -msoft-float options), and it is
- // stripped out by the ARM target. We should probably pass this a new
- // -target-option, which is handled by the -cc1/-cc1as invocation.
- //
- // FIXME2: For consistency, it would be ideal if we set up the target
- // machine state the same when using the frontend or the assembler. We don't
- // currently do that for the assembler, we pass the options directly to the
- // backend and never even instantiate the frontend TargetInfo. If we did,
- // and used its handleTargetFeatures hook, then we could ensure the
- // assembler and the frontend behave the same.
-
- // Use software floating point operations?
- if (ABI == arm::FloatABI::Soft)
- Features.push_back("+soft-float");
-
- // Use software floating point argument passing?
- if (ABI != arm::FloatABI::Hard)
- Features.push_back("+soft-float-abi");
- } else {
- // Here, we make sure that -Wa,-mfpu/cpu/arch/hwdiv will be passed down
- // to the assembler correctly.
- for (const Arg *A :
- Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
- StringRef Value = A->getValue();
- if (Value.startswith("-mfpu=")) {
- WaFPU = A;
- } else if (Value.startswith("-mcpu=")) {
- WaCPU = A;
- } else if (Value.startswith("-mhwdiv=")) {
- WaHDiv = A;
- } else if (Value.startswith("-march=")) {
- WaArch = A;
- }
- }
- }
-
- // Check -march. ClangAs gives preference to -Wa,-march=.
- const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
- StringRef ArchName;
- if (WaArch) {
- if (ArchArg)
- D.Diag(clang::diag::warn_drv_unused_argument)
- << ArchArg->getAsString(Args);
- ArchName = StringRef(WaArch->getValue()).substr(7);
- checkARMArchName(D, WaArch, Args, ArchName, Features, Triple);
- // FIXME: Set Arch.
- D.Diag(clang::diag::warn_drv_unused_argument) << WaArch->getAsString(Args);
- } else if (ArchArg) {
- ArchName = ArchArg->getValue();
- checkARMArchName(D, ArchArg, Args, ArchName, Features, Triple);
- }
-
- // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=.
- const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
- StringRef CPUName;
- if (WaCPU) {
- if (CPUArg)
- D.Diag(clang::diag::warn_drv_unused_argument)
- << CPUArg->getAsString(Args);
- CPUName = StringRef(WaCPU->getValue()).substr(6);
- checkARMCPUName(D, WaCPU, Args, CPUName, ArchName, Features, Triple);
- } else if (CPUArg) {
- CPUName = CPUArg->getValue();
- checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, Features, Triple);
- }
-
- // Add CPU features for generic CPUs
- if (CPUName == "native") {
- llvm::StringMap<bool> HostFeatures;
- if (llvm::sys::getHostCPUFeatures(HostFeatures))
- for (auto &F : HostFeatures)
- Features.push_back(
- Args.MakeArgString((F.second ? "+" : "-") + F.first()));
- }
-
- // Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=.
- const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
- if (WaFPU) {
- if (FPUArg)
- D.Diag(clang::diag::warn_drv_unused_argument)
- << FPUArg->getAsString(Args);
- getARMFPUFeatures(D, WaFPU, Args, StringRef(WaFPU->getValue()).substr(6),
- Features);
- } else if (FPUArg) {
- getARMFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features);
- }
-
- // Honor -mhwdiv=. ClangAs gives preference to -Wa,-mhwdiv=.
- const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ);
- if (WaHDiv) {
- if (HDivArg)
- D.Diag(clang::diag::warn_drv_unused_argument)
- << HDivArg->getAsString(Args);
- getARMHWDivFeatures(D, WaHDiv, Args,
- StringRef(WaHDiv->getValue()).substr(8), Features);
- } else if (HDivArg)
- getARMHWDivFeatures(D, HDivArg, Args, HDivArg->getValue(), Features);
-
- // Setting -msoft-float effectively disables NEON because of the GCC
- // implementation, although the same isn't true of VFP or VFP3.
- if (ABI == arm::FloatABI::Soft) {
- Features.push_back("-neon");
- // Also need to explicitly disable features which imply NEON.
- Features.push_back("-crypto");
- }
-
- // En/disable crc code generation.
- if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
- if (A->getOption().matches(options::OPT_mcrc))
- Features.push_back("+crc");
- else
- Features.push_back("-crc");
- }
-
- // Look for the last occurrence of -mlong-calls or -mno-long-calls. If
- // neither options are specified, see if we are compiling for kernel/kext and
- // decide whether to pass "+long-calls" based on the OS and its version.
- if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
- options::OPT_mno_long_calls)) {
- if (A->getOption().matches(options::OPT_mlong_calls))
- Features.push_back("+long-calls");
- } else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
- !Triple.isWatchOS()) {
- Features.push_back("+long-calls");
- }
-
- // Generate execute-only output (no data access to code sections).
- // Supported only on ARMv6T2 and ARMv7 and above.
- // Cannot be combined with -mno-movt or -mlong-calls
- if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, options::OPT_mno_execute_only)) {
- if (A->getOption().matches(options::OPT_mexecute_only)) {
- if (getARMSubArchVersionNumber(Triple) < 7 &&
- llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::AK_ARMV6T2)
- D.Diag(diag::err_target_unsupported_execute_only) << Triple.getArchName();
- else if (Arg *B = Args.getLastArg(options::OPT_mno_movt))
- D.Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args);
- // Long calls create constant pool entries and have not yet been fixed up
- // to play nicely with execute-only. Hence, they cannot be used in
- // execute-only code for now
- else if (Arg *B = Args.getLastArg(options::OPT_mlong_calls, options::OPT_mno_long_calls)) {
- if (B->getOption().matches(options::OPT_mlong_calls))
- D.Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args);
- }
-
- CmdArgs.push_back("-backend-option");
- CmdArgs.push_back("-arm-execute-only");
- }
- }
-
- // Kernel code has more strict alignment requirements.
- if (KernelOrKext)
- Features.push_back("+strict-align");
- else if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
- options::OPT_munaligned_access)) {
- if (A->getOption().matches(options::OPT_munaligned_access)) {
- // No v6M core supports unaligned memory access (v6M ARM ARM A3.2).
- if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
- D.Diag(diag::err_target_unsupported_unaligned) << "v6m";
- // v8M Baseline follows on from v6M, so doesn't support unaligned memory
- // access either.
- else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline)
- D.Diag(diag::err_target_unsupported_unaligned) << "v8m.base";
- } else
- Features.push_back("+strict-align");
- } else {
- // Assume pre-ARMv6 doesn't support unaligned accesses.
- //
- // ARMv6 may or may not support unaligned accesses depending on the
- // SCTLR.U bit, which is architecture-specific. We assume ARMv6
- // Darwin and NetBSD targets support unaligned accesses, and others don't.
- //
- // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit
- // which raises an alignment fault on unaligned accesses. Linux
- // defaults this bit to 0 and handles it as a system-wide (not
- // per-process) setting. It is therefore safe to assume that ARMv7+
- // Linux targets support unaligned accesses. The same goes for NaCl.
- //
- // The above behavior is consistent with GCC.
- int VersionNum = getARMSubArchVersionNumber(Triple);
- if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
- if (VersionNum < 6 ||
- Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
- Features.push_back("+strict-align");
- } else if (Triple.isOSLinux() || Triple.isOSNaCl()) {
- if (VersionNum < 7)
- Features.push_back("+strict-align");
- } else
- Features.push_back("+strict-align");
- }
-
- // llvm does not support reserving registers in general. There is support
- // for reserving r9 on ARM though (defined as a platform-specific register
- // in ARM EABI).
- if (Args.hasArg(options::OPT_ffixed_r9))
- Features.push_back("+reserve-r9");
-
- // The kext linker doesn't know how to deal with movw/movt.
- if (KernelOrKext || Args.hasArg(options::OPT_mno_movt))
- Features.push_back("+no-movt");
-}
-
void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
ArgStringList &CmdArgs, bool KernelOrKext) const {
// Select the ABI to use.
@@ -1224,7 +760,7 @@ void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
ABIName = A->getValue();
} else if (Triple.isOSBinFormatMachO()) {
- if (useAAPCSForMachO(Triple)) {
+ if (arm::useAAPCSForMachO(Triple)) {
ABIName = "aapcs";
} else if (Triple.isWatchABI()) {
ABIName = "aapcs16";
@@ -1292,34 +828,6 @@ void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
options::OPT_mno_implicit_float, true))
CmdArgs.push_back("-no-implicit-float");
}
-// ARM tools end.
-
-/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
-/// targeting. Set \p A to the Arg corresponding to the -mcpu or -mtune
-/// arguments if they are provided, or to nullptr otherwise.
-static std::string getAArch64TargetCPU(const ArgList &Args, Arg *&A) {
- std::string CPU;
- // If we have -mtune or -mcpu, use that.
- if ((A = Args.getLastArg(options::OPT_mtune_EQ))) {
- CPU = StringRef(A->getValue()).lower();
- } else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
- StringRef Mcpu = A->getValue();
- CPU = Mcpu.split("+").first.lower();
- }
-
- // Handle CPU name is 'native'.
- if (CPU == "native")
- return llvm::sys::getHostCPUName();
- else if (CPU.size())
- return CPU;
-
- // Make sure we pick "cyclone" if -arch is used.
- // FIXME: Should this be picked by checking the target triple instead?
- if (Args.getLastArg(options::OPT_arch))
- return "cyclone";
-
- return "generic";
-}
void Clang::AddAArch64TargetArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
@@ -1369,158 +877,7 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
}
}
-// Get CPU and ABI names. They are not independent
-// so we have to calculate them together.
-void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple,
- StringRef &CPUName, StringRef &ABIName) {
- const char *DefMips32CPU = "mips32r2";
- const char *DefMips64CPU = "mips64r2";
-
- // MIPS32r6 is the default for mips(el)?-img-linux-gnu and MIPS64r6 is the
- // default for mips64(el)?-img-linux-gnu.
- if (Triple.getVendor() == llvm::Triple::ImaginationTechnologies &&
- Triple.getEnvironment() == llvm::Triple::GNU) {
- DefMips32CPU = "mips32r6";
- DefMips64CPU = "mips64r6";
- }
-
- // MIPS64r6 is the default for Android MIPS64 (mips64el-linux-android).
- if (Triple.isAndroid()) {
- DefMips32CPU = "mips32";
- DefMips64CPU = "mips64r6";
- }
-
- // MIPS3 is the default for mips64*-unknown-openbsd.
- if (Triple.getOS() == llvm::Triple::OpenBSD)
- DefMips64CPU = "mips3";
-
- if (Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ))
- CPUName = A->getValue();
-
- if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
- ABIName = A->getValue();
- // Convert a GNU style Mips ABI name to the name
- // accepted by LLVM Mips backend.
- ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
- .Case("32", "o32")
- .Case("64", "n64")
- .Default(ABIName);
- }
-
- // Setup default CPU and ABI names.
- if (CPUName.empty() && ABIName.empty()) {
- switch (Triple.getArch()) {
- default:
- llvm_unreachable("Unexpected triple arch name");
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- CPUName = DefMips32CPU;
- break;
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- CPUName = DefMips64CPU;
- break;
- }
- }
-
- if (ABIName.empty() &&
- (Triple.getVendor() == llvm::Triple::MipsTechnologies ||
- Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) {
- ABIName = llvm::StringSwitch<const char *>(CPUName)
- .Case("mips1", "o32")
- .Case("mips2", "o32")
- .Case("mips3", "n64")
- .Case("mips4", "n64")
- .Case("mips5", "n64")
- .Case("mips32", "o32")
- .Case("mips32r2", "o32")
- .Case("mips32r3", "o32")
- .Case("mips32r5", "o32")
- .Case("mips32r6", "o32")
- .Case("mips64", "n64")
- .Case("mips64r2", "n64")
- .Case("mips64r3", "n64")
- .Case("mips64r5", "n64")
- .Case("mips64r6", "n64")
- .Case("octeon", "n64")
- .Case("p5600", "o32")
- .Default("");
- }
-
- if (ABIName.empty()) {
- // Deduce ABI name from the target triple.
- if (Triple.getArch() == llvm::Triple::mips ||
- Triple.getArch() == llvm::Triple::mipsel)
- ABIName = "o32";
- else
- ABIName = "n64";
- }
-
- if (CPUName.empty()) {
- // Deduce CPU name from ABI name.
- CPUName = llvm::StringSwitch<const char *>(ABIName)
- .Case("o32", DefMips32CPU)
- .Cases("n32", "n64", DefMips64CPU)
- .Default("");
- }
-
- // FIXME: Warn on inconsistent use of -march and -mabi.
-}
-
-std::string mips::getMipsABILibSuffix(const ArgList &Args,
- const llvm::Triple &Triple) {
- StringRef CPUName, ABIName;
- tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
- return llvm::StringSwitch<std::string>(ABIName)
- .Case("o32", "")
- .Case("n32", "32")
- .Case("n64", "64");
-}
-
-// Convert ABI name to the GNU tools acceptable variant.
-static StringRef getGnuCompatibleMipsABIName(StringRef ABI) {
- return llvm::StringSwitch<llvm::StringRef>(ABI)
- .Case("o32", "32")
- .Case("n64", "64")
- .Default(ABI);
-}
-
-// Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
-// and -mfloat-abi=.
-static mips::FloatABI getMipsFloatABI(const Driver &D, const ArgList &Args) {
- mips::FloatABI ABI = mips::FloatABI::Invalid;
- if (Arg *A =
- Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
- options::OPT_mfloat_abi_EQ)) {
- if (A->getOption().matches(options::OPT_msoft_float))
- ABI = mips::FloatABI::Soft;
- else if (A->getOption().matches(options::OPT_mhard_float))
- ABI = mips::FloatABI::Hard;
- else {
- ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue())
- .Case("soft", mips::FloatABI::Soft)
- .Case("hard", mips::FloatABI::Hard)
- .Default(mips::FloatABI::Invalid);
- if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
- D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
- ABI = mips::FloatABI::Hard;
- }
- }
- }
-
- // If unspecified, choose the default based on the platform.
- if (ABI == mips::FloatABI::Invalid) {
- // Assume "hard", because it's a default value used by gcc.
- // When we start to recognize specific target MIPS processors,
- // we will be able to select the default more correctly.
- ABI = mips::FloatABI::Hard;
- }
-
- assert(ABI != mips::FloatABI::Invalid && "must select an ABI");
- return ABI;
-}
-
-static void AddTargetFeature(const ArgList &Args,
+void tools::AddTargetFeature(const ArgList &Args,
std::vector<StringRef> &Features,
OptSpecifier OnOpt, OptSpecifier OffOpt,
StringRef FeatureName) {
@@ -1532,129 +889,6 @@ static void AddTargetFeature(const ArgList &Args,
}
}
-static void getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
- const ArgList &Args,
- std::vector<StringRef> &Features) {
- StringRef CPUName;
- StringRef ABIName;
- mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
- ABIName = getGnuCompatibleMipsABIName(ABIName);
-
- // Historically, PIC code for MIPS was associated with -mabicalls, a.k.a
- // SVR4 abicalls. Static code does not use SVR4 calling sequences. An ABI
- // extension was developed by Richard Sandiford & Code Sourcery to support
- // static code calling PIC code (CPIC). For O32 and N32 this means we have
- // several combinations of PIC/static and abicalls. Pure static, static
- // with the CPIC extension, and pure PIC code.
-
- // At final link time, O32 and N32 with CPIC will have another section
- // added to the binary which contains the stub functions to perform
- // any fixups required for PIC code.
-
- // For N64, the situation is more regular: code can either be static
- // (non-abicalls) or PIC (abicalls). GCC has traditionally picked PIC code
- // code for N64. Since Clang has already built the relocation model portion
- // of the commandline, we pick add +noabicalls feature in the N64 static
- // case.
-
- // The is another case to be accounted for: -msym32, which enforces that all
- // symbols have 32 bits in size. In this case, N64 can in theory use CPIC
- // but it is unsupported.
-
- // The combinations for N64 are:
- // a) Static without abicalls and 64bit symbols.
- // b) Static with abicalls and 32bit symbols.
- // c) PIC with abicalls and 64bit symbols.
-
- // For case (a) we need to add +noabicalls for N64.
-
- bool IsN64 = ABIName == "64";
- bool NonPIC = false;
-
- Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
- options::OPT_fpic, options::OPT_fno_pic,
- options::OPT_fPIE, options::OPT_fno_PIE,
- options::OPT_fpie, options::OPT_fno_pie);
- if (LastPICArg) {
- Option O = LastPICArg->getOption();
- NonPIC =
- (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) ||
- O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie));
- }
-
- if (IsN64 && NonPIC) {
- Features.push_back("+noabicalls");
- } else {
- AddTargetFeature(Args, Features, options::OPT_mno_abicalls,
- options::OPT_mabicalls, "noabicalls");
- }
-
- mips::FloatABI FloatABI = getMipsFloatABI(D, Args);
- if (FloatABI == mips::FloatABI::Soft) {
- // FIXME: Note, this is a hack. We need to pass the selected float
- // mode to the MipsTargetInfoBase to define appropriate macros there.
- // Now it is the only method.
- Features.push_back("+soft-float");
- }
-
- if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
- StringRef Val = StringRef(A->getValue());
- if (Val == "2008") {
- if (mips::getSupportedNanEncoding(CPUName) & mips::Nan2008)
- Features.push_back("+nan2008");
- else {
- Features.push_back("-nan2008");
- D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
- }
- } else if (Val == "legacy") {
- if (mips::getSupportedNanEncoding(CPUName) & mips::NanLegacy)
- Features.push_back("-nan2008");
- else {
- Features.push_back("+nan2008");
- D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
- }
- } else
- D.Diag(diag::err_drv_unsupported_option_argument)
- << A->getOption().getName() << Val;
- }
-
- AddTargetFeature(Args, Features, options::OPT_msingle_float,
- options::OPT_mdouble_float, "single-float");
- AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
- "mips16");
- AddTargetFeature(Args, Features, options::OPT_mmicromips,
- options::OPT_mno_micromips, "micromips");
- AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
- "dsp");
- AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
- "dspr2");
- AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
- "msa");
-
- // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
- // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
- // nooddspreg.
- if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
- options::OPT_mfp64)) {
- if (A->getOption().matches(options::OPT_mfp32))
- Features.push_back(Args.MakeArgString("-fp64"));
- else if (A->getOption().matches(options::OPT_mfpxx)) {
- Features.push_back(Args.MakeArgString("+fpxx"));
- Features.push_back(Args.MakeArgString("+nooddspreg"));
- } else
- Features.push_back(Args.MakeArgString("+fp64"));
- } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
- Features.push_back(Args.MakeArgString("+fpxx"));
- Features.push_back(Args.MakeArgString("+nooddspreg"));
- } else if (mips::isFP64ADefault(Triple, CPUName)) {
- Features.push_back(Args.MakeArgString("+fp64"));
- Features.push_back(Args.MakeArgString("+nooddspreg"));
- }
-
- AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
- options::OPT_modd_spreg, "nooddspreg");
-}
-
void Clang::AddMIPSTargetArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
const Driver &D = getToolChain().getDriver();
@@ -1666,7 +900,7 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
CmdArgs.push_back("-target-abi");
CmdArgs.push_back(ABIName.data());
- mips::FloatABI ABI = getMipsFloatABI(D, Args);
+ mips::FloatABI ABI = mips::getMipsFloatABI(D, Args);
if (ABI == mips::FloatABI::Soft) {
// Floating point operations and argument passing are soft.
CmdArgs.push_back("-msoft-float");
@@ -1723,115 +957,6 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
}
}
-/// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting.
-static std::string getPPCTargetCPU(const ArgList &Args) {
- if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
- StringRef CPUName = A->getValue();
-
- if (CPUName == "native") {
- std::string CPU = llvm::sys::getHostCPUName();
- if (!CPU.empty() && CPU != "generic")
- return CPU;
- else
- return "";
- }
-
- return llvm::StringSwitch<const char *>(CPUName)
- .Case("common", "generic")
- .Case("440", "440")
- .Case("440fp", "440")
- .Case("450", "450")
- .Case("601", "601")
- .Case("602", "602")
- .Case("603", "603")
- .Case("603e", "603e")
- .Case("603ev", "603ev")
- .Case("604", "604")
- .Case("604e", "604e")
- .Case("620", "620")
- .Case("630", "pwr3")
- .Case("G3", "g3")
- .Case("7400", "7400")
- .Case("G4", "g4")
- .Case("7450", "7450")
- .Case("G4+", "g4+")
- .Case("750", "750")
- .Case("970", "970")
- .Case("G5", "g5")
- .Case("a2", "a2")
- .Case("a2q", "a2q")
- .Case("e500mc", "e500mc")
- .Case("e5500", "e5500")
- .Case("power3", "pwr3")
- .Case("power4", "pwr4")
- .Case("power5", "pwr5")
- .Case("power5x", "pwr5x")
- .Case("power6", "pwr6")
- .Case("power6x", "pwr6x")
- .Case("power7", "pwr7")
- .Case("power8", "pwr8")
- .Case("power9", "pwr9")
- .Case("pwr3", "pwr3")
- .Case("pwr4", "pwr4")
- .Case("pwr5", "pwr5")
- .Case("pwr5x", "pwr5x")
- .Case("pwr6", "pwr6")
- .Case("pwr6x", "pwr6x")
- .Case("pwr7", "pwr7")
- .Case("pwr8", "pwr8")
- .Case("pwr9", "pwr9")
- .Case("powerpc", "ppc")
- .Case("powerpc64", "ppc64")
- .Case("powerpc64le", "ppc64le")
- .Default("");
- }
-
- return "";
-}
-
-static void getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
- const ArgList &Args,
- std::vector<StringRef> &Features) {
- handleTargetFeaturesGroup(Args, Features, options::OPT_m_ppc_Features_Group);
-
- ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args);
- if (FloatABI == ppc::FloatABI::Soft)
- Features.push_back("-hard-float");
-
- // Altivec is a bit weird, allow overriding of the Altivec feature here.
- AddTargetFeature(Args, Features, options::OPT_faltivec,
- options::OPT_fno_altivec, "altivec");
-}
-
-ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) {
- ppc::FloatABI ABI = ppc::FloatABI::Invalid;
- if (Arg *A =
- Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
- options::OPT_mfloat_abi_EQ)) {
- if (A->getOption().matches(options::OPT_msoft_float))
- ABI = ppc::FloatABI::Soft;
- else if (A->getOption().matches(options::OPT_mhard_float))
- ABI = ppc::FloatABI::Hard;
- else {
- ABI = llvm::StringSwitch<ppc::FloatABI>(A->getValue())
- .Case("soft", ppc::FloatABI::Soft)
- .Case("hard", ppc::FloatABI::Hard)
- .Default(ppc::FloatABI::Invalid);
- if (ABI == ppc::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
- D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
- ABI = ppc::FloatABI::Hard;
- }
- }
- }
-
- // If unspecified, choose the default based on the platform.
- if (ABI == ppc::FloatABI::Invalid) {
- ABI = ppc::FloatABI::Hard;
- }
-
- return ABI;
-}
-
void Clang::AddPPCTargetArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
// Select the ABI to use.
@@ -1889,11 +1014,6 @@ void Clang::AddPPCTargetArgs(const ArgList &Args,
}
}
-bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) {
- Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
- return A && (A->getValue() == StringRef(Value));
-}
-
/// Get the (LLVM) name of the R600 gpu we are targeting.
static std::string getR600TargetGPU(const ArgList &Args) {
if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
@@ -1918,48 +1038,6 @@ static std::string getLanaiTargetCPU(const ArgList &Args) {
return "";
}
-sparc::FloatABI sparc::getSparcFloatABI(const Driver &D,
- const ArgList &Args) {
- sparc::FloatABI ABI = sparc::FloatABI::Invalid;
- if (Arg *A =
- Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
- options::OPT_mfloat_abi_EQ)) {
- if (A->getOption().matches(options::OPT_msoft_float))
- ABI = sparc::FloatABI::Soft;
- else if (A->getOption().matches(options::OPT_mhard_float))
- ABI = sparc::FloatABI::Hard;
- else {
- ABI = llvm::StringSwitch<sparc::FloatABI>(A->getValue())
- .Case("soft", sparc::FloatABI::Soft)
- .Case("hard", sparc::FloatABI::Hard)
- .Default(sparc::FloatABI::Invalid);
- if (ABI == sparc::FloatABI::Invalid &&
- !StringRef(A->getValue()).empty()) {
- D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
- ABI = sparc::FloatABI::Hard;
- }
- }
- }
-
- // If unspecified, choose the default based on the platform.
- // Only the hard-float ABI on Sparc is standardized, and it is the
- // default. GCC also supports a nonstandard soft-float ABI mode, also
- // implemented in LLVM. However as this is not standard we set the default
- // to be hard-float.
- if (ABI == sparc::FloatABI::Invalid) {
- ABI = sparc::FloatABI::Hard;
- }
-
- return ABI;
-}
-
-static void getSparcTargetFeatures(const Driver &D, const ArgList &Args,
- std::vector<StringRef> &Features) {
- sparc::FloatABI FloatABI = sparc::getSparcFloatABI(D, Args);
- if (FloatABI == sparc::FloatABI::Soft)
- Features.push_back("+soft-float");
-}
-
void Clang::AddSparcTargetArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
sparc::FloatABI FloatABI =
@@ -1984,119 +1062,6 @@ void Clang::AddSystemZTargetArgs(const ArgList &Args,
CmdArgs.push_back("-mbackchain");
}
-static const char *getSystemZTargetCPU(const ArgList &Args) {
- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
- return A->getValue();
- return "z10";
-}
-
-static void getSystemZTargetFeatures(const ArgList &Args,
- std::vector<StringRef> &Features) {
- // -m(no-)htm overrides use of the transactional-execution facility.
- if (Arg *A = Args.getLastArg(options::OPT_mhtm, options::OPT_mno_htm)) {
- if (A->getOption().matches(options::OPT_mhtm))
- Features.push_back("+transactional-execution");
- else
- Features.push_back("-transactional-execution");
- }
- // -m(no-)vx overrides use of the vector facility.
- if (Arg *A = Args.getLastArg(options::OPT_mvx, options::OPT_mno_vx)) {
- if (A->getOption().matches(options::OPT_mvx))
- Features.push_back("+vector");
- else
- Features.push_back("-vector");
- }
-}
-
-static const char *getX86TargetCPU(const ArgList &Args,
- const llvm::Triple &Triple) {
- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
- if (StringRef(A->getValue()) != "native") {
- if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
- return "core-avx2";
-
- return A->getValue();
- }
-
- // 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.
- std::string CPU = llvm::sys::getHostCPUName();
- if (!CPU.empty() && CPU != "generic")
- return Args.MakeArgString(CPU);
- }
-
- if (const Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
- // Mapping built by referring to X86TargetInfo::getDefaultFeatures().
- StringRef Arch = A->getValue();
- const char *CPU;
- if (Triple.getArch() == llvm::Triple::x86) {
- CPU = llvm::StringSwitch<const char *>(Arch)
- .Case("IA32", "i386")
- .Case("SSE", "pentium3")
- .Case("SSE2", "pentium4")
- .Case("AVX", "sandybridge")
- .Case("AVX2", "haswell")
- .Default(nullptr);
- } else {
- CPU = llvm::StringSwitch<const char *>(Arch)
- .Case("AVX", "sandybridge")
- .Case("AVX2", "haswell")
- .Default(nullptr);
- }
- if (CPU)
- return CPU;
- }
-
- // Select the default CPU if none was given (or detection failed).
-
- if (Triple.getArch() != llvm::Triple::x86_64 &&
- Triple.getArch() != llvm::Triple::x86)
- return nullptr; // This routine is only handling x86 targets.
-
- bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
-
- // FIXME: Need target hooks.
- if (Triple.isOSDarwin()) {
- if (Triple.getArchName() == "x86_64h")
- return "core-avx2";
- // macosx10.12 drops support for all pre-Penryn Macs.
- // Simulators can still run on 10.11 though, like Xcode.
- if (Triple.isMacOSX() && !Triple.isOSVersionLT(10, 12))
- return "penryn";
- // 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())
- return "btver2";
-
- // On Android use targets compatible with gcc
- if (Triple.isAndroid())
- return Is64Bit ? "x86-64" : "i686";
-
- // Everything else goes to x86-64 in 64-bit mode.
- if (Is64Bit)
- return "x86-64";
-
- switch (Triple.getOS()) {
- case llvm::Triple::FreeBSD:
- case llvm::Triple::NetBSD:
- case llvm::Triple::OpenBSD:
- return "i486";
- case llvm::Triple::Haiku:
- return "i586";
- case llvm::Triple::Bitrig:
- return "i686";
- default:
- // Fallback to p4.
- return "pentium4";
- }
-}
-
/// Get the (LLVM) name of the WebAssembly cpu we are targeting.
static StringRef getWebAssemblyTargetCPU(const ArgList &Args) {
// If we have -mcpu=, use that.
@@ -2116,8 +1081,8 @@ static StringRef getWebAssemblyTargetCPU(const ArgList &Args) {
return "generic";
}
-static std::string getCPUName(const ArgList &Args, const llvm::Triple &T,
- bool FromAs = false) {
+std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T,
+ bool FromAs) {
Arg *A;
switch (T.getArch()) {
@@ -2126,14 +1091,14 @@ static std::string getCPUName(const ArgList &Args, const llvm::Triple &T,
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
- return getAArch64TargetCPU(Args, A);
+ return aarch64::getAArch64TargetCPU(Args, A);
case llvm::Triple::arm:
case llvm::Triple::armeb:
case llvm::Triple::thumb:
case llvm::Triple::thumbeb: {
StringRef MArch, MCPU;
- getARMArchCPUFromArgs(Args, MArch, MCPU, FromAs);
+ arm::getARMArchCPUFromArgs(Args, MArch, MCPU, FromAs);
return arm::getARMTargetCPU(MCPU, MArch, T);
}
case llvm::Triple::mips:
@@ -2155,7 +1120,7 @@ static std::string getCPUName(const ArgList &Args, const llvm::Triple &T,
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
case llvm::Triple::ppc64le: {
- std::string TargetCPUName = getPPCTargetCPU(Args);
+ std::string TargetCPUName = ppc::getPPCTargetCPU(Args);
// LLVM may default to generating code for the native CPU,
// but, like gcc, we default to a more generic option for
// each architecture. (except on Darwin)
@@ -2179,7 +1144,7 @@ static std::string getCPUName(const ArgList &Args, const llvm::Triple &T,
case llvm::Triple::x86:
case llvm::Triple::x86_64:
- return getX86TargetCPU(Args, T);
+ return x86::getX86TargetCPU(Args, T);
case llvm::Triple::hexagon:
return "hexagon" +
@@ -2189,7 +1154,7 @@ static std::string getCPUName(const ArgList &Args, const llvm::Triple &T,
return getLanaiTargetCPU(Args);
case llvm::Triple::systemz:
- return getSystemZTargetCPU(Args);
+ return systemz::getSystemZTargetCPU(Args);
case llvm::Triple::r600:
case llvm::Triple::amdgcn:
@@ -2423,70 +1388,6 @@ static void ParseMRecip(const Driver &D, const ArgList &Args,
OutStrings.push_back(Args.MakeArgString(Out));
}
-static void getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
- const ArgList &Args,
- std::vector<StringRef> &Features) {
- // If -march=native, autodetect the feature list.
- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
- if (StringRef(A->getValue()) == "native") {
- llvm::StringMap<bool> HostFeatures;
- if (llvm::sys::getHostCPUFeatures(HostFeatures))
- for (auto &F : HostFeatures)
- Features.push_back(
- Args.MakeArgString((F.second ? "+" : "-") + F.first()));
- }
- }
-
- if (Triple.getArchName() == "x86_64h") {
- // x86_64h implies quite a few of the more modern subtarget features
- // for Haswell class CPUs, but not all of them. Opt-out of a few.
- Features.push_back("-rdrnd");
- Features.push_back("-aes");
- Features.push_back("-pclmul");
- Features.push_back("-rtm");
- Features.push_back("-hle");
- Features.push_back("-fsgsbase");
- }
-
- const llvm::Triple::ArchType ArchType = Triple.getArch();
- // Add features to be compatible with gcc for Android.
- if (Triple.isAndroid()) {
- if (ArchType == llvm::Triple::x86_64) {
- Features.push_back("+sse4.2");
- Features.push_back("+popcnt");
- } else
- Features.push_back("+ssse3");
- }
-
- // Set features according to the -arch flag on MSVC.
- if (Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
- StringRef Arch = A->getValue();
- bool ArchUsed = false;
- // First, look for flags that are shared in x86 and x86-64.
- if (ArchType == llvm::Triple::x86_64 || ArchType == llvm::Triple::x86) {
- if (Arch == "AVX" || Arch == "AVX2") {
- ArchUsed = true;
- Features.push_back(Args.MakeArgString("+" + Arch.lower()));
- }
- }
- // Then, look for x86-specific flags.
- if (ArchType == llvm::Triple::x86) {
- if (Arch == "IA32") {
- ArchUsed = true;
- } else if (Arch == "SSE" || Arch == "SSE2") {
- ArchUsed = true;
- Features.push_back(Args.MakeArgString("+" + Arch.lower()));
- }
- }
- if (!ArchUsed)
- D.Diag(clang::diag::warn_drv_unused_argument) << A->getAsString(Args);
- }
-
- // 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);
-}
-
void Clang::AddX86TargetArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true) ||
@@ -2582,155 +1483,6 @@ void Clang::AddWebAssemblyTargetArgs(const ArgList &Args,
}
}
-// Decode AArch64 features from string like +[no]featureA+[no]featureB+...
-static bool DecodeAArch64Features(const Driver &D, StringRef text,
- std::vector<StringRef> &Features) {
- SmallVector<StringRef, 8> Split;
- text.split(Split, StringRef("+"), -1, false);
-
- for (StringRef Feature : Split) {
- StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
- if (!FeatureName.empty())
- Features.push_back(FeatureName);
- else if (Feature == "neon" || Feature == "noneon")
- D.Diag(diag::err_drv_no_neon_modifier);
- else
- return false;
- }
- return true;
-}
-
-// Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
-// decode CPU and feature.
-static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
- std::vector<StringRef> &Features) {
- std::pair<StringRef, StringRef> Split = Mcpu.split("+");
- CPU = Split.first;
-
- if (CPU == "generic") {
- Features.push_back("+neon");
- } else {
- unsigned ArchKind = llvm::AArch64::parseCPUArch(CPU);
- if (!llvm::AArch64::getArchFeatures(ArchKind, Features))
- return false;
-
- unsigned Extension = llvm::AArch64::getDefaultExtensions(CPU, ArchKind);
- if (!llvm::AArch64::getExtensionFeatures(Extension, Features))
- return false;
- }
-
- if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features))
- return false;
-
- return true;
-}
-
-static bool
-getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
- const ArgList &Args,
- std::vector<StringRef> &Features) {
- std::string MarchLowerCase = March.lower();
- std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+");
-
- unsigned ArchKind = llvm::AArch64::parseArch(Split.first);
- if (ArchKind == static_cast<unsigned>(llvm::AArch64::ArchKind::AK_INVALID) ||
- !llvm::AArch64::getArchFeatures(ArchKind, Features) ||
- (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features)))
- return false;
-
- return true;
-}
-
-static bool
-getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
- const ArgList &Args,
- std::vector<StringRef> &Features) {
- StringRef CPU;
- std::string McpuLowerCase = Mcpu.lower();
- if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Features))
- return false;
-
- return true;
-}
-
-static bool
-getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
- const ArgList &Args,
- std::vector<StringRef> &Features) {
- std::string MtuneLowerCase = Mtune.lower();
- // Handle CPU name is 'native'.
- if (MtuneLowerCase == "native")
- MtuneLowerCase = llvm::sys::getHostCPUName();
- if (MtuneLowerCase == "cyclone") {
- Features.push_back("+zcm");
- Features.push_back("+zcz");
- }
- return true;
-}
-
-static bool
-getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
- const ArgList &Args,
- std::vector<StringRef> &Features) {
- StringRef CPU;
- std::vector<StringRef> DecodedFeature;
- std::string McpuLowerCase = Mcpu.lower();
- if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, DecodedFeature))
- return false;
-
- return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
-}
-
-static void getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
- std::vector<StringRef> &Features) {
- Arg *A;
- bool success = true;
- // Enable NEON by default.
- Features.push_back("+neon");
- if ((A = Args.getLastArg(options::OPT_march_EQ)))
- success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
- else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
- success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
- else if (Args.hasArg(options::OPT_arch))
- success = getAArch64ArchFeaturesFromMcpu(D, getAArch64TargetCPU(Args, A),
- Args, Features);
-
- if (success && (A = Args.getLastArg(options::OPT_mtune_EQ)))
- success =
- getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features);
- else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
- success =
- getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
- else if (success && Args.hasArg(options::OPT_arch))
- success = getAArch64MicroArchFeaturesFromMcpu(
- D, getAArch64TargetCPU(Args, A), Args, Features);
-
- if (!success)
- D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
-
- if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
- Features.push_back("-fp-armv8");
- Features.push_back("-crypto");
- Features.push_back("-neon");
- }
-
- // En/disable crc
- if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
- if (A->getOption().matches(options::OPT_mcrc))
- Features.push_back("+crc");
- else
- Features.push_back("-crc");
- }
-
- if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
- options::OPT_munaligned_access))
- if (A->getOption().matches(options::OPT_mno_unaligned_access))
- Features.push_back("+strict-align");
-
- if (Args.hasArg(options::OPT_ffixed_x18))
- Features.push_back("+reserve-x18");
-}
-
static void getHexagonTargetFeatures(const ArgList &Args,
std::vector<StringRef> &Features) {
handleTargetFeaturesGroup(Args, Features,
@@ -2780,31 +1532,31 @@ static void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
- getMIPSTargetFeatures(D, Triple, Args, Features);
+ mips::getMIPSTargetFeatures(D, Triple, Args, Features);
break;
case llvm::Triple::arm:
case llvm::Triple::armeb:
case llvm::Triple::thumb:
case llvm::Triple::thumbeb:
- getARMTargetFeatures(TC, Triple, Args, CmdArgs, Features, ForAS);
+ arm::getARMTargetFeatures(TC, Triple, Args, CmdArgs, Features, ForAS);
break;
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
case llvm::Triple::ppc64le:
- getPPCTargetFeatures(D, Triple, Args, Features);
+ ppc::getPPCTargetFeatures(D, Triple, Args, Features);
break;
case llvm::Triple::systemz:
- getSystemZTargetFeatures(Args, Features);
+ systemz::getSystemZTargetFeatures(Args, Features);
break;
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
- getAArch64TargetFeatures(D, Args, Features);
+ aarch64::getAArch64TargetFeatures(D, Args, Features);
break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
- getX86TargetFeatures(D, Triple, Args, Features);
+ x86::getX86TargetFeatures(D, Triple, Args, Features);
break;
case llvm::Triple::hexagon:
getHexagonTargetFeatures(Args, Features);
@@ -2816,7 +1568,7 @@ static void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
case llvm::Triple::sparcv9:
- getSparcTargetFeatures(D, Args, Features);
+ sparc::getSparcTargetFeatures(D, Args, Features);
break;
case llvm::Triple::r600:
case llvm::Triple::amdgcn:
@@ -7982,112 +6734,10 @@ void arm::appendEBLinkFlags(const ArgList &Args, ArgStringList &CmdArgs,
// ARMv7 (and later) and ARMv6-M do not support BE-32, so instruct the linker
// to generate BE-8 executables.
- if (getARMSubArchVersionNumber(Triple) >= 7 || isARMMProfile(Triple))
+ if (arm::getARMSubArchVersionNumber(Triple) >= 7 || arm::isARMMProfile(Triple))
CmdArgs.push_back("--be8");
}
-mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) {
- // Strictly speaking, mips32r2 and mips64r2 are NanLegacy-only since Nan2008
- // was first introduced in Release 3. However, other compilers have
- // traditionally allowed it for Release 2 so we should do the same.
- return (NanEncoding)llvm::StringSwitch<int>(CPU)
- .Case("mips1", NanLegacy)
- .Case("mips2", NanLegacy)
- .Case("mips3", NanLegacy)
- .Case("mips4", NanLegacy)
- .Case("mips5", NanLegacy)
- .Case("mips32", NanLegacy)
- .Case("mips32r2", NanLegacy | Nan2008)
- .Case("mips32r3", NanLegacy | Nan2008)
- .Case("mips32r5", NanLegacy | Nan2008)
- .Case("mips32r6", Nan2008)
- .Case("mips64", NanLegacy)
- .Case("mips64r2", NanLegacy | Nan2008)
- .Case("mips64r3", NanLegacy | Nan2008)
- .Case("mips64r5", NanLegacy | Nan2008)
- .Case("mips64r6", Nan2008)
- .Default(NanLegacy);
-}
-
-bool mips::hasCompactBranches(StringRef &CPU) {
- // mips32r6 and mips64r6 have compact branches.
- return llvm::StringSwitch<bool>(CPU)
- .Case("mips32r6", true)
- .Case("mips64r6", true)
- .Default(false);
-}
-
-bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
- Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
- return A && (A->getValue() == StringRef(Value));
-}
-
-bool mips::isUCLibc(const ArgList &Args) {
- Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
- return A && A->getOption().matches(options::OPT_muclibc);
-}
-
-bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
- if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
- return llvm::StringSwitch<bool>(NaNArg->getValue())
- .Case("2008", true)
- .Case("legacy", false)
- .Default(false);
-
- // NaN2008 is the default for MIPS32r6/MIPS64r6.
- return llvm::StringSwitch<bool>(getCPUName(Args, Triple))
- .Cases("mips32r6", "mips64r6", true)
- .Default(false);
-
- return false;
-}
-
-bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
- if (!Triple.isAndroid())
- return false;
-
- // Android MIPS32R6 defaults to FP64A.
- return llvm::StringSwitch<bool>(CPUName)
- .Case("mips32r6", true)
- .Default(false);
-}
-
-bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
- StringRef ABIName, mips::FloatABI FloatABI) {
- if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
- Triple.getVendor() != llvm::Triple::MipsTechnologies &&
- !Triple.isAndroid())
- return false;
-
- if (ABIName != "32")
- return false;
-
- // FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
- // present.
- if (FloatABI == mips::FloatABI::Soft)
- return false;
-
- return llvm::StringSwitch<bool>(CPUName)
- .Cases("mips2", "mips3", "mips4", "mips5", true)
- .Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
- .Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
- .Default(false);
-}
-
-bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
- StringRef CPUName, StringRef ABIName,
- mips::FloatABI FloatABI) {
- bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
-
- // FPXX shouldn't be used if -msingle-float is present.
- if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
- options::OPT_mdouble_float))
- if (A->getOption().matches(options::OPT_msingle_float))
- UseFPXX = false;
-
- return UseFPXX;
-}
-
llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {
// See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
// archs which Darwin doesn't use.
@@ -8924,7 +7574,7 @@ void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::sparcel: {
CmdArgs.push_back("-32");
std::string CPU = getCPUName(Args, getToolChain().getTriple());
- CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+ CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
break;
}
@@ -8932,7 +7582,7 @@ void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::sparcv9: {
CmdArgs.push_back("-64");
std::string CPU = getCPUName(Args, getToolChain().getTriple());
- CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+ CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
break;
}
@@ -8944,7 +7594,7 @@ void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
CmdArgs.push_back("-mabi");
- CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
+ CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
if (getToolChain().getArch() == llvm::Triple::mips64)
CmdArgs.push_back("-EB");
@@ -9257,7 +7907,7 @@ void freebsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(CPUName.data());
CmdArgs.push_back("-mabi");
- CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
+ CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
if (getToolChain().getArch() == llvm::Triple::mips ||
getToolChain().getArch() == llvm::Triple::mips64)
@@ -9301,7 +7951,7 @@ void freebsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::sparcel:
case llvm::Triple::sparcv9: {
std::string CPU = getCPUName(Args, getToolChain().getTriple());
- CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+ CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
break;
}
@@ -9528,7 +8178,7 @@ void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::thumb:
case llvm::Triple::thumbeb: {
StringRef MArch, MCPU;
- getARMArchCPUFromArgs(Args, MArch, MCPU, /*FromAs*/ true);
+ arm::getARMArchCPUFromArgs(Args, MArch, MCPU, /*FromAs*/ true);
std::string Arch =
arm::getARMTargetCPU(MCPU, MArch, getToolChain().getTriple());
CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch));
@@ -9547,7 +8197,7 @@ void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(CPUName.data());
CmdArgs.push_back("-mabi");
- CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
+ CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
if (getToolChain().getArch() == llvm::Triple::mips ||
getToolChain().getArch() == llvm::Triple::mips64)
@@ -9563,7 +8213,7 @@ void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::sparcel: {
CmdArgs.push_back("-32");
std::string CPU = getCPUName(Args, getToolChain().getTriple());
- CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+ CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
break;
}
@@ -9571,7 +8221,7 @@ void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::sparcv9: {
CmdArgs.push_back("-64");
std::string CPU = getCPUName(Args, getToolChain().getTriple());
- CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+ CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
break;
}
@@ -9851,14 +8501,14 @@ void gnutools::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::sparcel: {
CmdArgs.push_back("-32");
std::string CPU = getCPUName(Args, getToolChain().getTriple());
- CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+ CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
break;
}
case llvm::Triple::sparcv9: {
CmdArgs.push_back("-64");
std::string CPU = getCPUName(Args, getToolChain().getTriple());
- CmdArgs.push_back(getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+ CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
break;
}
@@ -9912,7 +8562,7 @@ void gnutools::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
StringRef CPUName;
StringRef ABIName;
mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
- ABIName = getGnuCompatibleMipsABIName(ABIName);
+ ABIName = mips::getGnuCompatibleMipsABIName(ABIName);
CmdArgs.push_back("-march");
CmdArgs.push_back(CPUName.data());
@@ -9948,7 +8598,7 @@ void gnutools::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
A->render(Args, CmdArgs);
} else if (mips::shouldUseFPXX(
Args, getToolChain().getTriple(), CPUName, ABIName,
- getMipsFloatABI(getToolChain().getDriver(), Args)))
+ mips::getMipsFloatABI(getToolChain().getDriver(), Args)))
CmdArgs.push_back("-mfpxx");
// Pass on -mmips16 or -mno-mips16. However, the assembler equivalent of
@@ -9991,7 +8641,7 @@ void gnutools::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::systemz: {
// Always pass an -march option, since our default of z10 is later
// than the GNU assembler's default.
- StringRef CPUName = getSystemZTargetCPU(Args);
+ StringRef CPUName = systemz::getSystemZTargetCPU(Args);
CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));
break;
}