aboutsummaryrefslogtreecommitdiff
path: root/lib/Driver/ToolChains/Arch
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver/ToolChains/Arch')
-rw-r--r--lib/Driver/ToolChains/Arch/AArch64.cpp22
-rw-r--r--lib/Driver/ToolChains/Arch/ARM.cpp50
-rw-r--r--lib/Driver/ToolChains/Arch/ARM.h7
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.cpp102
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.h4
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.cpp12
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.h1
-rw-r--r--lib/Driver/ToolChains/Arch/X86.cpp2
8 files changed, 149 insertions, 51 deletions
diff --git a/lib/Driver/ToolChains/Arch/AArch64.cpp b/lib/Driver/ToolChains/Arch/AArch64.cpp
index 554d051fb155..ad04aedd098e 100644
--- a/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -20,14 +20,12 @@ using namespace clang;
using namespace llvm::opt;
/// 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.
+/// targeting. Set \p A to the Arg corresponding to the -mcpu argument if it is
+/// provided, or to nullptr otherwise.
std::string aarch64::getAArch64TargetCPU(const ArgList &Args, Arg *&A) {
std::string CPU;
- // If we have -mtune or -mcpu, use that.
- if ((A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))) {
- CPU = StringRef(A->getValue()).lower();
- } else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
+ // If we have -mcpu, use that.
+ if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
StringRef Mcpu = A->getValue();
CPU = Mcpu.split("+").first.lower();
}
@@ -74,7 +72,7 @@ static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
if (CPU == "generic") {
Features.push_back("+neon");
} else {
- unsigned ArchKind = llvm::AArch64::parseCPUArch(CPU);
+ llvm::AArch64::ArchKind ArchKind = llvm::AArch64::parseCPUArch(CPU);
if (!llvm::AArch64::getArchFeatures(ArchKind, Features))
return false;
@@ -96,8 +94,8 @@ getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
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::ArchKind ArchKind = llvm::AArch64::parseArch(Split.first);
+ if (ArchKind == llvm::AArch64::ArchKind::INVALID ||
!llvm::AArch64::getArchFeatures(ArchKind, Features) ||
(Split.second.size() && !DecodeAArch64Features(D, Split.second, Features)))
return false;
@@ -122,6 +120,12 @@ getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
const ArgList &Args,
std::vector<StringRef> &Features) {
std::string MtuneLowerCase = Mtune.lower();
+ // Check CPU name is valid
+ std::vector<StringRef> MtuneFeatures;
+ StringRef Tune;
+ if (!DecodeAArch64Mcpu(D, MtuneLowerCase, Tune, MtuneFeatures))
+ return false;
+
// Handle CPU name is 'native'.
if (MtuneLowerCase == "native")
MtuneLowerCase = llvm::sys::getHostCPUName();
diff --git a/lib/Driver/ToolChains/Arch/ARM.cpp b/lib/Driver/ToolChains/Arch/ARM.cpp
index 95b86f784f91..44c8871d0e1f 100644
--- a/lib/Driver/ToolChains/Arch/ARM.cpp
+++ b/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -29,8 +29,7 @@ int arm::getARMSubArchVersionNumber(const llvm::Triple &Triple) {
// True if M-profile.
bool arm::isARMMProfile(const llvm::Triple &Triple) {
llvm::StringRef Arch = Triple.getArchName();
- unsigned Profile = llvm::ARM::parseArchProfile(Arch);
- return Profile == llvm::ARM::PK_M;
+ return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::M;
}
// Get Arch/CPU from args.
@@ -88,6 +87,15 @@ static bool DecodeARMFeatures(const Driver &D, StringRef text,
return true;
}
+static void DecodeARMFeaturesFromCPU(const Driver &D, StringRef CPU,
+ std::vector<StringRef> &Features) {
+ if (CPU != "generic") {
+ llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU);
+ unsigned Extension = llvm::ARM::getDefaultExtensions(CPU, ArchKind);
+ llvm::ARM::getExtensionFeatures(Extension, Features);
+ }
+}
+
// 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.
@@ -98,7 +106,7 @@ static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args,
std::pair<StringRef, StringRef> Split = ArchName.split("+");
std::string MArch = arm::getARMArch(ArchName, Triple);
- if (llvm::ARM::parseArch(MArch) == llvm::ARM::AK_INVALID ||
+ if (llvm::ARM::parseArch(MArch) == llvm::ARM::ArchKind::INVALID ||
(Split.second.size() && !DecodeARMFeatures(D, Split.second, Features)))
D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
}
@@ -123,6 +131,26 @@ bool arm::useAAPCSForMachO(const llvm::Triple &T) {
T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T);
}
+// Select mode for reading thread pointer (-mtp=soft/cp15).
+arm::ReadTPMode arm::getReadTPMode(const ToolChain &TC, const ArgList &Args) {
+ if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
+ const Driver &D = TC.getDriver();
+ arm::ReadTPMode ThreadPointer =
+ llvm::StringSwitch<arm::ReadTPMode>(A->getValue())
+ .Case("cp15", ReadTPMode::Cp15)
+ .Case("soft", ReadTPMode::Soft)
+ .Default(ReadTPMode::Invalid);
+ if (ThreadPointer != ReadTPMode::Invalid)
+ return ThreadPointer;
+ if (StringRef(A->getValue()).empty())
+ D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args);
+ else
+ D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
+ return ReadTPMode::Invalid;
+ }
+ return ReadTPMode::Soft;
+}
+
// Select the float ABI as determined by -msoft-float, -mhard-float, and
// -mfloat-abi=.
arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) {
@@ -254,6 +282,7 @@ void arm::getARMTargetFeatures(const ToolChain &TC,
bool KernelOrKext =
Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
arm::FloatABI ABI = arm::getARMFloatABI(TC, Args);
+ arm::ReadTPMode ThreadPointer = arm::getReadTPMode(TC, Args);
const Arg *WaCPU = nullptr, *WaFPU = nullptr;
const Arg *WaHDiv = nullptr, *WaArch = nullptr;
@@ -295,6 +324,9 @@ void arm::getARMTargetFeatures(const ToolChain &TC,
}
}
+ if (ThreadPointer == arm::ReadTPMode::Cp15)
+ Features.push_back("+read-tp-hard");
+
// Check -march. ClangAs gives preference to -Wa,-march=.
const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
StringRef ArchName;
@@ -332,6 +364,8 @@ void arm::getARMTargetFeatures(const ToolChain &TC,
for (auto &F : HostFeatures)
Features.push_back(
Args.MakeArgString((F.second ? "+" : "-") + F.first()));
+ } else if (!CPUName.empty()) {
+ DecodeARMFeaturesFromCPU(D, CPUName, Features);
}
// Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=.
@@ -393,7 +427,7 @@ void arm::getARMTargetFeatures(const ToolChain &TC,
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)
+ llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::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);
@@ -525,11 +559,11 @@ std::string arm::getARMTargetCPU(StringRef CPU, StringRef Arch,
// FIXME: This is redundant with -mcpu, why does LLVM use this.
StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch,
const llvm::Triple &Triple) {
- unsigned ArchKind;
+ llvm::ARM::ArchKind ArchKind;
if (CPU == "generic") {
std::string ARMArch = tools::arm::getARMArch(Arch, Triple);
ArchKind = llvm::ARM::parseArch(ARMArch);
- if (ArchKind == llvm::ARM::AK_INVALID)
+ if (ArchKind == llvm::ARM::ArchKind::INVALID)
// In case of generic Arch, i.e. "arm",
// extract arch from default cpu of the Triple
ArchKind = llvm::ARM::parseCPUArch(Triple.getARMCPUForArch(ARMArch));
@@ -537,10 +571,10 @@ StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch,
// FIXME: horrible hack to get around the fact that Cortex-A7 is only an
// armv7k triple if it's actually been specified via "-arch armv7k".
ArchKind = (Arch == "armv7k" || Arch == "thumbv7k")
- ? (unsigned)llvm::ARM::AK_ARMV7K
+ ? llvm::ARM::ArchKind::ARMV7K
: llvm::ARM::parseCPUArch(CPU);
}
- if (ArchKind == llvm::ARM::AK_INVALID)
+ if (ArchKind == llvm::ARM::ArchKind::INVALID)
return "";
return llvm::ARM::getSubArch(ArchKind);
}
diff --git a/lib/Driver/ToolChains/Arch/ARM.h b/lib/Driver/ToolChains/Arch/ARM.h
index 52afaab762d0..c1dc16884033 100644
--- a/lib/Driver/ToolChains/Arch/ARM.h
+++ b/lib/Driver/ToolChains/Arch/ARM.h
@@ -32,6 +32,12 @@ StringRef getLLVMArchSuffixForARM(llvm::StringRef CPU, llvm::StringRef Arch,
void appendEBLinkFlags(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs,
const llvm::Triple &Triple);
+enum class ReadTPMode {
+ Invalid,
+ Soft,
+ Cp15,
+};
+
enum class FloatABI {
Invalid,
Soft,
@@ -40,6 +46,7 @@ enum class FloatABI {
};
FloatABI getARMFloatABI(const ToolChain &TC, const llvm::opt::ArgList &Args);
+ReadTPMode getReadTPMode(const ToolChain &TC, const llvm::opt::ArgList &Args);
bool useAAPCSForMachO(const llvm::Triple &T);
void getARMArchCPUFromArgs(const llvm::opt::ArgList &Args,
diff --git a/lib/Driver/ToolChains/Arch/Mips.cpp b/lib/Driver/ToolChains/Arch/Mips.cpp
index b45dcd6db678..61481a92d0b7 100644
--- a/lib/Driver/ToolChains/Arch/Mips.cpp
+++ b/lib/Driver/ToolChains/Arch/Mips.cpp
@@ -35,7 +35,7 @@ void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple,
// 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) {
+ Triple.isGNUEnvironment()) {
DefMips32CPU = "mips32r6";
DefMips64CPU = "mips64r6";
}
@@ -227,11 +227,32 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie));
}
- if (IsN64 && NonPIC)
+ bool UseAbiCalls = false;
+
+ Arg *ABICallsArg =
+ Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls);
+ UseAbiCalls =
+ !ABICallsArg || ABICallsArg->getOption().matches(options::OPT_mabicalls);
+
+ if (UseAbiCalls && IsN64 && NonPIC) {
+ D.Diag(diag::warn_drv_unsupported_abicalls);
+ UseAbiCalls = false;
+ }
+
+ if (!UseAbiCalls)
Features.push_back("+noabicalls");
else
- AddTargetFeature(Args, Features, options::OPT_mno_abicalls,
- options::OPT_mabicalls, "noabicalls");
+ Features.push_back("-noabicalls");
+
+ if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
+ options::OPT_mno_long_calls)) {
+ if (A->getOption().matches(options::OPT_mno_long_calls))
+ Features.push_back("-long-calls");
+ else if (!UseAbiCalls)
+ Features.push_back("+long-calls");
+ else
+ D.Diag(diag::warn_drv_unsupported_longcalls) << (ABICallsArg ? 0 : 1);
+ }
mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args);
if (FloatABI == mips::FloatABI::Soft) {
@@ -244,14 +265,14 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
StringRef Val = StringRef(A->getValue());
if (Val == "2008") {
- if (mips::getSupportedNanEncoding(CPUName) & mips::Nan2008)
+ if (mips::getIEEE754Standard(CPUName) & mips::Std2008)
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)
+ if (mips::getIEEE754Standard(CPUName) & mips::Legacy)
Features.push_back("-nan2008");
else {
Features.push_back("+nan2008");
@@ -262,6 +283,28 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
<< A->getOption().getName() << Val;
}
+ if (Arg *A = Args.getLastArg(options::OPT_mabs_EQ)) {
+ StringRef Val = StringRef(A->getValue());
+ if (Val == "2008") {
+ if (mips::getIEEE754Standard(CPUName) & mips::Std2008) {
+ Features.push_back("+abs2008");
+ } else {
+ Features.push_back("-abs2008");
+ D.Diag(diag::warn_target_unsupported_abs2008) << CPUName;
+ }
+ } else if (Val == "legacy") {
+ if (mips::getIEEE754Standard(CPUName) & mips::Legacy) {
+ Features.push_back("-abs2008");
+ } else {
+ Features.push_back("+abs2008");
+ D.Diag(diag::warn_target_unsupported_abslegacy) << 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,
@@ -299,32 +342,31 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
options::OPT_modd_spreg, "nooddspreg");
AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4,
"nomadd4");
- AddTargetFeature(Args, Features, options::OPT_mlong_calls,
- options::OPT_mno_long_calls, "long-calls");
- AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt,"mt");
+ AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt");
}
-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);
+mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) {
+ // Strictly speaking, mips32r2 and mips64r2 do not conform to the
+ // IEEE754-2008 standard. Support for this standard was first introduced
+ // in Release 3. However, other compilers have traditionally allowed it
+ // for Release 2 so we should do the same.
+ return (IEEE754Standard)llvm::StringSwitch<int>(CPU)
+ .Case("mips1", Legacy)
+ .Case("mips2", Legacy)
+ .Case("mips3", Legacy)
+ .Case("mips4", Legacy)
+ .Case("mips5", Legacy)
+ .Case("mips32", Legacy)
+ .Case("mips32r2", Legacy | Std2008)
+ .Case("mips32r3", Legacy | Std2008)
+ .Case("mips32r5", Legacy | Std2008)
+ .Case("mips32r6", Std2008)
+ .Case("mips64", Legacy)
+ .Case("mips64r2", Legacy | Std2008)
+ .Case("mips64r3", Legacy | Std2008)
+ .Case("mips64r5", Legacy | Std2008)
+ .Case("mips64r6", Std2008)
+ .Default(Std2008);
}
bool mips::hasCompactBranches(StringRef &CPU) {
diff --git a/lib/Driver/ToolChains/Arch/Mips.h b/lib/Driver/ToolChains/Arch/Mips.h
index 0b788660948c..89eea9a1514c 100644
--- a/lib/Driver/ToolChains/Arch/Mips.h
+++ b/lib/Driver/ToolChains/Arch/Mips.h
@@ -24,7 +24,7 @@ namespace tools {
bool isMipsArch(llvm::Triple::ArchType Arch);
namespace mips {
-typedef enum { NanLegacy = 1, Nan2008 = 2 } NanEncoding;
+typedef enum { Legacy = 1, Std2008 = 2 } IEEE754Standard;
enum class FloatABI {
Invalid,
@@ -32,7 +32,7 @@ enum class FloatABI {
Hard,
};
-NanEncoding getSupportedNanEncoding(StringRef &CPU);
+IEEE754Standard getIEEE754Standard(StringRef &CPU);
bool hasCompactBranches(StringRef &CPU);
void getMipsCPUAndABI(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple, StringRef &CPUName,
diff --git a/lib/Driver/ToolChains/Arch/PPC.cpp b/lib/Driver/ToolChains/Arch/PPC.cpp
index 541323127f9a..7c7e1c70e550 100644
--- a/lib/Driver/ToolChains/Arch/PPC.cpp
+++ b/lib/Driver/ToolChains/Arch/PPC.cpp
@@ -86,6 +86,18 @@ std::string ppc::getPPCTargetCPU(const ArgList &Args) {
return "";
}
+const char *ppc::getPPCAsmModeForCPU(StringRef Name) {
+ return llvm::StringSwitch<const char *>(Name)
+ .Case("pwr7", "-mpower7")
+ .Case("power7", "-mpower7")
+ .Case("pwr8", "-mpower8")
+ .Case("power8", "-mpower8")
+ .Case("ppc64le", "-mpower8")
+ .Case("pwr9", "-mpower9")
+ .Case("power9", "-mpower9")
+ .Default("-many");
+}
+
void ppc::getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args,
std::vector<StringRef> &Features) {
diff --git a/lib/Driver/ToolChains/Arch/PPC.h b/lib/Driver/ToolChains/Arch/PPC.h
index 892eb2c34158..7d7c68101b7b 100644
--- a/lib/Driver/ToolChains/Arch/PPC.h
+++ b/lib/Driver/ToolChains/Arch/PPC.h
@@ -32,6 +32,7 @@ enum class FloatABI {
FloatABI getPPCFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
std::string getPPCTargetCPU(const llvm::opt::ArgList &Args);
+const char *getPPCAsmModeForCPU(StringRef Name);
void getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args,
diff --git a/lib/Driver/ToolChains/Arch/X86.cpp b/lib/Driver/ToolChains/Arch/X86.cpp
index a85a7f1f6371..a18b2aa35b03 100644
--- a/lib/Driver/ToolChains/Arch/X86.cpp
+++ b/lib/Driver/ToolChains/Arch/X86.cpp
@@ -101,8 +101,6 @@ const char *x86::getX86TargetCPU(const ArgList &Args,
return "i486";
case llvm::Triple::Haiku:
return "i586";
- case llvm::Triple::Bitrig:
- return "i686";
default:
// Fallback to p4.
return "pentium4";