#include "llvm/Support/TargetParser.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
+#include <cctype>
using namespace llvm;
// 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;
// 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;
}
// 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:
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: