diff --git a/llvm/include/llvm/Support/AArch64TargetParser.h b/llvm/include/llvm/Support/AArch64TargetParser.h --- a/llvm/include/llvm/Support/AArch64TargetParser.h +++ b/llvm/include/llvm/Support/AArch64TargetParser.h @@ -15,7 +15,6 @@ #define LLVM_SUPPORT_AARCH64TARGETPARSER_H #include "llvm/ADT/StringRef.h" -#include "llvm/Support/ARMTargetParser.h" #include // FIXME:This should be made into class design,to avoid dupplication. @@ -80,33 +79,70 @@ }; enum class ArchKind { -#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) ID, +#define AARCH64_ARCH(NAME, ID, SUB_ARCH, ARCH_BASE_EXT) ID, #include "AArch64TargetParser.def" }; -const ARM::ArchNames AArch64ARCHNames[] = { -#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, \ - ARCH_BASE_EXT) \ - {NAME, \ - sizeof(NAME) - 1, \ - CPU_ATTR, \ - sizeof(CPU_ATTR) - 1, \ - "+" SUB_ARCH, \ - sizeof(SUB_ARCH), \ - ARM::FPUKind::ARCH_FPU, \ - ARCH_BASE_EXT, \ - AArch64::ArchKind::ID, \ - ARCH_ATTR}, +template struct ArchNames { + const char *NameCStr; + size_t NameLength; + const char *SubArchCStr; + size_t SubArchLength; + uint64_t ArchBaseExtensions; + T ID; + + StringRef getName() const { return StringRef(NameCStr, NameLength); } + + // Sub-Arch name. + StringRef getSubArch() const { + return getArchFeature().substr(1, SubArchLength); + } + + // Arch Feature name. + StringRef getArchFeature() const { + return StringRef(SubArchCStr, SubArchLength); + } +}; + +const ArchNames AArch64ARCHNames[] = { +#define AARCH64_ARCH(NAME, ID, SUB_ARCH, ARCH_BASE_EXT) \ + {NAME, sizeof(NAME) - 1, "+" SUB_ARCH, sizeof(SUB_ARCH), \ + ARCH_BASE_EXT, AArch64::ArchKind::ID}, #include "AArch64TargetParser.def" }; -const ARM::ExtName AArch64ARCHExtNames[] = { +// List of Arch Extension names. +struct ExtName { + const char *NameCStr; + size_t NameLength; + uint64_t ID; + const char *Feature; + const char *NegFeature; + + StringRef getName() const { return StringRef(NameCStr, NameLength); } +}; + +const ExtName AArch64ARCHExtNames[] = { #define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \ {NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE}, #include "AArch64TargetParser.def" }; -const ARM::CpuNames AArch64CPUNames[] = { +// List of CPU names and their arches. +// The same CPU can have multiple arches and can be default on multiple arches. +// When finding the Arch for a CPU, first-found prevails. Sort them accordingly. +// When this becomes table-generated, we'd probably need two tables. +template struct CpuNames { + const char *NameCStr; + size_t NameLength; + T ArchID; + bool Default; // is $Name the default CPU for $ArchID ? + uint64_t DefaultExtensions; + + StringRef getName() const { return StringRef(NameCStr, NameLength); } +}; + +const CpuNames AArch64CPUNames[] = { #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ {NAME, sizeof(NAME) - 1, AArch64::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT}, #include "AArch64TargetParser.def" @@ -127,8 +163,7 @@ }; const ArchKind ArchKinds[] = { -#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \ - ArchKind::ID, +#define AARCH64_ARCH(NAME, ID, SUB_ARCH, ARCH_BASE_EXT) ArchKind::ID, #include "AArch64TargetParser.def" }; @@ -149,8 +184,6 @@ bool getArchFeatures(ArchKind AK, std::vector &Features); StringRef getArchName(ArchKind AK); -unsigned getArchAttr(ArchKind AK); -StringRef getCPUAttr(ArchKind AK); StringRef getSubArch(ArchKind AK); StringRef getArchExtName(unsigned ArchExtKind); StringRef getArchExtFeature(StringRef ArchExt); @@ -158,9 +191,7 @@ StringRef resolveCPUAlias(StringRef CPU); // Information by Name -unsigned getDefaultFPU(StringRef CPU, ArchKind AK); uint64_t getDefaultExtensions(StringRef CPU, ArchKind AK); -StringRef getDefaultCPU(StringRef Arch); ArchKind getCPUArchKind(StringRef CPU); ArchKind getSubArchArchKind(StringRef SubArch); diff --git a/llvm/include/llvm/Support/AArch64TargetParser.def b/llvm/include/llvm/Support/AArch64TargetParser.def --- a/llvm/include/llvm/Support/AArch64TargetParser.def +++ b/llvm/include/llvm/Support/AArch64TargetParser.def @@ -13,88 +13,74 @@ // NOTE: NO INCLUDE GUARD DESIRED! #ifndef AARCH64_ARCH -#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) +#define AARCH64_ARCH(NAME, ID, SUB_ARCH, ARCH_BASE_EXT) #endif // NOTE: The order and the grouping of the elements matter to make ArchKind iterable. // List is organised as armv8a -> armv8n-a, armv9a -> armv9m-a and armv8-r. -AARCH64_ARCH("invalid", INVALID, "", "", - ARMBuildAttrs::CPUArch::v8_A, FK_NONE, AArch64::AEK_NONE) -AARCH64_ARCH("armv8-a", ARMV8A, "8-A", "v8a", ARMBuildAttrs::CPUArch::v8_A, - FK_CRYPTO_NEON_FP_ARMV8, +AARCH64_ARCH("invalid", INVALID, "", + AArch64::AEK_NONE) +AARCH64_ARCH("armv8-a", ARMV8A, "v8a", (AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD)) -AARCH64_ARCH("armv8.1-a", ARMV8_1A, "8.1-A", "v8.1a", - ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, +AARCH64_ARCH("armv8.1-a", ARMV8_1A, "v8.1a", (AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD | AArch64::AEK_LSE | AArch64::AEK_RDM)) -AARCH64_ARCH("armv8.2-a", ARMV8_2A, "8.2-A", "v8.2a", - ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, +AARCH64_ARCH("armv8.2-a", ARMV8_2A, "v8.2a", (AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM)) -AARCH64_ARCH("armv8.3-a", ARMV8_3A, "8.3-A", "v8.3a", - ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, +AARCH64_ARCH("armv8.3-a", ARMV8_3A, "v8.3a", (AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM | AArch64::AEK_RCPC)) -AARCH64_ARCH("armv8.4-a", ARMV8_4A, "8.4-A", "v8.4a", - ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, +AARCH64_ARCH("armv8.4-a", ARMV8_4A, "v8.4a", (AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD)) -AARCH64_ARCH("armv8.5-a", ARMV8_5A, "8.5-A", "v8.5a", - ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, +AARCH64_ARCH("armv8.5-a", ARMV8_5A, "v8.5a", (AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD)) -AARCH64_ARCH("armv8.6-a", ARMV8_6A, "8.6-A", "v8.6a", - ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, +AARCH64_ARCH("armv8.6-a", ARMV8_6A, "v8.6a", (AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 | AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM)) -AARCH64_ARCH("armv8.7-a", ARMV8_7A, "8.7-A", "v8.7a", - ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, +AARCH64_ARCH("armv8.7-a", ARMV8_7A, "v8.7a", (AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 | AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM)) -AARCH64_ARCH("armv8.8-a", ARMV8_8A, "8.8-A", "v8.8a", - ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, +AARCH64_ARCH("armv8.8-a", ARMV8_8A, "v8.8a", (AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 | AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM)) -AARCH64_ARCH("armv9-a", ARMV9A, "9-A", "v9a", - ARMBuildAttrs::CPUArch::v8_A, FK_NEON_FP_ARMV8, +AARCH64_ARCH("armv9-a", ARMV9A, "v9a", (AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_SVE2)) -AARCH64_ARCH("armv9.1-a", ARMV9_1A, "9.1-A", "v9.1a", - ARMBuildAttrs::CPUArch::v8_A, FK_NEON_FP_ARMV8, +AARCH64_ARCH("armv9.1-a", ARMV9_1A, "v9.1a", (AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2)) -AARCH64_ARCH("armv9.2-a", ARMV9_2A, "9.2-A", "v9.2a", - ARMBuildAttrs::CPUArch::v8_A, FK_NEON_FP_ARMV8, +AARCH64_ARCH("armv9.2-a", ARMV9_2A, "v9.2a", (AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2)) -AARCH64_ARCH("armv9.3-a", ARMV9_3A, "9.3-A", "v9.3a", - ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, +AARCH64_ARCH("armv9.3-a", ARMV9_3A, "v9.3a", (AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SVE2)) // For v8-R, we do not enable crypto and align with GCC that enables a more // minimal set of optional architecture extensions. -AARCH64_ARCH("armv8-r", ARMV8R, "8-R", "v8r", - ARMBuildAttrs::CPUArch::v8_R, FK_CRYPTO_NEON_FP_ARMV8, +AARCH64_ARCH("armv8-r", ARMV8R, "v8r", (AArch64::AEK_CRC | AArch64::AEK_RDM | AArch64::AEK_SSBS | AArch64::AEK_DOTPROD | AArch64::AEK_FP | AArch64::AEK_SIMD | AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_RAS | diff --git a/llvm/include/llvm/Support/ARMTargetParser.h b/llvm/include/llvm/Support/ARMTargetParser.h --- a/llvm/include/llvm/Support/ARMTargetParser.h +++ b/llvm/include/llvm/Support/ARMTargetParser.h @@ -280,7 +280,6 @@ StringRef getDefaultCPU(StringRef Arch); StringRef getCanonicalArchName(StringRef Arch); StringRef getFPUSynonym(StringRef FPU); -StringRef getArchSynonym(StringRef Arch); // Parser uint64_t parseHWDiv(StringRef HWDiv); diff --git a/llvm/include/llvm/Support/ARMTargetParserCommon.h b/llvm/include/llvm/Support/ARMTargetParserCommon.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Support/ARMTargetParserCommon.h @@ -0,0 +1,32 @@ +//===---------------- ARMTargetParserCommon ---------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Code that is common to ARMTargetParser and AArch64TargetParser. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ARMTARGETPARSERCOMMON_H +#define LLVM_SUPPORT_ARMTARGETPARSERCOMMON_H + +#include "llvm/ADT/StringRef.h" + +namespace llvm { +namespace ARM { + +/// Converts e.g. "armv8" -> "armv8-a" +StringRef 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, minus 'eb'. +/// If invalid, return empty string. +StringRef getCanonicalArchName(StringRef Arch); + +} // namespace ARM +} // namespace llvm +#endif diff --git a/llvm/lib/Support/AArch64TargetParser.cpp b/llvm/lib/Support/AArch64TargetParser.cpp --- a/llvm/lib/Support/AArch64TargetParser.cpp +++ b/llvm/lib/Support/AArch64TargetParser.cpp @@ -14,6 +14,7 @@ #include "llvm/Support/AArch64TargetParser.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" +#include "llvm/Support/ARMTargetParserCommon.h" #include using namespace llvm; @@ -24,17 +25,6 @@ return 0; } -unsigned AArch64::getDefaultFPU(StringRef CPU, AArch64::ArchKind AK) { - if (CPU == "generic") - return AArch64ARCHNames[static_cast(AK)].DefaultFPU; - - return StringSwitch(CPU) -#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ - .Case(NAME, ARM::DEFAULT_FPU) -#include "../../include/llvm/Support/AArch64TargetParser.def" - .Default(ARM::FK_INVALID); -} - uint64_t AArch64::getDefaultExtensions(StringRef CPU, AArch64::ArchKind AK) { if (CPU == "generic") return AArch64ARCHNames[static_cast(AK)].ArchBaseExtensions; @@ -61,8 +51,7 @@ AArch64::ArchKind AArch64::getSubArchArchKind(StringRef SubArch) { return StringSwitch(SubArch) -#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, \ - ARCH_BASE_EXT) \ +#define AARCH64_ARCH(NAME, ID, SUB_ARCH, ARCH_BASE_EXT) \ .Case(SUB_ARCH, ArchKind::ID) #include "../../include/llvm/Support/AArch64TargetParser.def" .Default(ArchKind::INVALID); @@ -106,25 +95,10 @@ return AArch64ARCHNames[static_cast(AK)].getName(); } -StringRef AArch64::getCPUAttr(AArch64::ArchKind AK) { - return AArch64ARCHNames[static_cast(AK)].getCPUAttr(); -} - StringRef AArch64::getSubArch(AArch64::ArchKind AK) { return AArch64ARCHNames[static_cast(AK)].getSubArch(); } -unsigned AArch64::getArchAttr(AArch64::ArchKind AK) { - return AArch64ARCHNames[static_cast(AK)].ArchAttr; -} - -StringRef AArch64::getArchExtName(unsigned ArchExtKind) { - for (const auto &AE : AArch64ARCHExtNames) - if (ArchExtKind == AE.ID) - return AE.getName(); - return StringRef(); -} - StringRef AArch64::getArchExtFeature(StringRef ArchExt) { if (ArchExt.startswith("no")) { StringRef ArchExtBase(ArchExt.substr(2)); @@ -153,20 +127,6 @@ return static_cast(AK_v8); } -StringRef AArch64::getDefaultCPU(StringRef Arch) { - ArchKind AK = parseArch(Arch); - if (AK == ArchKind::INVALID) - return StringRef(); - - // Look for multiple AKs to find the default for pair AK+Name. - for (const auto &CPU : AArch64CPUNames) - if (CPU.ArchID == AK && CPU.Default) - return CPU.getName(); - - // If we can't find a default then target the architecture instead - return "generic"; -} - void AArch64::fillValidCPUArchList(SmallVectorImpl &Values) { for (const auto &Arch : AArch64CPUNames) { if (Arch.ArchID != ArchKind::INVALID) @@ -184,11 +144,11 @@ // Allows partial match, ex. "v8a" matches "armv8a". AArch64::ArchKind AArch64::parseArch(StringRef Arch) { - Arch = ARM::getCanonicalArchName(Arch); + Arch = llvm::ARM::getCanonicalArchName(Arch); if (checkArchVersion(Arch) < 8) return ArchKind::INVALID; - StringRef Syn = ARM::getArchSynonym(Arch); + StringRef Syn = llvm::ARM::getArchSynonym(Arch); for (const auto &A : AArch64ARCHNames) { if (A.getName().endswith(Syn)) return A.ID; diff --git a/llvm/lib/Support/ARMTargetParser.cpp b/llvm/lib/Support/ARMTargetParser.cpp --- a/llvm/lib/Support/ARMTargetParser.cpp +++ b/llvm/lib/Support/ARMTargetParser.cpp @@ -14,6 +14,7 @@ #include "llvm/Support/ARMTargetParser.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" +#include "llvm/Support/ARMTargetParserCommon.h" #include using namespace llvm; @@ -142,38 +143,6 @@ return getProfileKind(parseArch(Arch)); } -StringRef ARM::getArchSynonym(StringRef Arch) { - return StringSwitch(Arch) - .Case("v5", "v5t") - .Case("v5e", "v5te") - .Case("v6j", "v6") - .Case("v6hl", "v6k") - .Cases("v6m", "v6sm", "v6s-m", "v6-m") - .Cases("v6z", "v6zk", "v6kz") - .Cases("v7", "v7a", "v7hl", "v7l", "v7-a") - .Case("v7r", "v7-r") - .Case("v7m", "v7-m") - .Case("v7em", "v7e-m") - .Cases("v8", "v8a", "v8l", "aarch64", "arm64", "v8-a") - .Case("v8.1a", "v8.1-a") - .Case("v8.2a", "v8.2-a") - .Case("v8.3a", "v8.3-a") - .Case("v8.4a", "v8.4-a") - .Case("v8.5a", "v8.5-a") - .Case("v8.6a", "v8.6-a") - .Case("v8.7a", "v8.7-a") - .Case("v8.8a", "v8.8-a") - .Case("v8r", "v8-r") - .Cases("v9", "v9a", "v9-a") - .Case("v9.1a", "v9.1-a") - .Case("v9.2a", "v9.2-a") - .Case("v9.3a", "v9.3-a") - .Case("v8m.base", "v8-m.base") - .Case("v8m.main", "v8-m.main") - .Case("v8.1m.main", "v8.1-m.main") - .Default(Arch); -} - bool ARM::getFPUFeatures(unsigned FPUKind, std::vector &Features) { if (FPUKind >= FK_LAST || FPUKind == FK_INVALID) @@ -282,65 +251,6 @@ return FPUNames[FPUKind].NeonSupport; } -// 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, minus 'eb'. -// If invalid, return empty string. -StringRef ARM::getCanonicalArchName(StringRef Arch) { - size_t offset = StringRef::npos; - StringRef A = Arch; - StringRef Error = ""; - - // Begins with "arm" / "thumb", move past it. - if (A.startswith("arm64_32")) - offset = 8; - else if (A.startswith("arm64e")) - offset = 6; - else if (A.startswith("arm64")) - offset = 5; - else if (A.startswith("aarch64_32")) - offset = 10; - else if (A.startswith("arm")) - offset = 3; - else if (A.startswith("thumb")) - offset = 5; - else if (A.startswith("aarch64")) { - offset = 7; - // AArch64 uses "_be", not "eb" suffix. - if (A.contains("eb")) - return Error; - if (A.substr(offset, 3) == "_be") - offset += 3; - } - - // Ex. "armebv7", move past the "eb". - if (offset != StringRef::npos && A.substr(offset, 2) == "eb") - offset += 2; - // Or, if it ends with eb ("armv7eb"), chop it off. - else if (A.endswith("eb")) - A = A.substr(0, A.size() - 2); - // Trim the head - if (offset != StringRef::npos) - A = A.substr(offset); - - // Empty string means offset reached the end, which means it's valid. - if (A.empty()) - return Arch; - - // Only match non-marketing names - if (offset != StringRef::npos) { - // Must start with 'vN'. - if (A.size() >= 2 && (A[0] != 'v' || !std::isdigit(A[1]))) - return Error; - // Can't have an extra 'eb'. - if (A.contains("eb")) - return Error; - } - - // Arch will either be a 'v' name (v7a) or a marketing name (xscale). - return A; -} - StringRef ARM::getFPUSynonym(StringRef FPU) { return StringSwitch(FPU) .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported diff --git a/llvm/lib/Support/ARMTargetParserCommon.cpp b/llvm/lib/Support/ARMTargetParserCommon.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Support/ARMTargetParserCommon.cpp @@ -0,0 +1,103 @@ +//===---------------- ARMTargetParserCommon ---------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Code that is common to ARMTargetParser and AArch64TargetParser. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/ARMTargetParserCommon.h" +#include "llvm/ADT/StringSwitch.h" + +using namespace llvm; + +StringRef ARM::getArchSynonym(StringRef Arch) { + return StringSwitch(Arch) + .Case("v5", "v5t") + .Case("v5e", "v5te") + .Case("v6j", "v6") + .Case("v6hl", "v6k") + .Cases("v6m", "v6sm", "v6s-m", "v6-m") + .Cases("v6z", "v6zk", "v6kz") + .Cases("v7", "v7a", "v7hl", "v7l", "v7-a") + .Case("v7r", "v7-r") + .Case("v7m", "v7-m") + .Case("v7em", "v7e-m") + .Cases("v8", "v8a", "v8l", "aarch64", "arm64", "v8-a") + .Case("v8.1a", "v8.1-a") + .Case("v8.2a", "v8.2-a") + .Case("v8.3a", "v8.3-a") + .Case("v8.4a", "v8.4-a") + .Case("v8.5a", "v8.5-a") + .Case("v8.6a", "v8.6-a") + .Case("v8.7a", "v8.7-a") + .Case("v8.8a", "v8.8-a") + .Case("v8r", "v8-r") + .Cases("v9", "v9a", "v9-a") + .Case("v9.1a", "v9.1-a") + .Case("v9.2a", "v9.2-a") + .Case("v9.3a", "v9.3-a") + .Case("v8m.base", "v8-m.base") + .Case("v8m.main", "v8-m.main") + .Case("v8.1m.main", "v8.1-m.main") + .Default(Arch); +} + +StringRef ARM::getCanonicalArchName(StringRef Arch) { + size_t offset = StringRef::npos; + StringRef A = Arch; + StringRef Error = ""; + + // Begins with "arm" / "thumb", move past it. + if (A.startswith("arm64_32")) + offset = 8; + else if (A.startswith("arm64e")) + offset = 6; + else if (A.startswith("arm64")) + offset = 5; + else if (A.startswith("aarch64_32")) + offset = 10; + else if (A.startswith("arm")) + offset = 3; + else if (A.startswith("thumb")) + offset = 5; + else if (A.startswith("aarch64")) { + offset = 7; + // AArch64 uses "_be", not "eb" suffix. + if (A.contains("eb")) + return Error; + if (A.substr(offset, 3) == "_be") + offset += 3; + } + + // Ex. "armebv7", move past the "eb". + if (offset != StringRef::npos && A.substr(offset, 2) == "eb") + offset += 2; + // Or, if it ends with eb ("armv7eb"), chop it off. + else if (A.endswith("eb")) + A = A.substr(0, A.size() - 2); + // Trim the head + if (offset != StringRef::npos) + A = A.substr(offset); + + // Empty string means offset reached the end, which means it's valid. + if (A.empty()) + return Arch; + + // Only match non-marketing names + if (offset != StringRef::npos) { + // Must start with 'vN'. + if (A.size() >= 2 && (A[0] != 'v' || !std::isdigit(A[1]))) + return Error; + // Can't have an extra 'eb'. + if (A.contains("eb")) + return Error; + } + + // Arch will either be a 'v' name (v7a) or a marketing name (xscale). + return A; +} diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -121,6 +121,7 @@ AArch64TargetParser.cpp ABIBreak.cpp ARMTargetParser.cpp + ARMTargetParserCommon.cpp AMDGPUMetadata.cpp APFixedPoint.cpp APFloat.cpp diff --git a/llvm/unittests/Support/TargetParserTest.cpp b/llvm/unittests/Support/TargetParserTest.cpp --- a/llvm/unittests/Support/TargetParserTest.cpp +++ b/llvm/unittests/Support/TargetParserTest.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/Triple.h" #include "llvm/Support/AArch64TargetParser.h" #include "llvm/Support/ARMBuildAttributes.h" +#include "llvm/Support/ARMTargetParser.h" #include "llvm/Support/FormatVariadic.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -949,11 +950,6 @@ AArch64::getDefaultExtensions(params.CPUName, AK); EXPECT_PRED_FORMAT2(AssertSameExtensionFlags, params.ExpectedFlags, default_extensions); - - unsigned FPUKind = AArch64::getDefaultFPU(params.CPUName, AK); - EXPECT_EQ(params.ExpectedFPU, ARM::getFPUName(FPUKind)); - - EXPECT_EQ(params.CPUAttr, AArch64::getCPUAttr(AK)); } INSTANTIATE_TEST_SUITE_P( @@ -1404,10 +1400,7 @@ bool testAArch64Arch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch, unsigned ArchAttr) { AArch64::ArchKind AK = AArch64::parseArch(Arch); - return (AK != AArch64::ArchKind::INVALID) && - AArch64::getDefaultCPU(Arch).equals(DefaultCPU) && - AArch64::getSubArch(AK).equals(SubArch) && - (AArch64::getArchAttr(AK) == ArchAttr); + return AK != AArch64::ArchKind::INVALID; } TEST(TargetParserTest, testAArch64Arch) {