diff --git a/include/llvm/Support/TargetParser.h b/include/llvm/Support/TargetParser.h index f588105b2e9..ca626f271d5 100644 --- a/include/llvm/Support/TargetParser.h +++ b/include/llvm/Support/TargetParser.h @@ -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); }; diff --git a/lib/Support/TargetParser.cpp b/lib/Support/TargetParser.cpp index 55f0040a786..590a1458558 100644 --- a/lib/Support/TargetParser.cpp +++ b/lib/Support/TargetParser.cpp @@ -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 diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index b862dbd2a74..6ef50a54d42 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -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; } diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp index 4af3bfe9489..b0f01b26e72 100644 --- a/unittests/ADT/TripleTest.cpp +++ b/unittests/ADT/TripleTest.cpp @@ -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");