Adding profile and version parsers to ARMTargetParser
authorRenato Golin <renato.golin@linaro.org>
Fri, 22 May 2015 18:17:55 +0000 (18:17 +0000)
committerRenato Golin <renato.golin@linaro.org>
Fri, 22 May 2015 18:17:55 +0000 (18:17 +0000)
This allows us to match armv6m to default to thumb, but will also be used by
Clang's driver and remove the current incomplete copy in it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238036 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/TargetParser.h
lib/Support/TargetParser.cpp
lib/Support/Triple.cpp
unittests/ADT/TripleTest.cpp

index f588105b2e907b28d26458d241d9e09892292686..ca626f271d519505479aee8ed5a9e225756ef1d2 100644 (file)
@@ -112,6 +112,14 @@ namespace ARM {
     EK_LITTLE,
     EK_BIG
   };
+
+  // v6/v7/v8 Profile
+  enum ProfileKind {
+    PK_INVALID = 0,
+    PK_A,
+    PK_R,
+    PK_M
+  };
 } // namespace ARM
 
 // Target Parsers, one per architecture.
@@ -137,6 +145,8 @@ public:
   static unsigned parseCPUArch(StringRef CPU);
   static unsigned parseArchISA(StringRef Arch);
   static unsigned parseArchEndian(StringRef Arch);
+  static unsigned parseArchProfile(StringRef Arch);
+  static unsigned parseArchVersion(StringRef Arch);
 
 };
 
index 55f0040a786521ea63a278b1a4afcab469f44d4f..590a1458558d1a487a9c9edd0da788165ff5deeb 100644 (file)
@@ -388,4 +388,74 @@ unsigned ARMTargetParser::parseArchEndian(StringRef Arch) {
   return ARM::EK_INVALID;
 }
 
+// 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:
+  case ARM::AK_ARMV7M:
+  case ARM::AK_ARMV6SM:
+  case ARM::AK_ARMV7EM:
+    return ARM::PK_M;
+  case ARM::AK_ARMV7R:
+    return ARM::PK_R;
+  case ARM::AK_ARMV7:
+  case ARM::AK_ARMV7A:
+  case ARM::AK_ARMV8A:
+  case ARM::AK_ARMV8_1A:
+    return ARM::PK_A;
+  }
+  return ARM::PK_INVALID;
+}
+
+// Version number 4 ~ 8 (ex. v7 = 7).
+unsigned ARMTargetParser::parseArchVersion(StringRef Arch) {
+  // FIXME: We're running parseArch twice.
+  Arch = getCanonicalArchName(Arch);
+  switch(parseArch(Arch)) {
+  case ARM::AK_ARMV2:
+  case ARM::AK_ARMV2A:
+    return 2;
+  case ARM::AK_ARMV3:
+  case ARM::AK_ARMV3M:
+    return 3;
+  case ARM::AK_ARMV4:
+  case ARM::AK_ARMV4T:
+    return 4;
+  case ARM::AK_ARMV5:
+  case ARM::AK_ARMV5T:
+  case ARM::AK_ARMV5TE:
+  case ARM::AK_IWMMXT:
+  case ARM::AK_IWMMXT2:
+  case ARM::AK_XSCALE:
+  case ARM::AK_ARMV5E:
+  case ARM::AK_ARMV5TEJ:
+    return 5;
+  case ARM::AK_ARMV6:
+  case ARM::AK_ARMV6J:
+  case ARM::AK_ARMV6K:
+  case ARM::AK_ARMV6T2:
+  case ARM::AK_ARMV6Z:
+  case ARM::AK_ARMV6ZK:
+  case ARM::AK_ARMV6M:
+  case ARM::AK_ARMV6SM:
+  case ARM::AK_ARMV6HL:
+    return 6;
+  case ARM::AK_ARMV7:
+  case ARM::AK_ARMV7A:
+  case ARM::AK_ARMV7R:
+  case ARM::AK_ARMV7M:
+  case ARM::AK_ARMV7L:
+  case ARM::AK_ARMV7HL:
+  case ARM::AK_ARMV7S:
+  case ARM::AK_ARMV7EM:
+    return 7;
+  case ARM::AK_ARMV8A:
+  case ARM::AK_ARMV8_1A:
+    return 8;
+  }
+  return 0;
+}
+
 } // namespace llvm
index b862dbd2a74dd1d419dc38c3fc5d51aeacfe3ad4..6ef50a54d4217a809bff15fc1d4460df1f641a5a 100644 (file)
@@ -281,8 +281,16 @@ static Triple::ArchType parseARMArch(StringRef ArchName) {
       (ArchName.startswith("v2") || ArchName.startswith("v3")))
     return Triple::UnknownArch;
 
-  // FIXME: Add isMProfile to ARMTargetParser and
-  // either change armv6m to thumb or UnknownArch.
+  // Thumb only for v6m
+  unsigned Profile = ARMTargetParser::parseArchProfile(ArchName);
+  unsigned Version = ARMTargetParser::parseArchVersion(ArchName);
+  if (Profile == ARM::PK_M && Version == 6) {
+    if (ENDIAN == ARM::EK_BIG)
+      return Triple::thumbeb;
+    else
+      return Triple::thumb;
+  }
+
   return arch;
 }
 
index 4af3bfe9489e919c75028c2552abe04d5624e0ca..b0f01b26e7229f2f69dd06b94037727e2a274772 100644 (file)
@@ -900,6 +900,14 @@ TEST(TripleTest, ParseARMArch) {
     Triple T = Triple("armv5eb");
     EXPECT_EQ(Triple::armeb, T.getArch());
   }
+  {
+    Triple T = Triple("armebv7m");
+    EXPECT_EQ(Triple::armeb, T.getArch());
+  }
+  {
+    Triple T = Triple("armv7eb");
+    EXPECT_EQ(Triple::armeb, T.getArch());
+  }
   // THUMB
   {
     Triple T = Triple("thumb");
@@ -917,10 +925,22 @@ TEST(TripleTest, ParseARMArch) {
     Triple T = Triple("thumbv4teb");
     EXPECT_EQ(Triple::thumbeb, T.getArch());
   }
+  {
+    Triple T = Triple("thumbebv7");
+    EXPECT_EQ(Triple::thumbeb, T.getArch());
+  }
+  {
+    Triple T = Triple("armv6m");
+    EXPECT_EQ(Triple::thumb, T.getArch());
+  }
   {
     Triple T = Triple("thumbv2");
     EXPECT_EQ(Triple::UnknownArch, T.getArch());
   }
+  {
+    Triple T = Triple("thumbebv6eb");
+    EXPECT_EQ(Triple::UnknownArch, T.getArch());
+  }
   // AARCH64
   {
     Triple T = Triple("arm64");