diff options
Diffstat (limited to 'llvm/lib/Support/TargetParser.cpp')
-rw-r--r-- | llvm/lib/Support/TargetParser.cpp | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/llvm/lib/Support/TargetParser.cpp b/llvm/lib/Support/TargetParser.cpp index 590a1458558..a3998d2d13e 100644 --- a/llvm/lib/Support/TargetParser.cpp +++ b/llvm/lib/Support/TargetParser.cpp @@ -16,6 +16,7 @@ #include "llvm/Support/TargetParser.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" +#include <cctype> using namespace llvm; @@ -279,14 +280,17 @@ StringRef ARMTargetParser::getArchSynonym(StringRef Arch) { // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but // (iwmmxt|xscale)(eb)? is also permitted. If the former, return -// "v.+", if the latter, return unmodified string. If invalid, return "". +// "v.+", if the latter, return unmodified string, minus 'eb'. +// If invalid, return empty string. StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) { size_t offset = StringRef::npos; StringRef A = Arch; StringRef Error = ""; // Begins with "arm" / "thumb", move past it. - if (A.startswith("arm")) + if (A.startswith("arm64")) + offset = 5; + else if (A.startswith("arm")) offset = 3; else if (A.startswith("thumb")) offset = 5; @@ -305,21 +309,25 @@ StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) { // Or, if it ends with eb ("armv7eb"), chop it off. else if (A.endswith("eb")) A = A.substr(0, A.size() - 2); - // Reached the end or a 'v', canonicalise. - if (offset != StringRef::npos && (offset == A.size() || A[offset] == 'v')) + // Trim the head + if (offset != StringRef::npos) A = A.substr(offset); - // Empty string mans offset reached the end. Although valid, this arch - // will not have a match in the table. Return the original string. + // Empty string means offset reached the end, which means it's valid. if (A.empty()) return Arch; - // If can't find the arch, return an empty StringRef. - if (parseArch(A) == ARM::AK_INVALID) - return Error; + // Only match non-marketing names + if (offset != StringRef::npos) { + // Must start with 'vN'. + if (A[0] != 'v' || !std::isdigit(A[1])) + return Error; + // Can't have an extra 'eb'. + if (A.find("eb") != StringRef::npos) + return Error; + } - // Arch will either be a 'v' name (v7a) or a marketing name (xscale) - // or empty, if invalid. + // Arch will either be a 'v' name (v7a) or a marketing name (xscale). return A; } @@ -390,7 +398,6 @@ unsigned ARMTargetParser::parseArchEndian(StringRef Arch) { // Profile A/R/M unsigned ARMTargetParser::parseArchProfile(StringRef Arch) { - // FIXME: We're running parseArch twice. Arch = getCanonicalArchName(Arch); switch(parseArch(Arch)) { case ARM::AK_ARMV6M: @@ -409,9 +416,8 @@ unsigned ARMTargetParser::parseArchProfile(StringRef Arch) { return ARM::PK_INVALID; } -// Version number 4 ~ 8 (ex. v7 = 7). +// Version number (ex. v7 = 7). unsigned ARMTargetParser::parseArchVersion(StringRef Arch) { - // FIXME: We're running parseArch twice. Arch = getCanonicalArchName(Arch); switch(parseArch(Arch)) { case ARM::AK_ARMV2: |