summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorJohn Brawn <john.brawn@arm.com>2015-05-08 12:52:02 +0000
committerJohn Brawn <john.brawn@arm.com>2015-05-08 12:52:02 +0000
commit50ed9470dcd867c3341991bdc3fe704db43aae4d (patch)
treea12ed06ca5854c8ebdcb667dc9180ad3a13574a4 /llvm
parent6c253006b8961247e7406592675d8787d761dce1 (diff)
downloadbcm5719-llvm-50ed9470dcd867c3341991bdc3fe704db43aae4d.tar.gz
bcm5719-llvm-50ed9470dcd867c3341991bdc3fe704db43aae4d.zip
[ARM] Reject invalid -march values
Restructure Triple::getARMCPUForArch so that invalid values will return nullptr, while retaining the behaviour that an argument specifying no particular architecture version will give a default CPU. This will be used by clang to give an error on invalid -march values. Also restructure the extraction of the architecture version from the MArch string a little to hopefully make what it's doing clearer. Differential Revision: http://reviews.llvm.org/D9599 llvm-svn: 236845
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Support/Triple.cpp75
-rw-r--r--llvm/unittests/ADT/TripleTest.cpp31
2 files changed, 71 insertions, 35 deletions
diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp
index 0a10a48557e..dd7423e46a8 100644
--- a/llvm/lib/Support/Triple.cpp
+++ b/llvm/lib/Support/Triple.cpp
@@ -1088,18 +1088,52 @@ const char *Triple::getARMCPUForArch(StringRef MArch) const {
break;
}
+ // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?
+ // Only the (v.+) part is relevant for determining the CPU, as it determines
+ // the architecture version, so we first remove the surrounding parts.
+ // (ep9312|iwmmxt|xscale)(eb)? is also permitted, so we have to be a bit
+ // careful when removing the leading (arm|thumb)?(eb)? as we don't want to
+ // permit things like armep9312.
const char *result = nullptr;
size_t offset = StringRef::npos;
if (MArch.startswith("arm"))
offset = 3;
- if (MArch.startswith("thumb"))
+ else if (MArch.startswith("thumb"))
offset = 5;
if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
offset += 2;
- if (MArch.endswith("eb"))
+ else if (MArch.endswith("eb"))
MArch = MArch.substr(0, MArch.size() - 2);
- if (offset != StringRef::npos)
- result = llvm::StringSwitch<const char *>(MArch.substr(offset))
+ if (offset != StringRef::npos && (offset == MArch.size() || MArch[offset] == 'v'))
+ MArch = MArch.substr(offset);
+
+ if (MArch == "") {
+ // If no specific architecture version is requested, return the minimum CPU
+ // required by the OS and environment.
+ switch (getOS()) {
+ case llvm::Triple::NetBSD:
+ switch (getEnvironment()) {
+ case llvm::Triple::GNUEABIHF:
+ case llvm::Triple::GNUEABI:
+ case llvm::Triple::EABIHF:
+ case llvm::Triple::EABI:
+ return "arm926ej-s";
+ default:
+ return "strongarm";
+ }
+ case llvm::Triple::NaCl:
+ return "cortex-a8";
+ default:
+ switch (getEnvironment()) {
+ case llvm::Triple::EABIHF:
+ case llvm::Triple::GNUEABIHF:
+ return "arm1176jzf-s";
+ default:
+ return "arm7tdmi";
+ }
+ }
+ } else {
+ result = llvm::StringSwitch<const char *>(MArch)
.Cases("v2", "v2a", "arm2")
.Case("v3", "arm6")
.Case("v3m", "arm7m")
@@ -1120,40 +1154,11 @@ const char *Triple::getARMCPUForArch(StringRef MArch) const {
.Cases("v7em", "v7e-m", "cortex-m4")
.Cases("v8", "v8a", "v8-a", "cortex-a53")
.Cases("v8.1a", "v8.1-a", "generic")
- .Default(nullptr);
- else
- result = llvm::StringSwitch<const char *>(MArch)
.Case("ep9312", "ep9312")
.Case("iwmmxt", "iwmmxt")
.Case("xscale", "xscale")
.Default(nullptr);
-
- if (result)
- return result;
-
- // If all else failed, return the most base CPU with thumb interworking
- // supported by LLVM.
- // FIXME: Should warn once that we're falling back.
- switch (getOS()) {
- case llvm::Triple::NetBSD:
- switch (getEnvironment()) {
- case llvm::Triple::GNUEABIHF:
- case llvm::Triple::GNUEABI:
- case llvm::Triple::EABIHF:
- case llvm::Triple::EABI:
- return "arm926ej-s";
- default:
- return "strongarm";
- }
- case llvm::Triple::NaCl:
- return "cortex-a8";
- default:
- switch (getEnvironment()) {
- case llvm::Triple::EABIHF:
- case llvm::Triple::GNUEABIHF:
- return "arm1176jzf-s";
- default:
- return "arm7tdmi";
- }
}
+
+ return result;
}
diff --git a/llvm/unittests/ADT/TripleTest.cpp b/llvm/unittests/ADT/TripleTest.cpp
index 96050374221..d168097d540 100644
--- a/llvm/unittests/ADT/TripleTest.cpp
+++ b/llvm/unittests/ADT/TripleTest.cpp
@@ -705,6 +705,37 @@ TEST(TripleTest, getARMCPUForArch) {
llvm::Triple Triple("arm--nacl");
EXPECT_STREQ("cortex-a8", Triple.getARMCPUForArch("arm"));
}
+ // armebv6 and armv6eb are permitted, but armebv6eb is not
+ {
+ llvm::Triple Triple("armebv6-non-eabi");
+ EXPECT_STREQ("arm1136jf-s", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv6eb-none-eabi");
+ EXPECT_STREQ("arm1136jf-s", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armebv6eb-none-eabi");
+ EXPECT_EQ(nullptr, Triple.getARMCPUForArch());
+ }
+ // armeb is permitted, but armebeb is not
+ {
+ llvm::Triple Triple("armeb-none-eabi");
+ EXPECT_STREQ("arm7tdmi", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armebeb-none-eabi");
+ EXPECT_EQ(nullptr, Triple.getARMCPUForArch());
+ }
+ // xscaleeb is permitted, but armebxscale is not
+ {
+ llvm::Triple Triple("xscaleeb-none-eabi");
+ EXPECT_STREQ("xscale", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armebxscale-none-eabi");
+ EXPECT_EQ(nullptr, Triple.getARMCPUForArch());
+ }
}
TEST(TripleTest, NormalizeARM) {
OpenPOWER on IntegriCloud