From 62f973306c3a8d1cd92b0e53c352d74a12075b29 Mon Sep 17 00:00:00 2001 From: John Brawn Date: Fri, 8 May 2015 12:52:02 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236845 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/Triple.cpp | 75 +++++++++++++++++++----------------- unittests/ADT/TripleTest.cpp | 31 +++++++++++++++ 2 files changed, 71 insertions(+), 35 deletions(-) diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index 0a10a48557e..dd7423e46a8 100644 --- a/lib/Support/Triple.cpp +++ b/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(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(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(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/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp index 96050374221..d168097d540 100644 --- a/unittests/ADT/TripleTest.cpp +++ b/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) { -- 2.34.1