summaryrefslogtreecommitdiffstats
path: root/clang/lib/Driver
diff options
context:
space:
mode:
authorBradley Smith <bradley.smith@arm.com>2015-11-18 16:33:48 +0000
committerBradley Smith <bradley.smith@arm.com>2015-11-18 16:33:48 +0000
commitbbf5a00de13580dd65f6bdf77c446b1f2faf69dd (patch)
treeed41569a957b4e748b765dd81e772b89ab9161f7 /clang/lib/Driver
parent7b0a7d8d1e35720e55805587cadf7973bba36032 (diff)
downloadbcm5719-llvm-bbf5a00de13580dd65f6bdf77c446b1f2faf69dd.tar.gz
bcm5719-llvm-bbf5a00de13580dd65f6bdf77c446b1f2faf69dd.zip
[ARM] Support +feature targeting in -mcpu/-march
llvm-svn: 253471
Diffstat (limited to 'clang/lib/Driver')
-rw-r--r--clang/lib/Driver/Tools.cpp40
1 files changed, 32 insertions, 8 deletions
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index d951a48510a..d6a3a1f482d 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -589,23 +589,47 @@ static void getARMFPUFeatures(const Driver &D, const Arg *A,
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<const char *> &Features) {
+ SmallVector<StringRef, 8> Split;
+ text.split(Split, StringRef("+"), -1, false);
+
+ for (StringRef Feature : Split) {
+ const char *FeatureName = llvm::ARM::getArchExtFeature(Feature);
+ if (FeatureName)
+ 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<const char *> &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)
+ 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<const char *> &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())
+ 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);
}
@@ -771,12 +795,12 @@ static void getARMTargetFeatures(const ToolChain &TC,
D.Diag(clang::diag::warn_drv_unused_argument)
<< ArchArg->getAsString(Args);
ArchName = StringRef(WaArch->getValue()).substr(7);
- checkARMArchName(D, WaArch, Args, ArchName, Triple);
+ 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, Triple);
+ checkARMArchName(D, ArchArg, Args, ArchName, Features, Triple);
}
// Check -mcpu. ClangAs gives preference to -Wa,-mcpu=.
@@ -787,10 +811,10 @@ static void getARMTargetFeatures(const ToolChain &TC,
D.Diag(clang::diag::warn_drv_unused_argument)
<< CPUArg->getAsString(Args);
CPUName = StringRef(WaCPU->getValue()).substr(6);
- checkARMCPUName(D, WaCPU, Args, CPUName, ArchName, Triple);
+ checkARMCPUName(D, WaCPU, Args, CPUName, ArchName, Features, Triple);
} else if (CPUArg) {
CPUName = CPUArg->getValue();
- checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, Triple);
+ checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, Features, Triple);
}
// Add CPU features for generic CPUs
@@ -6274,7 +6298,7 @@ const std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) {
MArch = Arch;
else
MArch = Triple.getArchName();
- MArch = StringRef(MArch).lower();
+ MArch = StringRef(MArch).split("+").first.lower();
// Handle -march=native.
if (MArch == "native") {
@@ -6313,7 +6337,7 @@ std::string arm::getARMTargetCPU(StringRef CPU, StringRef Arch,
// FIXME: Warn on inconsistent use of -mcpu and -march.
// If we have -mcpu=, use that.
if (!CPU.empty()) {
- std::string MCPU = StringRef(CPU).lower();
+ std::string MCPU = StringRef(CPU).split("+").first.lower();
// Handle -mcpu=native.
if (MCPU == "native")
return llvm::sys::getHostCPUName();
OpenPOWER on IntegriCloud