From f4225d325c19ae0e5dbe39faa900d81e24559da0 Mon Sep 17 00:00:00 2001 From: Tomas Matheson Date: Fri, 9 Dec 2022 11:36:06 +0000 Subject: [PATCH] [AArch64] Reland "Improve TargetParser API" Reworked after several other major changes to the TargetParser since this was reverted. Combined with several other changes. Inline calls for the following macros and delete AArch64TargetParser.def: AARCH64_ARCH, AARCH64_CPU_NAME, AARCH64_CPU_ALIAS, AARCH64_ARCH_EXT_NAME Squashed changes from D139278 and D139102. Differential Revision: https://reviews.llvm.org/D138792 --- clang/lib/Basic/Targets/AArch64.cpp | 322 +++++++-------- clang/lib/Basic/Targets/AArch64.h | 3 +- clang/lib/Driver/ToolChains/Arch/AArch64.cpp | 59 ++- clang/test/Preprocessor/aarch64-target-features.c | 22 +- flang/test/Driver/target-cpu-features.f90 | 2 +- .../command-disassemble-aarch64-extensions.s | 193 ++++----- llvm/include/llvm/ADT/StringRef.h | 3 +- llvm/include/llvm/Support/VersionTuple.h | 13 +- .../llvm/TargetParser/AArch64TargetParser.def | 434 --------------------- .../llvm/TargetParser/AArch64TargetParser.h | 390 ++++++++++++++---- .../Target/AArch64/AsmParser/AArch64AsmParser.cpp | 79 ++-- llvm/lib/TargetParser/AArch64TargetParser.cpp | 162 +++----- llvm/unittests/TargetParser/TargetParserTest.cpp | 326 +++++++--------- 13 files changed, 853 insertions(+), 1155 deletions(-) delete mode 100644 llvm/include/llvm/TargetParser/AArch64TargetParser.def diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index a4b27bb..d7893c1 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -47,69 +47,58 @@ static constexpr Builtin::Info BuiltinInfo[] = { #include "clang/Basic/BuiltinsAArch64.def" }; -static StringRef getArchVersionString(llvm::AArch64::ArchKind Kind) { - switch (Kind) { - case llvm::AArch64::ArchKind::ARMV9A: - case llvm::AArch64::ArchKind::ARMV9_1A: - case llvm::AArch64::ArchKind::ARMV9_2A: - case llvm::AArch64::ArchKind::ARMV9_3A: - case llvm::AArch64::ArchKind::ARMV9_4A: - return "9"; - default: - return "8"; - } -} - void AArch64TargetInfo::setArchFeatures() { - switch (ArchKind) { - case llvm::AArch64::ArchKind::ARMV8_9A: - case llvm::AArch64::ArchKind::ARMV8_8A: - case llvm::AArch64::ArchKind::ARMV8_7A: - HasWFxT = true; - LLVM_FALLTHROUGH; - case llvm::AArch64::ArchKind::ARMV8_6A: - HasBFloat16 = true; - HasMatMul = true; - LLVM_FALLTHROUGH; - case llvm::AArch64::ArchKind::ARMV8_5A: - HasAlternativeNZCV = true; - HasFRInt3264 = true; - HasSSBS = true; - HasSB = true; - HasPredRes = true; - HasBTI = true; - LLVM_FALLTHROUGH; - case llvm::AArch64::ArchKind::ARMV8_4A: + if (*ArchInfo == llvm::AArch64::ARMV8R) { HasDotProd = true; HasDIT = true; HasFlagM = true; - LLVM_FALLTHROUGH; - case llvm::AArch64::ArchKind::ARMV8_3A: HasRCPC = true; FPU |= NeonMode; - LLVM_FALLTHROUGH; - case llvm::AArch64::ArchKind::ARMV8_2A: HasCCPP = true; - LLVM_FALLTHROUGH; - case llvm::AArch64::ArchKind::ARMV8_1A: HasCRC = true; HasLSE = true; HasRDM = true; - return; - default: - break; - } - switch (ArchKind) { - case llvm::AArch64::ArchKind::ARMV9_4A: - case llvm::AArch64::ArchKind::ARMV9_3A: - case llvm::AArch64::ArchKind::ARMV9_2A: - HasWFxT = true; - LLVM_FALLTHROUGH; - case llvm::AArch64::ArchKind::ARMV9_1A: - HasBFloat16 = true; - HasMatMul = true; - LLVM_FALLTHROUGH; - case llvm::AArch64::ArchKind::ARMV9A: + } else if (ArchInfo->Version.getMajor() == 8) { + if (ArchInfo->Version.getMinor() >= 7) { + HasWFxT = true; + } + if (ArchInfo->Version.getMinor() >= 6) { + HasBFloat16 = true; + HasMatMul = true; + } + if (ArchInfo->Version.getMinor() >= 5) { + HasAlternativeNZCV = true; + HasFRInt3264 = true; + HasSSBS = true; + HasSB = true; + HasPredRes = true; + HasBTI = true; + } + if (ArchInfo->Version.getMinor() >= 4) { + HasDotProd = true; + HasDIT = true; + HasFlagM = true; + } + if (ArchInfo->Version.getMinor() >= 3) { + HasRCPC = true; + FPU |= NeonMode; + } + if (ArchInfo->Version.getMinor() >= 2) { + HasCCPP = true; + } + if (ArchInfo->Version.getMinor() >= 1) { + HasCRC = true; + HasLSE = true; + HasRDM = true; + } + } else if (ArchInfo->Version.getMajor() == 9) { + if (ArchInfo->Version.getMinor() >= 2) { + HasWFxT = true; + } + if (ArchInfo->Version.getMinor() >= 1) { + HasBFloat16 = true; + HasMatMul = true; + } FPU |= SveMode; HasSVE2 = true; HasFullFP16 = true; @@ -128,29 +117,6 @@ void AArch64TargetInfo::setArchFeatures() { HasCRC = true; HasLSE = true; HasRDM = true; - return; - default: - break; - } - if (ArchKind == llvm::AArch64::ArchKind::ARMV8R) { - HasDotProd = true; - HasDIT = true; - HasFlagM = true; - HasRCPC = true; - FPU |= NeonMode; - HasCCPP = true; - HasCRC = true; - HasLSE = true; - HasRDM = true; - } -} - -StringRef AArch64TargetInfo::getArchProfile() const { - switch (ArchKind) { - case llvm::AArch64::ArchKind::ARMV8R: - return "R"; - default: - return "A"; } } @@ -257,7 +223,7 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef, bool AArch64TargetInfo::isValidCPUName(StringRef Name) const { return Name == "generic" || - llvm::AArch64::parseCPUArch(Name) != llvm::AArch64::ArchKind::INVALID; + llvm::AArch64::parseCpu(Name).Arch != llvm::AArch64::INVALID; } bool AArch64TargetInfo::setCPU(const std::string &Name) { @@ -387,8 +353,10 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, // ACLE predefines. Many can only have one possible value on v8 AArch64. Builder.defineMacro("__ARM_ACLE", "200"); - Builder.defineMacro("__ARM_ARCH", getArchVersionString(ArchKind)); - Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + getArchProfile() + "'"); + Builder.defineMacro("__ARM_ARCH", + std::to_string(ArchInfo->Version.getMajor())); + Builder.defineMacro("__ARM_ARCH_PROFILE", + std::string("'") + (char)ArchInfo->Profile + "'"); Builder.defineMacro("__ARM_64BIT_STATE", "1"); Builder.defineMacro("__ARM_PCS_AAPCS64", "1"); @@ -559,52 +527,34 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasD128) Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1"); - switch (ArchKind) { - default: - break; - case llvm::AArch64::ArchKind::ARMV8_1A: + if (*ArchInfo == llvm::AArch64::ARMV8_1A) getTargetDefinesARMV81A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_2A: + else if (*ArchInfo == llvm::AArch64::ARMV8_2A) getTargetDefinesARMV82A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_3A: + else if (*ArchInfo == llvm::AArch64::ARMV8_3A) getTargetDefinesARMV83A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_4A: + else if (*ArchInfo == llvm::AArch64::ARMV8_4A) getTargetDefinesARMV84A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_5A: + else if (*ArchInfo == llvm::AArch64::ARMV8_5A) getTargetDefinesARMV85A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_6A: + else if (*ArchInfo == llvm::AArch64::ARMV8_6A) getTargetDefinesARMV86A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_7A: + else if (*ArchInfo == llvm::AArch64::ARMV8_7A) getTargetDefinesARMV87A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_8A: + else if (*ArchInfo == llvm::AArch64::ARMV8_8A) getTargetDefinesARMV88A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV8_9A: + else if (*ArchInfo == llvm::AArch64::ARMV8_9A) getTargetDefinesARMV89A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV9A: + else if (*ArchInfo == llvm::AArch64::ARMV9A) getTargetDefinesARMV9A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV9_1A: + else if (*ArchInfo == llvm::AArch64::ARMV9_1A) getTargetDefinesARMV91A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV9_2A: + else if (*ArchInfo == llvm::AArch64::ARMV9_2A) getTargetDefinesARMV92A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV9_3A: + else if (*ArchInfo == llvm::AArch64::ARMV9_3A) getTargetDefinesARMV93A(Opts, Builder); - break; - case llvm::AArch64::ArchKind::ARMV9_4A: + else if (*ArchInfo == llvm::AArch64::ARMV9_4A) getTargetDefinesARMV94A(Opts, Builder); - break; - } // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work. Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); @@ -645,42 +595,34 @@ AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const { unsigned AArch64TargetInfo::multiVersionSortPriority(StringRef Name) const { if (Name == "default") return 0; - unsigned Priority = llvm::StringSwitch(Name) -#define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE, FMV_ID, \ - DEP_FEATURES, FMV_PRIORITY) \ - .Case(NAME, FMV_PRIORITY) -#include "llvm/TargetParser/AArch64TargetParser.def" - ; - assert((Name == "none" || Priority < multiVersionFeatureCost()) && - "FMV priority is out of bounds!"); - return Priority; + for (const auto &E : llvm::AArch64::Extensions) + if (Name == E.Name) + return E.FmvPriority; + return 0; } unsigned AArch64TargetInfo::multiVersionFeatureCost() const { // Take the maximum priority as per feature cost, so more features win. - // AARCH64_ARCH_EXT_NAME "none" feature must have top priority, use it. - return multiVersionSortPriority("none"); + return llvm::AArch64::ExtensionInfo::MaxFMVPriority; } bool AArch64TargetInfo::getFeatureDepOptions(StringRef Name, std::string &FeatureVec) const { - FeatureVec = llvm::StringSwitch(Name) -#define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE, FMV_ID, \ - DEP_FEATURES, FMV_PRIORITY) \ - .Case(NAME, DEP_FEATURES) -#include "llvm/TargetParser/AArch64TargetParser.def" - .Default(""); + FeatureVec = ""; + for (const auto &E : llvm::AArch64::Extensions) { + if (Name == E.Name) { + FeatureVec = E.DependentFeatures; + break; + } + } return FeatureVec != ""; } bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const { - unsigned Feat = llvm::StringSwitch(FeatureStr) -#define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE, FMV_ID, \ - DEP_FEATURES, FMV_PRIORITY) \ - .Case(NAME, llvm::AArch64::FEAT_##FMV_ID) -#include "llvm/TargetParser/AArch64TargetParser.def" - .Default(llvm::AArch64::FEAT_MAX); - return Feat != llvm::AArch64::FEAT_MAX; + for (const auto &E : llvm::AArch64::Extensions) + if (FeatureStr == E.Name) + return true; + return false; } bool AArch64TargetInfo::hasFeature(StringRef Feature) const { @@ -736,24 +678,21 @@ bool AArch64TargetInfo::hasFeature(StringRef Feature) const { void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap &Features, StringRef Name, bool Enabled) const { Features[Name] = Enabled; - // If the feature is an architecture feature (like v8.2a), add all previous // architecture versions and any dependant target features. - llvm::AArch64::ArchKind AK = llvm::AArch64::getSubArchArchKind(Name); - if (AK == llvm::AArch64::ArchKind::INVALID) - return; - // In case of v9.x the v8.x counterparts are added too. - if ("9" == getArchVersionString(AK)) - for (llvm::AArch64::ArchKind I = llvm::AArch64::convertV9toV8(AK); - I != llvm::AArch64::ArchKind::INVALID; --I) - Features[llvm::AArch64::getSubArch(I)] = Enabled; - - llvm::AArch64::ArchKind I = AK; - for (--I; I != llvm::AArch64::ArchKind::INVALID; --I) - Features[llvm::AArch64::getSubArch(I)] = Enabled; + const llvm::AArch64::ArchInfo &ArchInfo = + llvm::AArch64::ArchInfo::findBySubArch(Name); + + if (ArchInfo == llvm::AArch64::INVALID) + return; // Not an architecure, nothing more to do. + + for (const auto *OtherArch : llvm::AArch64::ArchInfos) + if (ArchInfo.implies(*OtherArch)) + Features[OtherArch->getSubArch()] = Enabled; // Set any features implied by the architecture - uint64_t Extensions = llvm::AArch64::getDefaultExtensions("generic", AK); + uint64_t Extensions = + llvm::AArch64::getDefaultExtensions("generic", ArchInfo); std::vector CPUFeats; if (llvm::AArch64::getExtensionFeatures(Extensions, CPUFeats)) { for (auto F : CPUFeats) { @@ -899,38 +838,51 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector &Features, if (Feature == "+strict-align") HasUnaligned = false; // All predecessor archs are added but select the latest one for ArchKind. - if (Feature == "+v8a" && ArchKind < llvm::AArch64::ArchKind::ARMV8A) - ArchKind = llvm::AArch64::ArchKind::ARMV8A; - if (Feature == "+v8.1a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_1A) - ArchKind = llvm::AArch64::ArchKind::ARMV8_1A; - if (Feature == "+v8.2a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_2A) - ArchKind = llvm::AArch64::ArchKind::ARMV8_2A; - if (Feature == "+v8.3a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_3A) - ArchKind = llvm::AArch64::ArchKind::ARMV8_3A; - if (Feature == "+v8.4a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_4A) - ArchKind = llvm::AArch64::ArchKind::ARMV8_4A; - if (Feature == "+v8.5a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_5A) - ArchKind = llvm::AArch64::ArchKind::ARMV8_5A; - if (Feature == "+v8.6a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_6A) - ArchKind = llvm::AArch64::ArchKind::ARMV8_6A; - if (Feature == "+v8.7a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_7A) - ArchKind = llvm::AArch64::ArchKind::ARMV8_7A; - if (Feature == "+v8.8a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_8A) - ArchKind = llvm::AArch64::ArchKind::ARMV8_8A; - if (Feature == "+v8.9a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_9A) - ArchKind = llvm::AArch64::ArchKind::ARMV8_9A; - if (Feature == "+v9a" && ArchKind < llvm::AArch64::ArchKind::ARMV9A) - ArchKind = llvm::AArch64::ArchKind::ARMV9A; - if (Feature == "+v9.1a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_1A) - ArchKind = llvm::AArch64::ArchKind::ARMV9_1A; - if (Feature == "+v9.2a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_2A) - ArchKind = llvm::AArch64::ArchKind::ARMV9_2A; - if (Feature == "+v9.3a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_3A) - ArchKind = llvm::AArch64::ArchKind::ARMV9_3A; - if (Feature == "+v9.4a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_4A) - ArchKind = llvm::AArch64::ArchKind::ARMV9_4A; + if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version) + ArchInfo = &llvm::AArch64::ARMV8A; + if (Feature == "+v8.1a" && + ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version) + ArchInfo = &llvm::AArch64::ARMV8_1A; + if (Feature == "+v8.2a" && + ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version) + ArchInfo = &llvm::AArch64::ARMV8_2A; + if (Feature == "+v8.3a" && + ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version) + ArchInfo = &llvm::AArch64::ARMV8_3A; + if (Feature == "+v8.4a" && + ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version) + ArchInfo = &llvm::AArch64::ARMV8_4A; + if (Feature == "+v8.5a" && + ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version) + ArchInfo = &llvm::AArch64::ARMV8_5A; + if (Feature == "+v8.6a" && + ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version) + ArchInfo = &llvm::AArch64::ARMV8_6A; + if (Feature == "+v8.7a" && + ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version) + ArchInfo = &llvm::AArch64::ARMV8_7A; + if (Feature == "+v8.8a" && + ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version) + ArchInfo = &llvm::AArch64::ARMV8_8A; + if (Feature == "+v8.9a" && + ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version) + ArchInfo = &llvm::AArch64::ARMV8_9A; + if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version) + ArchInfo = &llvm::AArch64::ARMV9A; + if (Feature == "+v9.1a" && + ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version) + ArchInfo = &llvm::AArch64::ARMV9_1A; + if (Feature == "+v9.2a" && + ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version) + ArchInfo = &llvm::AArch64::ARMV9_2A; + if (Feature == "+v9.3a" && + ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version) + ArchInfo = &llvm::AArch64::ARMV9_3A; + if (Feature == "+v9.4a" && + ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version) + ArchInfo = &llvm::AArch64::ARMV9_4A; if (Feature == "+v8r") - ArchKind = llvm::AArch64::ArchKind::ARMV8R; + ArchInfo = &llvm::AArch64::ARMV8R; if (Feature == "+fullfp16") { FPU |= NeonMode; HasFullFP16 = true; @@ -998,8 +950,8 @@ bool AArch64TargetInfo::initFeatureMap( const std::vector &FeaturesVec) const { std::vector UpdatedFeaturesVec; // Parse the CPU and add any implied features. - llvm::AArch64::ArchKind Arch = llvm::AArch64::parseCPUArch(CPU); - if (Arch != llvm::AArch64::ArchKind::INVALID) { + const llvm::AArch64::ArchInfo &Arch = llvm::AArch64::parseCpu(CPU).Arch; + if (Arch != llvm::AArch64::INVALID) { uint64_t Exts = llvm::AArch64::getDefaultExtensions(CPU, Arch); std::vector CPUFeats; llvm::AArch64::getExtensionFeatures(Exts, CPUFeats); @@ -1082,13 +1034,13 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const { FoundArch = true; std::pair Split = Feature.split("=").second.trim().split("+"); - llvm::AArch64::ArchKind ArchKind = llvm::AArch64::parseArch(Split.first); + const llvm::AArch64::ArchInfo &AI = llvm::AArch64::parseArch(Split.first); // Parse the architecture version, adding the required features to // Ret.Features. - if (ArchKind == llvm::AArch64::ArchKind::INVALID) + if (AI == llvm::AArch64::INVALID) continue; - Ret.Features.push_back(llvm::AArch64::getArchFeature(ArchKind).str()); + Ret.Features.push_back(AI.ArchFeature.str()); // Add any extra features, after the + SplitAndAddFeatures(Split.second, Ret.Features); } else if (Feature.startswith("cpu=")) { diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 55e8a63..95edf69 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -76,10 +76,9 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool HasNoSVE = false; bool HasFMV = true; - llvm::AArch64::ArchKind ArchKind = llvm::AArch64::ArchKind::INVALID; + const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A; std::string ABI; - StringRef getArchProfile() const; public: AArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index 2a12693..fcbf2e0 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -70,7 +70,7 @@ std::string aarch64::getAArch64TargetCPU(const ArgList &Args, // Decode AArch64 features from string like +[no]featureA+[no]featureB+... static bool DecodeAArch64Features(const Driver &D, StringRef text, std::vector &Features, - llvm::AArch64::ArchKind ArchKind) { + const llvm::AArch64::ArchInfo &ArchInfo) { SmallVector Split; text.split(Split, StringRef("+"), -1, false); @@ -104,14 +104,14 @@ static bool DecodeAArch64Features(const Driver &D, StringRef text, // +sve implies +f32mm if the base architecture is >= v8.6A (except v9A) // It isn't the case in general that sve implies both f64mm and f32mm - if ((ArchKind == llvm::AArch64::ArchKind::ARMV8_6A || - ArchKind == llvm::AArch64::ArchKind::ARMV8_7A || - ArchKind == llvm::AArch64::ArchKind::ARMV8_8A || - ArchKind == llvm::AArch64::ArchKind::ARMV8_9A || - ArchKind == llvm::AArch64::ArchKind::ARMV9_1A || - ArchKind == llvm::AArch64::ArchKind::ARMV9_2A || - ArchKind == llvm::AArch64::ArchKind::ARMV9_3A || - ArchKind == llvm::AArch64::ArchKind::ARMV9_4A) && + if ((ArchInfo == llvm::AArch64::ARMV8_6A || + ArchInfo == llvm::AArch64::ARMV8_7A || + ArchInfo == llvm::AArch64::ARMV8_8A || + ArchInfo == llvm::AArch64::ARMV8_9A || + ArchInfo == llvm::AArch64::ARMV9_1A || + ArchInfo == llvm::AArch64::ARMV9_2A || + ArchInfo == llvm::AArch64::ARMV9_3A || + ArchInfo == llvm::AArch64::ARMV9_4A) && Feature == "sve") Features.push_back("+f32mm"); } @@ -123,10 +123,8 @@ static bool DecodeAArch64Features(const Driver &D, StringRef text, static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU, std::vector &Features) { std::pair Split = Mcpu.split("+"); - CPU = Split.first; - llvm::AArch64::ArchKind ArchKind = llvm::AArch64::ArchKind::ARMV8A; - - CPU = llvm::AArch64::resolveCPUAlias(CPU); + const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A; + CPU = llvm::AArch64::resolveCPUAlias(Split.first); if (CPU == "native") CPU = llvm::sys::getHostCPUName(); @@ -134,21 +132,21 @@ static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU, if (CPU == "generic") { Features.push_back("+neon"); } else { - ArchKind = llvm::AArch64::parseCPUArch(CPU); - if (ArchKind == llvm::AArch64::ArchKind::INVALID) + ArchInfo = &llvm::AArch64::parseCpu(CPU).Arch; + if (*ArchInfo == llvm::AArch64::INVALID) return false; - Features.push_back(llvm::AArch64::getArchFeature(ArchKind)); + Features.push_back(ArchInfo->ArchFeature); - uint64_t Extension = llvm::AArch64::getDefaultExtensions(CPU, ArchKind); + uint64_t Extension = llvm::AArch64::getDefaultExtensions(CPU, *ArchInfo); if (!llvm::AArch64::getExtensionFeatures(Extension, Features)) return false; - } + } - if (Split.second.size() && - !DecodeAArch64Features(D, Split.second, Features, ArchKind)) - return false; + if (Split.second.size() && + !DecodeAArch64Features(D, Split.second, Features, *ArchInfo)) + return false; - return true; + return true; } static bool @@ -158,25 +156,26 @@ getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March, std::string MarchLowerCase = March.lower(); std::pair Split = StringRef(MarchLowerCase).split("+"); - llvm::AArch64::ArchKind ArchKind = llvm::AArch64::parseArch(Split.first); + const llvm::AArch64::ArchInfo *ArchInfo = + &llvm::AArch64::parseArch(Split.first); if (Split.first == "native") - ArchKind = llvm::AArch64::getCPUArchKind(llvm::sys::getHostCPUName().str()); - if (ArchKind == llvm::AArch64::ArchKind::INVALID) + ArchInfo = &llvm::AArch64::getArchForCpu(llvm::sys::getHostCPUName().str()); + if (*ArchInfo == llvm::AArch64::INVALID) return false; - Features.push_back(llvm::AArch64::getArchFeature(ArchKind)); + Features.push_back(ArchInfo->ArchFeature); // Enable SVE2 by default on Armv9-A. // It can still be disabled if +nosve2 is present. // We must do this early so that DecodeAArch64Features has the correct state - if ((ArchKind == llvm::AArch64::ArchKind::ARMV9A || - ArchKind == llvm::AArch64::ArchKind::ARMV9_1A || - ArchKind == llvm::AArch64::ArchKind::ARMV9_2A)) { + if ((*ArchInfo == llvm::AArch64::ARMV9A || + *ArchInfo == llvm::AArch64::ARMV9_1A || + *ArchInfo == llvm::AArch64::ARMV9_2A)) { Features.push_back("+sve"); Features.push_back("+sve2"); } if ((Split.second.size() && - !DecodeAArch64Features(D, Split.second, Features, ArchKind))) + !DecodeAArch64Features(D, Split.second, Features, *ArchInfo))) return false; return true; diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c index 3ec31e1..8ad5b3a 100644 --- a/clang/test/Preprocessor/aarch64-target-features.c +++ b/clang/test/Preprocessor/aarch64-target-features.c @@ -295,29 +295,29 @@ // RUN: %clang -target aarch64 -mcpu=a64fx -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-A64FX %s // RUN: %clang -target aarch64 -mcpu=carmel -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-CARMEL %s // CHECK-MCPU-APPLE-A7: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+sha2" "-target-feature" "+aes" -// CHECK-MCPU-APPLE-A10: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+crc" "-target-feature" "+rdm" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+sha2" "-target-feature" "+aes" -// CHECK-MCPU-APPLE-A11: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+crc" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+fullfp16" "-target-feature" "+ras" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+sha2" "-target-feature" "+aes" -// CHECK-MCPU-APPLE-A12: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.3a" "-target-feature" "+crc" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+fullfp16" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+sha2" "-target-feature" "+aes" +// CHECK-MCPU-APPLE-A10: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+rdm" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+sha2" "-target-feature" "+aes" +// CHECK-MCPU-APPLE-A11: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+sha2" "-target-feature" "+aes" +// CHECK-MCPU-APPLE-A12: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.3a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+sha2" "-target-feature" "+aes" // CHECK-MCPU-A34: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" -// CHECK-MCPU-APPLE-A13: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.4a" "-target-feature" "+crc" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+crypto" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+fp16fml" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+fullfp16" "-target-feature" "+sm4" "-target-feature" "+sha3" "-target-feature" "+sha2" "-target-feature" "+aes" +// CHECK-MCPU-APPLE-A13: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.4a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+fp16fml" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+fullfp16" "-target-feature" "+sm4" "-target-feature" "+sha3" "-target-feature" "+sha2" "-target-feature" "+aes" // CHECK-MCPU-A35: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" // CHECK-MCPU-A53: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" // CHECK-MCPU-A57: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" // CHECK-MCPU-A72: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" // CHECK-MCPU-CORTEX-A73: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" -// CHECK-MCPU-CORTEX-R82: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8r" "-target-feature" "+crc" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+fp16fml" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+ssbs" "-target-feature" "+sb" "-target-feature" "+fullfp16" +// CHECK-MCPU-CORTEX-R82: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8r" "-target-feature" "+crc" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+fp16fml" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+sb" "-target-feature" "+neon" "-target-feature" "+ssbs" "-target-feature" "+fullfp16" // CHECK-MCPU-M3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" -// CHECK-MCPU-M4: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+crc" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+crypto" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+fullfp16" +// CHECK-MCPU-M4: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+neon" "-target-feature" "+sha2" "-target-feature" "+aes" // CHECK-MCPU-KRYO: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" -// CHECK-MCPU-THUNDERX2T99: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+crc" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" -// CHECK-MCPU-A64FX: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+crc" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+fullfp16" "-target-feature" "+ras" "-target-feature" "+sve" "-target-feature" "+sha2" -// CHECK-MCPU-CARMEL: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+crc" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+fullfp16" "-target-feature" "+ras" "-target-feature" "+sha2" "-target-feature" "+aes" +// CHECK-MCPU-THUNDERX2T99: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.1a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+neon" "-target-feature" "+sha2" "-target-feature" "+aes" +// CHECK-MCPU-A64FX: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+neon" "-target-feature" "+sve" "-target-feature" "+sha2" "-target-feature" "+aes" +// CHECK-MCPU-CARMEL: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.2a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rdm" "-target-feature" "+neon" "-target-feature" "+sha2" "-target-feature" "+aes" // RUN: %clang -target x86_64-apple-macosx -arch arm64 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARCH-ARM64 %s -// CHECK-ARCH-ARM64: "-target-cpu" "apple-m1" "-target-feature" "+v8.5a" "-target-feature" "+crc" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+crypto" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+fp16fml" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+fullfp16" "-target-feature" "+sm4" "-target-feature" "+sha3" "-target-feature" "+sha2" "-target-feature" "+aes" +// CHECK-ARCH-ARM64: "-target-cpu" "apple-m1" "-target-feature" "+v8.5a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+fp16fml" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+fullfp16" "-target-feature" "+sm4" "-target-feature" "+sha3" "-target-feature" "+sha2" "-target-feature" "+aes" // RUN: %clang -target x86_64-apple-macosx -arch arm64_32 -### -c %s 2>&1 | FileCheck --check-prefix=CHECK-ARCH-ARM64_32 %s -// CHECK-ARCH-ARM64_32: "-target-cpu" "apple-s4" "-target-feature" "+v8.3a" "-target-feature" "+crc" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+fullfp16" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+sha2" "-target-feature" "+aes" +// CHECK-ARCH-ARM64_32: "-target-cpu" "apple-s4" "-target-feature" "+v8.3a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz" "-target-feature" "+sha2" "-target-feature" "+aes" // RUN: %clang -target aarch64 -march=armv8-a+fp+simd+crc+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-1 %s // RUN: %clang -target aarch64 -march=armv8-a+nofp+nosimd+nocrc+nocrypto+fp+simd+crc+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-1 %s diff --git a/flang/test/Driver/target-cpu-features.f90 b/flang/test/Driver/target-cpu-features.f90 index 985a13d..0270448 100644 --- a/flang/test/Driver/target-cpu-features.f90 +++ b/flang/test/Driver/target-cpu-features.f90 @@ -36,7 +36,7 @@ ! CHECK-A57-SAME: "-target-cpu" "cortex-a57" "-target-feature" "+v8a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+sha2" "-target-feature" "+aes" ! CHECK-A76: "-fc1" "-triple" "aarch64-unknown-linux-gnu" -! CHECK-A76-SAME: "-target-cpu" "cortex-a76" "-target-feature" "+v8.2a" "-target-feature" "+crc" "-target-feature" "+lse" "-target-feature" "+rdm" "-target-feature" "+crypto" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+fullfp16" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+ssbs" "-target-feature" "+sha2" "-target-feature" "+aes" +! CHECK-A76-SAME: "-target-cpu" "cortex-a76" "-target-feature" "+v8.2a" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+dotprod" "-target-feature" "+fp-armv8" "-target-feature" "+fullfp16" "-target-feature" "+lse" "-target-feature" "+ras" "-target-feature" "+rcpc" "-target-feature" "+rdm" "-target-feature" "+neon" "-target-feature" "+ssbs" "-target-feature" "+sha2" "-target-feature" "+aes" ! CHECK-ARMV9: "-fc1" "-triple" "aarch64-unknown-linux-gnu" ! CHECK-ARMV9-SAME: "-target-cpu" "generic" "-target-feature" "+neon" "-target-feature" "+v9a" "-target-feature" "+sve" "-target-feature" "+sve2" diff --git a/lldb/test/Shell/Commands/command-disassemble-aarch64-extensions.s b/lldb/test/Shell/Commands/command-disassemble-aarch64-extensions.s index 480ed6b..e154f54 100644 --- a/lldb/test/Shell/Commands/command-disassemble-aarch64-extensions.s +++ b/lldb/test/Shell/Commands/command-disassemble-aarch64-extensions.s @@ -9,98 +9,111 @@ .globl fn .type fn, @function fn: - // These are in the same order as llvm/include/llvm/TargetParser/AArch64TargetParser.def - crc32b w0, w0, w0 // CRC - ldaddab w0, w0, [sp] // LSE - sqrdmlah v0.4h, v1.4h, v2.4h // RDM - // CRYPTO enables a combination of other features - sm4e v0.4s, v0.4s // SM4 - bcax v0.16b, v0.16b, v0.16b, v0.16b // SHA3 - sha256h q0, q0, v0.4s // SHA256 - aesd v0.16b, v0.16b // AES - sdot v0.2s, v1.8b, v2.8b // DOTPROD - fcvt d0, s0 // FP - addp v0.4s, v0.4s, v0.4s // SIMD (neon) - fabs h1, h2 // FP16 - fmlal v0.2s, v1.2h, v2.2h // FP16FML - psb csync // PROFILE/SPE - msr erxpfgctl_el1, x0 // RAS - abs z31.h, p7/m, z31.h // SVE - sqdmlslbt z0.d, z1.s, z31.s // SVE2 - aesd z0.b, z0.b, z31.b // SVE2AES - sm4e z0.s, z0.s, z0.s // SVE2SM4 - rax1 z0.d, z0.d, z0.d // SVE2SHA3 - bdep z0.b, z1.b, z31.b // SVE2BITPERM - addqv v0.8h, p0, z0.h // SVE2p1 / SME2p1 - bfadd z23.h, p3/m, z23.h, z13.h // B16B16 - ldaprb w0, [x0, #0] // RCPC - mrs x0, rndr // RAND - irg x0, x0 // MTE - mrs x2, ssbs // SSBS - sb // SB - cfp rctx, x0 // PREDRES - bfdot v2.2s, v3.4h, v4.4h // BF16 - smmla v1.4s, v16.16b, v31.16b // I8MM - fmmla z0.s, z1.s, z2.s // F32MM - fmmla z0.d, z1.d, z2.d // F64MM - tcommit // TME - ld64b x0, [x13] // LS64 - brb iall // BRBE - pacia x0, x1 // PAUTH - cfinv // FLAGM - addha za0.s, p0/m, p0/m, z0.s // SME - fmopa za0.d, p0/m, p0/m, z0.d, z0.d // SMEF64 - addha za0.d, p0/m, p0/m, z0.d // SMEI64 - add {z0.h, z1.h}, {z0.h, z1.h}, z0.h // SME2 + // These are in alphabetical order by extension name + aesd v0.16b, v0.16b // AEK_AES + bfadd z23.h, p3/m, z23.h, z13.h // AEK_B16B16 + bfdot v2.2s, v3.4h, v4.4h // AEK_BF16 + brb iall // AEK_BRBE + crc32b w0, w0, w0 // AEK_CRC + // AEK_CRYPTO enables a combination of other features + smin x0, x0, #0 // AEK_CSSC + sysp #0, c2, c0, #0, x0, x1 // AEK_D128 + sdot v0.2s, v1.8b, v2.8b // AEK_DOTPROD + fmmla z0.s, z1.s, z2.s // AEK_F32MM + fmmla z0.d, z1.d, z2.d // AEK_F64MM + cfinv // AEK_FLAGM + fcvt d0, s0 // AEK_FP + fabs h1, h2 // AEK_FP16 + fmlal v0.2s, v1.2h, v2.2h // AEK_FP16FML + bc.eq lbl // AEK_HBC + smmla v1.4s, v16.16b, v31.16b // AEK_I8MM + ld64b x0, [x13] // AEK_LS64 + ldaddab w0, w0, [sp] // AEK_LSE + ldclrp x1, x2, [x11] // AEK_LSE128 + irg x0, x0 // AEK_MTE + cpyfp [x0]!, [x1]!, x2! // AEK_MOPS + pacia x0, x1 // AEK_PAUTH + mrs x0, pmccntr_el0 // AEK_PERFMON + cfp rctx, x0 // AEK_PREDRES + psb csync // AEK_PROFILE/SPE + msr erxpfgctl_el1, x0 // AEK_RAS + ldaprb w0, [x0, #0] // AEK_RCPC + stilp w26, w2, [x18] // AEK_RCPC3 + sqrdmlah v0.4h, v1.4h, v2.4h // AEK_RDM + mrs x0, rndr // AEK_RAND + sb // AEK_SB + sha256h q0, q0, v0.4s // AEK_SHA2 + bcax v0.16b, v0.16b, v0.16b, v0.16b // AEK_SHA3 + addp v0.4s, v0.4s, v0.4s // AEK_SIMD (neon) + sm4e v0.4s, v0.4s // AEK_SM4 + addha za0.s, p0/m, p0/m, z0.s // AEK_SME + fadd za.h[w11, 7], {z12.h - z13.h} // AEK_SMEF16F16 + fmopa za0.d, p0/m, p0/m, z0.d, z0.d // AEK_SMEF64F64 + addha za0.d, p0/m, p0/m, z0.d // AEK_SMEI16I64 + add {z0.h, z1.h}, {z0.h, z1.h}, z0.h // AEK_SME2 + // AEK_SME2P1: see AEK_SVE2P1 + mrs x2, ssbs // AEK_SSBS + abs z31.h, p7/m, z31.h // AEK_SVE + sqdmlslbt z0.d, z1.s, z31.s // AEK_SVE2 + aesd z0.b, z0.b, z31.b // AEK_SVE2AES + bdep z0.b, z1.b, z31.b // AEK_SVE2BITPERM + rax1 z0.d, z0.d, z0.d // AEK_SVE2SHA3 + sm4e z0.s, z0.s, z0.s // AEK_SVE2SM4 + addqv v0.8h, p0, z0.h // AEK_SVE2p1 / AEK_SME2p1 + rcwswp x0, x1, [x2] // AEK_THE + tcommit // AEK_TME lbl: - bc.eq lbl // HBC - cpyfp [x0]!, [x1]!, x2! // MOPS - mrs x0, pmccntr_el0 // PERFMON .fn_end: .size fn, .fn_end-fn # CHECK: command-disassemble-aarch64-extensions.s.tmp`fn: -# CHECK: crc32b w0, w0, w0 -# CHECK: ldaddab w0, w0, [sp] -# CHECK: sqrdmlah v0.4h, v1.4h, v2.4h -# CHECK: sm4e v0.4s, v0.4s -# CHECK: bcax v0.16b, v0.16b, v0.16b, v0.16b -# CHECK: sha256h q0, q0, v0.4s -# CHECK: aesd v0.16b, v0.16b -# CHECK: sdot v0.2s, v1.8b, v2.8b -# CHECK: fcvt d0, s0 -# CHECK: addp v0.4s, v0.4s, v0.4s -# CHECK: fabs h1, h2 -# CHECK: fmlal v0.2s, v1.2h, v2.2h -# CHECK: psb csync -# CHECK: msr ERXPFGCTL_EL1, x0 -# CHECK: abs z31.h, p7/m, z31.h -# CHECK: sqdmlslbt z0.d, z1.s, z31.s -# CHECK: aesd z0.b, z0.b, z31.b -# CHECK: sm4e z0.s, z0.s, z0.s -# CHECK: rax1 z0.d, z0.d, z0.d -# CHECK: bdep z0.b, z1.b, z31.b -# CHECK: addqv v0.8h, p0, z0.h -# CHECK: bfadd z23.h, p3/m, z23.h, z13.h -# CHECK: ldaprb w0, [x0] -# CHECK: mrs x0, RNDR -# CHECK: irg x0, x0 -# CHECK: mrs x2, SSBS -# CHECK: sb -# CHECK: cfp rctx, x0 -# CHECK: bfdot v2.2s, v3.4h, v4.4h -# CHECK: smmla v1.4s, v16.16b, v31.16b -# CHECK: fmmla z0.s, z1.s, z2.s -# CHECK: fmmla z0.d, z1.d, z2.d -# CHECK: tcommit -# CHECK: ld64b x0, [x13] -# CHECK: brb iall -# CHECK: pacia x0, x1 -# CHECK: cfinv -# CHECK: addha za0.s, p0/m, p0/m, z0.s -# CHECK: fmopa za0.d, p0/m, p0/m, z0.d, z0.d -# CHECK: addha za0.d, p0/m, p0/m, z0.d -# CHECK: add { z0.h, z1.h }, { z0.h, z1.h }, z0.h -# CHECK: bc.eq 0xa4 -# CHECK: cpyfp [x0]!, [x1]!, x2! -# CHECK: mrs x0, PMCCNTR_EL0 +# CHECK-NEXT: aesd v0.16b, v0.16b +# CHECK-NEXT: bfadd z23.h, p3/m, z23.h, z13.h +# CHECK-NEXT: bfdot v2.2s, v3.4h, v4.4h +# CHECK-NEXT: brb iall +# CHECK-NEXT: crc32b w0, w0, w0 +# CHECK-NEXT: smin x0, x0, #0 +# CHECK-NEXT: sysp #0x0, c2, c0, #0x0, x0, x1 +# CHECK-NEXT: sdot v0.2s, v1.8b, v2.8b +# CHECK-NEXT: fmmla z0.s, z1.s, z2.s +# CHECK-NEXT: fmmla z0.d, z1.d, z2.d +# CHECK-NEXT: cfinv +# CHECK-NEXT: fcvt d0, s0 +# CHECK-NEXT: fabs h1, h2 +# CHECK-NEXT: fmlal v0.2s, v1.2h, v2.2h +# CHECK-NEXT: bc.eq 0xc8 +# CHECK-NEXT: smmla v1.4s, v16.16b, v31.16b +# CHECK-NEXT: ld64b x0, [x13] +# CHECK-NEXT: ldaddab w0, w0, [sp] +# CHECK-NEXT: ldclrp x1, x2, [x11] +# CHECK-NEXT: irg x0, x0 +# CHECK-NEXT: cpyfp [x0]!, [x1]!, x2! +# CHECK-NEXT: pacia x0, x1 +# CHECK-NEXT: mrs x0, PMCCNTR_EL0 +# CHECK-NEXT: cfp rctx, x0 +# CHECK-NEXT: psb csync +# CHECK-NEXT: msr ERXPFGCTL_EL1, x0 +# CHECK-NEXT: ldaprb w0, [x0] +# CHECK-NEXT: stilp w26, w2, [x18] +# CHECK-NEXT: sqrdmlah v0.4h, v1.4h, v2.4h +# CHECK-NEXT: mrs x0, RNDR +# CHECK-NEXT: sb +# CHECK-NEXT: sha256h q0, q0, v0.4s +# CHECK-NEXT: bcax v0.16b, v0.16b, v0.16b, v0.16b +# CHECK-NEXT: addp v0.4s, v0.4s, v0.4s +# CHECK-NEXT: sm4e v0.4s, v0.4s +# CHECK-NEXT: addha za0.s, p0/m, p0/m, z0.s +# CHECK-NEXT: fadd za.h[w11, 7, vgx2], { z12.h, z13.h } +# CHECK-NEXT: fmopa za0.d, p0/m, p0/m, z0.d, z0.d +# CHECK-NEXT: addha za0.d, p0/m, p0/m, z0.d +# CHECK-NEXT: add { z0.h, z1.h }, { z0.h, z1.h }, z0.h +# CHECK-NEXT: mrs x2, SSBS +# CHECK-NEXT: abs z31.h, p7/m, z31.h +# CHECK-NEXT: sqdmlslbt z0.d, z1.s, z31.s +# CHECK-NEXT: aesd z0.b, z0.b, z31.b +# CHECK-NEXT: bdep z0.b, z1.b, z31.b +# CHECK-NEXT: rax1 z0.d, z0.d, z0.d +# CHECK-NEXT: sm4e z0.s, z0.s, z0.s +# CHECK-NEXT: addqv v0.8h, p0, z0.h +# CHECK-NEXT: rcwswp x0, x1, [x2] +# CHECK-NEXT: tcommit diff --git a/llvm/include/llvm/ADT/StringRef.h b/llvm/include/llvm/ADT/StringRef.h index 032f42a..9fea390c 100644 --- a/llvm/include/llvm/ADT/StringRef.h +++ b/llvm/include/llvm/ADT/StringRef.h @@ -561,7 +561,8 @@ namespace llvm { /// \param N The number of characters to included in the substring. If N /// exceeds the number of characters remaining in the string, the string /// suffix (starting with \p Start) will be returned. - [[nodiscard]] StringRef substr(size_t Start, size_t N = npos) const { + [[nodiscard]] constexpr StringRef substr(size_t Start, + size_t N = npos) const { Start = std::min(Start, Length); return StringRef(Data + Start, std::min(N, Length - Start)); } diff --git a/llvm/include/llvm/Support/VersionTuple.h b/llvm/include/llvm/Support/VersionTuple.h index 1118754..828a6db 100644 --- a/llvm/include/llvm/Support/VersionTuple.h +++ b/llvm/include/llvm/Support/VersionTuple.h @@ -41,24 +41,25 @@ class VersionTuple { unsigned HasBuild : 1; public: - VersionTuple() + constexpr VersionTuple() : Major(0), Minor(0), HasMinor(false), Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {} - explicit VersionTuple(unsigned Major) + explicit constexpr VersionTuple(unsigned Major) : Major(Major), Minor(0), HasMinor(false), Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {} - explicit VersionTuple(unsigned Major, unsigned Minor) + explicit constexpr VersionTuple(unsigned Major, unsigned Minor) : Major(Major), Minor(Minor), HasMinor(true), Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {} - explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor) + explicit constexpr VersionTuple(unsigned Major, unsigned Minor, + unsigned Subminor) : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(0), HasBuild(false) {} - explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor, - unsigned Build) + explicit constexpr VersionTuple(unsigned Major, unsigned Minor, + unsigned Subminor, unsigned Build) : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(Build), HasBuild(true) {} diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.def b/llvm/include/llvm/TargetParser/AArch64TargetParser.def deleted file mode 100644 index 570172a..0000000 --- a/llvm/include/llvm/TargetParser/AArch64TargetParser.def +++ /dev/null @@ -1,434 +0,0 @@ -//===- AARCH64TargetParser.def - AARCH64 target parsing defines ---------*- 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 -// -//===----------------------------------------------------------------------===// -// -// This file provides defines to build up the AARCH64 target parser's logic. -// -//===----------------------------------------------------------------------===// - -// NOTE: NO INCLUDE GUARD DESIRED! - -#ifndef AARCH64_ARCH -#define AARCH64_ARCH(NAME, ID, ARCH_FEATURE, 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, "+", - 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, "+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, "+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, "+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, "+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, "+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, "+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, "+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, "+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("armv8.9-a", ARMV8_9A, "+v8.9a", - (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::AEK_RASv2)) -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_SVE | AArch64::AEK_SVE2)) -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_SVE | - AArch64::AEK_SVE2)) -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_SVE | - AArch64::AEK_SVE2)) -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_SVE | - AArch64::AEK_SVE2)) -AARCH64_ARCH("armv9.4-a", ARMV9_4A, "+v9.4a", - (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_SVE | - AArch64::AEK_SVE2 | AArch64::AEK_RASv2)) -// 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, "+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 | - AArch64::AEK_RCPC | AArch64::AEK_SB)) -#undef AARCH64_ARCH - -#ifndef AARCH64_ARCH_EXT_NAME -#define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE,\ - FMV_ID, DEP_FEATURES, FMV_PRIORITY) -#endif -// FIXME: This would be nicer were it tablegen -AARCH64_ARCH_EXT_NAME("invalid", AArch64::AEK_INVALID, {}, {}, MAX, "", 0) -// "none" feature has the maximum allowed function multi versioning priority -AARCH64_ARCH_EXT_NAME("none", AArch64::AEK_NONE, {}, {}, MAX, "", 1000) -AARCH64_ARCH_EXT_NAME("crc", AArch64::AEK_CRC, "+crc", "-crc", CRC, "+crc", 110) -AARCH64_ARCH_EXT_NAME("lse", AArch64::AEK_LSE, "+lse", "-lse", LSE, "+lse", 80) -AARCH64_ARCH_EXT_NAME("rdm", AArch64::AEK_RDM, "+rdm", "-rdm", RDM, - "+rdm,+fp-armv8,+neon", 70) -AARCH64_ARCH_EXT_NAME("crypto", AArch64::AEK_CRYPTO, "+crypto", "-crypto", MAX, - "", 0) -AARCH64_ARCH_EXT_NAME("sm4", AArch64::AEK_SM4, "+sm4", "-sm4", SM4, - "+sm4,+fp-armv8,+neon", 60) -AARCH64_ARCH_EXT_NAME("sha3", AArch64::AEK_SHA3, "+sha3", "-sha3", SHA3, - "+sha3,+sha2,+fp-armv8,+neon", 140) -AARCH64_ARCH_EXT_NAME("sha2", AArch64::AEK_SHA2, "+sha2", "-sha2", SHA2, - "+sha2,+fp-armv8,+neon", 130) -AARCH64_ARCH_EXT_NAME("aes", AArch64::AEK_AES, "+aes", "-aes", AES, - "+fp-armv8,+neon", 150) -AARCH64_ARCH_EXT_NAME("dotprod", AArch64::AEK_DOTPROD, "+dotprod", "-dotprod", - DOTPROD, "+dotprod,+fp-armv8,+neon", 50) -AARCH64_ARCH_EXT_NAME("fp", AArch64::AEK_FP, "+fp-armv8", "-fp-armv8", FP, - "+fp-armv8,+neon", 90) -AARCH64_ARCH_EXT_NAME("simd", AArch64::AEK_SIMD, "+neon", "-neon", SIMD, - "+fp-armv8,+neon", 100) -AARCH64_ARCH_EXT_NAME("fp16", AArch64::AEK_FP16, "+fullfp16", "-fullfp16", FP16, - "+fullfp16,+fp-armv8,+neon", 170) -AARCH64_ARCH_EXT_NAME("fp16fml", AArch64::AEK_FP16FML, "+fp16fml", "-fp16fml", - FP16FML, "+fp16fml,+fullfp16,+fp-armv8,+neon", 40) -AARCH64_ARCH_EXT_NAME("profile", AArch64::AEK_PROFILE, "+spe", "-spe", MAX, "", - 0) -AARCH64_ARCH_EXT_NAME("ras", AArch64::AEK_RAS, "+ras", "-ras", MAX, "", 0) -AARCH64_ARCH_EXT_NAME("rasv2", AArch64::AEK_RASv2, "+rasv2", "-rasv2", MAX, "", - 0) -AARCH64_ARCH_EXT_NAME("sve", AArch64::AEK_SVE, "+sve", "-sve", SVE, - "+sve,+fullfp16,+fp-armv8,+neon", 310) -AARCH64_ARCH_EXT_NAME("sve2", AArch64::AEK_SVE2, "+sve2", "-sve2", SVE2, - "+sve2,+sve,+fullfp16,+fp-armv8,+neon", 370) -AARCH64_ARCH_EXT_NAME("sve2-aes", AArch64::AEK_SVE2AES, "+sve2-aes", - "-sve2-aes", SVE_AES, - "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 380) -AARCH64_ARCH_EXT_NAME("sve2-sm4", AArch64::AEK_SVE2SM4, "+sve2-sm4", - "-sve2-sm4", SVE_SM4, - "+sve2,+sve,+sve2-sm4,+fullfp16,+fp-armv8,+neon", 420) -AARCH64_ARCH_EXT_NAME("sve2-sha3", AArch64::AEK_SVE2SHA3, "+sve2-sha3", - "-sve2-sha3", SVE_SHA3, - "+sve2,+sve,+sve2-sha3,+fullfp16,+fp-armv8,+neon", 410) -AARCH64_ARCH_EXT_NAME("sve2-bitperm", AArch64::AEK_SVE2BITPERM, "+sve2-bitperm", - "-sve2-bitperm", SVE_BITPERM, - "+sve2,+sve,+sve2-bitperm,+fullfp16,+fp-armv8,+neon", 400) -AARCH64_ARCH_EXT_NAME("sve2p1", AArch64::AEK_SVE2p1, "+sve2p1", "-sve2p1", MAX, - "", 0) -AARCH64_ARCH_EXT_NAME("b16b16", AArch64::AEK_B16B16, "+b16b16", "-b16b16", MAX, - "", 0) -AARCH64_ARCH_EXT_NAME("rcpc", AArch64::AEK_RCPC, "+rcpc", "-rcpc", RCPC, - "+rcpc", 230) -AARCH64_ARCH_EXT_NAME("rcpc2", AArch64::AEK_NONE, {}, {}, RCPC2, "+rcpc", 240) -AARCH64_ARCH_EXT_NAME("rng", AArch64::AEK_RAND, "+rand", "-rand", RNG, "+rand", - 10) -AARCH64_ARCH_EXT_NAME("memtag", AArch64::AEK_MTE, "+mte", "-mte", MEMTAG, "", - 440) -AARCH64_ARCH_EXT_NAME("memtag2", AArch64::AEK_NONE, {}, {}, MEMTAG2, "+mte", - 450) -AARCH64_ARCH_EXT_NAME("memtag3", AArch64::AEK_NONE, {}, {}, MEMTAG3, "+mte", - 460) -AARCH64_ARCH_EXT_NAME("ssbs", AArch64::AEK_SSBS, "+ssbs", "-ssbs", SSBS, "", - 490) -AARCH64_ARCH_EXT_NAME("ssbs2", AArch64::AEK_NONE, {}, {}, SSBS2, "+ssbs", 500) -AARCH64_ARCH_EXT_NAME("sb", AArch64::AEK_SB, "+sb", "-sb", SB, "+sb", 470) -AARCH64_ARCH_EXT_NAME("predres", AArch64::AEK_PREDRES, "+predres", "-predres", - PREDRES, "+predres", 480) -AARCH64_ARCH_EXT_NAME("bf16", AArch64::AEK_BF16, "+bf16", "-bf16", BF16, - "+bf16", 280) -AARCH64_ARCH_EXT_NAME("i8mm", AArch64::AEK_I8MM, "+i8mm", "-i8mm", I8MM, - "+i8mm", 270) -AARCH64_ARCH_EXT_NAME("f32mm", AArch64::AEK_F32MM, "+f32mm", "-f32mm", - SVE_F32MM, "+sve,+f32mm,+fullfp16,+fp-armv8,+neon", 350) -AARCH64_ARCH_EXT_NAME("f64mm", AArch64::AEK_F64MM, "+f64mm", "-f64mm", - SVE_F64MM, "+sve,+f64mm,+fullfp16,+fp-armv8,+neon", 360) -AARCH64_ARCH_EXT_NAME("tme", AArch64::AEK_TME, "+tme", "-tme", MAX, "", 0) -AARCH64_ARCH_EXT_NAME("ls64", AArch64::AEK_LS64, "+ls64", "-ls64", LS64, "", - 520) -AARCH64_ARCH_EXT_NAME("brbe", AArch64::AEK_BRBE, "+brbe", "-brbe", MAX, "", 0) -AARCH64_ARCH_EXT_NAME("pauth", AArch64::AEK_PAUTH, "+pauth", "-pauth", MAX, "", - 0) -AARCH64_ARCH_EXT_NAME("flagm", AArch64::AEK_FLAGM, "+flagm", "-flagm", FLAGM, - "+flagm", 20) -AARCH64_ARCH_EXT_NAME("flagm2", AArch64::AEK_NONE, {}, {}, FLAGM2, - "+flagm,+altnzcv", 30) -AARCH64_ARCH_EXT_NAME("sme", AArch64::AEK_SME, "+sme", "-sme", SME, - "+sme,+bf16", 430) -AARCH64_ARCH_EXT_NAME("sme-f64f64", AArch64::AEK_SMEF64F64, "+sme-f64f64", - "-sme-f64f64", SME_F64, "+sme,+sme-f64f64,+bf16", 560) -AARCH64_ARCH_EXT_NAME("sme-i16i64", AArch64::AEK_SMEI16I64, "+sme-i16i64", - "-sme-i16i64", SME_I64, "+sme,+sme-i16i64,+bf16", 570) -AARCH64_ARCH_EXT_NAME("sme-f16f16", AArch64::AEK_SMEF16F16, "+sme-f16f16", - "-sme-f16f16", MAX, "", 0) -AARCH64_ARCH_EXT_NAME("sme2", AArch64::AEK_SME2, "+sme2", "-sme2", SME2, - "+sme2,+sme,+bf16", 580) -AARCH64_ARCH_EXT_NAME("sme2p1", AArch64::AEK_SME2p1, "+sme2p1", "-sme2p1", MAX, - "", 0) -AARCH64_ARCH_EXT_NAME("hbc", AArch64::AEK_HBC, "+hbc", "-hbc", MAX, "", 0) -AARCH64_ARCH_EXT_NAME("mops", AArch64::AEK_MOPS, "+mops", "-mops", MAX, "", 0) -AARCH64_ARCH_EXT_NAME("pmuv3", AArch64::AEK_PERFMON, "+perfmon", "-perfmon", - MAX, "", 0) -AARCH64_ARCH_EXT_NAME("predres2", AArch64::AEK_SPECRES2, "+specres2", - "-specres2", MAX, "", 0) -AARCH64_ARCH_EXT_NAME("cssc", AArch64::AEK_CSSC, "+cssc", "-cssc", MAX, "", 0) -AARCH64_ARCH_EXT_NAME("rcpc3", AArch64::AEK_RCPC3, "+rcpc3", "-rcpc3", MAX, "", - 0) -AARCH64_ARCH_EXT_NAME("the", AArch64::AEK_THE, "+the", "-the", MAX, "", 0) -AARCH64_ARCH_EXT_NAME("d128", AArch64::AEK_D128, "+d128", "-d128", MAX, "", 0) -AARCH64_ARCH_EXT_NAME("lse128", AArch64::AEK_LSE128, "+lse128", "-lse128", MAX, - "", 0) -AARCH64_ARCH_EXT_NAME("sha1", AArch64::AEK_NONE, {}, {}, SHA1, - "+fp-armv8,+neon", 120) -AARCH64_ARCH_EXT_NAME("pmull", AArch64::AEK_NONE, {}, {}, PMULL, - "+aes,+fp-armv8,+neon", 160) -AARCH64_ARCH_EXT_NAME("dit", AArch64::AEK_NONE, {}, {}, DIT, "+dit", 180) -AARCH64_ARCH_EXT_NAME("dpb", AArch64::AEK_NONE, {}, {}, DPB, "+ccpp", 190) -AARCH64_ARCH_EXT_NAME("dpb2", AArch64::AEK_NONE, {}, {}, DPB2, "+ccpp,+ccdp", - 200) -AARCH64_ARCH_EXT_NAME("jscvt", AArch64::AEK_NONE, {}, {}, JSCVT, - "+fp-armv8,+neon,+jsconv", 210) -AARCH64_ARCH_EXT_NAME("fcma", AArch64::AEK_NONE, {}, {}, FCMA, - "+fp-armv8,+neon,+complxnum", 220) -AARCH64_ARCH_EXT_NAME("frintts", AArch64::AEK_NONE, {}, {}, FRINTTS, "+fptoint", - 250) -AARCH64_ARCH_EXT_NAME("dgh", AArch64::AEK_NONE, {}, {}, DGH, "", 260) -AARCH64_ARCH_EXT_NAME("ebf16", AArch64::AEK_NONE, {}, {}, EBF16, "+bf16", 290) -AARCH64_ARCH_EXT_NAME("rpres", AArch64::AEK_NONE, {}, {}, RPRES, "", 300) -AARCH64_ARCH_EXT_NAME("sve-bf16", AArch64::AEK_NONE, {}, {}, SVE_BF16, - "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 320) -AARCH64_ARCH_EXT_NAME("sve-ebf16", AArch64::AEK_NONE, {}, {}, SVE_EBF16, - "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 330) -AARCH64_ARCH_EXT_NAME("sve-i8mm", AArch64::AEK_NONE, {}, {}, SVE_I8MM, - "+sve,+i8mm,+fullfp16,+fp-armv8,+neon", 340) -AARCH64_ARCH_EXT_NAME("sve2-pmull128", AArch64::AEK_NONE, {}, {}, SVE_PMULL128, - "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 390) -AARCH64_ARCH_EXT_NAME("bti", AArch64::AEK_NONE, {}, {}, BTI, "+bti", 510) -AARCH64_ARCH_EXT_NAME("ls64_v", AArch64::AEK_NONE, {}, {}, LS64_V, "", 530) -AARCH64_ARCH_EXT_NAME("ls64_accdata", AArch64::AEK_NONE, {}, {}, LS64_ACCDATA, - "+ls64", 540) -AARCH64_ARCH_EXT_NAME("wfxt", AArch64::AEK_NONE, {}, {}, WFXT, "+wfxt", 550) -#undef AARCH64_ARCH_EXT_NAME - -#ifndef AARCH64_CPU_NAME -#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_EXT) -#endif -AARCH64_CPU_NAME("cortex-a34", ARMV8A, - (AArch64::AEK_CRC)) -AARCH64_CPU_NAME("cortex-a35", ARMV8A, - (AArch64::AEK_CRC)) -AARCH64_CPU_NAME("cortex-a53", ARMV8A, - (AArch64::AEK_CRC)) -AARCH64_CPU_NAME("cortex-a55", ARMV8_2A, - (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC)) -AARCH64_CPU_NAME("cortex-a510", ARMV9A, - (AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SB | - AArch64::AEK_PAUTH | AArch64::AEK_MTE | AArch64::AEK_SSBS | - AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM | - AArch64::AEK_FP16FML)) -AARCH64_CPU_NAME("cortex-a57", ARMV8A, - (AArch64::AEK_CRC)) -AARCH64_CPU_NAME("cortex-a65", ARMV8_2A, - (AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | - AArch64::AEK_RCPC | AArch64::AEK_SSBS)) -AARCH64_CPU_NAME("cortex-a65ae", ARMV8_2A, - (AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | - AArch64::AEK_RCPC | AArch64::AEK_SSBS)) -AARCH64_CPU_NAME("cortex-a72", ARMV8A, - (AArch64::AEK_CRC)) -AARCH64_CPU_NAME("cortex-a73", ARMV8A, - (AArch64::AEK_CRC)) -AARCH64_CPU_NAME("cortex-a75", ARMV8_2A, - (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC)) -AARCH64_CPU_NAME("cortex-a76", ARMV8_2A, - (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | - AArch64::AEK_SSBS)) -AARCH64_CPU_NAME("cortex-a76ae", ARMV8_2A, - (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | - AArch64::AEK_SSBS)) -AARCH64_CPU_NAME("cortex-a77", ARMV8_2A, - (AArch64::AEK_FP16 | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | - AArch64::AEK_SSBS)) -AARCH64_CPU_NAME("cortex-a78", ARMV8_2A, - (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | - AArch64::AEK_SSBS | AArch64::AEK_PROFILE)) -AARCH64_CPU_NAME("cortex-a78c", ARMV8_2A, - (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | - AArch64::AEK_SSBS | AArch64::AEK_PROFILE | AArch64::AEK_FLAGM | - AArch64::AEK_PAUTH | AArch64::AEK_FP16FML)) -AARCH64_CPU_NAME("cortex-a710", ARMV9A, - (AArch64::AEK_MTE | AArch64::AEK_PAUTH | AArch64::AEK_FLAGM | - AArch64::AEK_SB | AArch64::AEK_I8MM | AArch64::AEK_FP16FML | - AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM | - AArch64::AEK_BF16)) -AARCH64_CPU_NAME("cortex-a715", ARMV9A, - (AArch64::AEK_SB | AArch64::AEK_SSBS | AArch64::AEK_MTE | - AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_PAUTH | - AArch64::AEK_I8MM | AArch64::AEK_PREDRES | AArch64::AEK_PERFMON | - AArch64::AEK_PROFILE | AArch64::AEK_SVE | AArch64::AEK_SVE2BITPERM | - AArch64::AEK_BF16 | AArch64::AEK_FLAGM)) -AARCH64_CPU_NAME("cortex-r82", ARMV8R, - (AArch64::AEK_LSE)) -AARCH64_CPU_NAME("cortex-x1", ARMV8_2A, - (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | - AArch64::AEK_SSBS | AArch64::AEK_PROFILE)) -AARCH64_CPU_NAME("cortex-x1c", ARMV8_2A, - (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | - AArch64::AEK_SSBS | AArch64::AEK_PAUTH | AArch64::AEK_PROFILE)) -AARCH64_CPU_NAME("cortex-x2", ARMV9A, - (AArch64::AEK_MTE | AArch64::AEK_BF16 | AArch64::AEK_I8MM | - AArch64::AEK_PAUTH | AArch64::AEK_SSBS | AArch64::AEK_SB | - AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM | - AArch64::AEK_FP16FML)) -AARCH64_CPU_NAME("cortex-x3", ARMV9A, - (AArch64::AEK_SVE | AArch64::AEK_PERFMON | AArch64::AEK_PROFILE | - AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_MTE | - AArch64::AEK_SVE2BITPERM | AArch64::AEK_SB | AArch64::AEK_PAUTH | - AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_PREDRES | - AArch64::AEK_FLAGM | AArch64::AEK_SSBS)) -AARCH64_CPU_NAME("neoverse-e1", ARMV8_2A, - (AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | - AArch64::AEK_RCPC | AArch64::AEK_SSBS)) -AARCH64_CPU_NAME("neoverse-n1", ARMV8_2A, - (AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | - AArch64::AEK_PROFILE | AArch64::AEK_RCPC | - AArch64::AEK_SSBS)) -AARCH64_CPU_NAME("neoverse-n2", ARMV8_5A, - (AArch64::AEK_BF16 | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | - AArch64::AEK_I8MM | AArch64::AEK_MTE | - AArch64::AEK_SB | AArch64::AEK_SSBS | - AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM)) -AARCH64_CPU_NAME("neoverse-512tvb", ARMV8_4A, - (AArch64::AEK_SVE | AArch64::AEK_SSBS | - AArch64::AEK_FP16 | AArch64::AEK_BF16 | - AArch64::AEK_DOTPROD | AArch64::AEK_PROFILE | - AArch64::AEK_RAND | AArch64::AEK_FP16FML | AArch64::AEK_I8MM)) -AARCH64_CPU_NAME("neoverse-v1", ARMV8_4A, - (AArch64::AEK_SVE | AArch64::AEK_SSBS | - AArch64::AEK_FP16 | AArch64::AEK_BF16 | - AArch64::AEK_DOTPROD | AArch64::AEK_PROFILE | - AArch64::AEK_RAND | AArch64::AEK_FP16FML | AArch64::AEK_I8MM)) -AARCH64_CPU_NAME("neoverse-v2", ARMV9A, - (AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SSBS | - AArch64::AEK_FP16 | AArch64::AEK_BF16 | AArch64::AEK_RAND | - AArch64::AEK_DOTPROD | AArch64::AEK_PROFILE | - AArch64::AEK_SVE2BITPERM | AArch64::AEK_FP16FML | - AArch64::AEK_I8MM | AArch64::AEK_MTE)) -AARCH64_CPU_NAME("cyclone", ARMV8A, - (AArch64::AEK_NONE)) -AARCH64_CPU_NAME("apple-a7", ARMV8A, - (AArch64::AEK_NONE)) -AARCH64_CPU_NAME("apple-a8", ARMV8A, - (AArch64::AEK_NONE)) -AARCH64_CPU_NAME("apple-a9", ARMV8A, - (AArch64::AEK_NONE)) -AARCH64_CPU_NAME("apple-a10", ARMV8A, - (AArch64::AEK_CRC | AArch64::AEK_RDM)) -AARCH64_CPU_NAME("apple-a11", ARMV8_2A, - (AArch64::AEK_FP16)) -AARCH64_CPU_NAME("apple-a12", ARMV8_3A, - (AArch64::AEK_FP16)) -AARCH64_CPU_NAME("apple-a13", ARMV8_4A, - (AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3)) -AARCH64_CPU_NAME("apple-a14", ARMV8_5A, - (AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3)) -AARCH64_CPU_NAME("apple-a15", ARMV8_5A, - (AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3 | - AArch64::AEK_BF16 | AArch64::AEK_I8MM)) -AARCH64_CPU_NAME("apple-a16", ARMV8_5A, - (AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3 | - AArch64::AEK_BF16 | AArch64::AEK_I8MM)) -AARCH64_CPU_NAME("apple-m1", ARMV8_5A, - (AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3)) -AARCH64_CPU_NAME("apple-m2", ARMV8_5A, - (AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3 | - AArch64::AEK_BF16 | AArch64::AEK_I8MM)) -AARCH64_CPU_NAME("apple-s4", ARMV8_3A, - (AArch64::AEK_FP16)) -AARCH64_CPU_NAME("apple-s5", ARMV8_3A, - (AArch64::AEK_FP16)) -AARCH64_CPU_NAME("exynos-m3", ARMV8A, - (AArch64::AEK_CRC)) -AARCH64_CPU_NAME("exynos-m4", ARMV8_2A, - (AArch64::AEK_DOTPROD | AArch64::AEK_FP16)) -AARCH64_CPU_NAME("exynos-m5", ARMV8_2A, - (AArch64::AEK_DOTPROD | AArch64::AEK_FP16)) -AARCH64_CPU_NAME("falkor", ARMV8A, - (AArch64::AEK_CRC | AArch64::AEK_RDM)) -AARCH64_CPU_NAME("saphira", ARMV8_3A, - (AArch64::AEK_PROFILE)) -AARCH64_CPU_NAME("kryo", ARMV8A, - (AArch64::AEK_CRC)) -AARCH64_CPU_NAME("thunderx2t99", ARMV8_1A, - (AArch64::AEK_NONE)) -AARCH64_CPU_NAME("thunderx3t110", ARMV8_3A, - (AArch64::AEK_NONE)) -AARCH64_CPU_NAME("thunderx", ARMV8A, - (AArch64::AEK_CRC)) -AARCH64_CPU_NAME("thunderxt88", ARMV8A, - (AArch64::AEK_CRC)) -AARCH64_CPU_NAME("thunderxt81", ARMV8A, - (AArch64::AEK_CRC)) -AARCH64_CPU_NAME("thunderxt83", ARMV8A, - (AArch64::AEK_CRC)) -AARCH64_CPU_NAME("tsv110", ARMV8_2A, - (AArch64::AEK_DOTPROD | - AArch64::AEK_FP16 | AArch64::AEK_FP16FML | - AArch64::AEK_PROFILE)) -AARCH64_CPU_NAME("a64fx", ARMV8_2A, - (AArch64::AEK_FP16 | AArch64::AEK_SVE)) -AARCH64_CPU_NAME("carmel", ARMV8_2A, - AArch64::AEK_FP16) -AARCH64_CPU_NAME("ampere1", ARMV8_6A, - (AArch64::AEK_FP16 | AArch64::AEK_SB | AArch64::AEK_SSBS)) -// Invalid CPU -AARCH64_CPU_NAME("invalid", INVALID, AArch64::AEK_INVALID) -#undef AARCH64_CPU_NAME - -#ifndef AARCH64_CPU_ALIAS -#define AARCH64_CPU_ALIAS(ALIAS,NAME) -#endif -AARCH64_CPU_ALIAS("grace", "neoverse-v2") -#undef AARCH64_CPU_ALIAS diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h index 309e355..0ffec6b 100644 --- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h +++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h @@ -16,9 +16,10 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/VersionTuple.h" +#include #include -// FIXME:This should be made into class design,to avoid dupplication. namespace llvm { class Triple; @@ -149,103 +150,356 @@ enum ArchExtKind : uint64_t { }; // clang-format on -enum class ArchKind { -#define AARCH64_ARCH(NAME, ID, ARCH_FEATURE, ARCH_BASE_EXT) ID, -#include "AArch64TargetParser.def" +// Represents an extension that can be enabled with -march=+. +// Typically these correspond to Arm Architecture extensions, unlike +// SubtargetFeature which may represent either an actual extension or some +// internal LLVM property. +struct ExtensionInfo { + StringRef Name; // Human readable name, e.g. "profile". + ArchExtKind ID; // Corresponding to the ArchExtKind, this extensions + // representation in the bitfield. + StringRef Feature; // -mattr enable string, e.g. "+spe" + StringRef NegFeature; // -mattr disable string, e.g. "-spe" + + // FIXME These were added by D127812 FMV support and need documenting: + CPUFeatures CPUFeature; // Bitfield value set in __aarch64_cpu_features + StringRef DependentFeatures; + unsigned FmvPriority; + static constexpr unsigned MaxFMVPriority = 1000; }; -struct ArchNames { - StringRef Name; - StringRef ArchFeature; - uint64_t ArchBaseExtensions; - ArchKind ID; +// clang-format off +inline constexpr ExtensionInfo Extensions[] = { + {"aes", AArch64::AEK_AES, "+aes", "-aes", FEAT_AES, "+fp-armv8,+neon", 150}, + {"b16b16", AArch64::AEK_B16B16, "+b16b16", "-b16b16", FEAT_MAX, "", 0}, + {"bf16", AArch64::AEK_BF16, "+bf16", "-bf16", FEAT_BF16, "+bf16", 280}, + {"brbe", AArch64::AEK_BRBE, "+brbe", "-brbe", FEAT_MAX, "", 0}, + {"bti", AArch64::AEK_NONE, {}, {}, FEAT_BTI, "+bti", 510}, + {"crc", AArch64::AEK_CRC, "+crc", "-crc", FEAT_CRC, "+crc", 110}, + {"crypto", AArch64::AEK_CRYPTO, "+crypto", "-crypto", FEAT_MAX, "", 0}, + {"cssc", AArch64::AEK_CSSC, "+cssc", "-cssc", FEAT_MAX, "", 0}, + {"d128", AArch64::AEK_D128, "+d128", "-d128", FEAT_MAX, "", 0}, + {"dgh", AArch64::AEK_NONE, {}, {}, FEAT_DGH, "", 260}, + {"dit", AArch64::AEK_NONE, {}, {}, FEAT_DIT, "+dit", 180}, + {"dotprod", AArch64::AEK_DOTPROD, "+dotprod", "-dotprod", FEAT_DOTPROD, "+dotprod,+fp-armv8,+neon", 50}, + {"dpb", AArch64::AEK_NONE, {}, {}, FEAT_DPB, "+ccpp", 190}, + {"dpb2", AArch64::AEK_NONE, {}, {}, FEAT_DPB2, "+ccpp,+ccdp", 200}, + {"ebf16", AArch64::AEK_NONE, {}, {}, FEAT_EBF16, "+bf16", 290}, + {"f32mm", AArch64::AEK_F32MM, "+f32mm", "-f32mm", FEAT_SVE_F32MM, "+sve,+f32mm,+fullfp16,+fp-armv8,+neon", 350}, + {"f64mm", AArch64::AEK_F64MM, "+f64mm", "-f64mm", FEAT_SVE_F64MM, "+sve,+f64mm,+fullfp16,+fp-armv8,+neon", 360}, + {"fcma", AArch64::AEK_NONE, {}, {}, FEAT_FCMA, "+fp-armv8,+neon,+complxnum", 220}, + {"flagm", AArch64::AEK_FLAGM, "+flagm", "-flagm", FEAT_FLAGM, "+flagm", 20}, + {"flagm2", AArch64::AEK_NONE, {}, {}, FEAT_FLAGM2, "+flagm,+altnzcv", 30}, + {"fp", AArch64::AEK_FP, "+fp-armv8", "-fp-armv8", FEAT_FP, "+fp-armv8,+neon", 90}, + {"fp16", AArch64::AEK_FP16, "+fullfp16", "-fullfp16", FEAT_FP16, "+fullfp16,+fp-armv8,+neon", 170}, + {"fp16fml", AArch64::AEK_FP16FML, "+fp16fml", "-fp16fml", FEAT_FP16FML, "+fp16fml,+fullfp16,+fp-armv8,+neon", 40}, + {"frintts", AArch64::AEK_NONE, {}, {}, FEAT_FRINTTS, "+fptoint", 250}, + {"hbc", AArch64::AEK_HBC, "+hbc", "-hbc", FEAT_MAX, "", 0}, + {"i8mm", AArch64::AEK_I8MM, "+i8mm", "-i8mm", FEAT_I8MM, "+i8mm", 270}, + {"jscvt", AArch64::AEK_NONE, {}, {}, FEAT_JSCVT, "+fp-armv8,+neon,+jsconv", 210}, + {"ls64_accdata", AArch64::AEK_NONE, {}, {}, FEAT_LS64_ACCDATA, "+ls64", 540}, + {"ls64_v", AArch64::AEK_NONE, {}, {}, FEAT_LS64_V, "", 530}, + {"ls64", AArch64::AEK_LS64, "+ls64", "-ls64", FEAT_LS64, "", 520}, + {"lse", AArch64::AEK_LSE, "+lse", "-lse", FEAT_LSE, "+lse", 80}, + {"lse128", AArch64::AEK_LSE128, "+lse128", "-lse128", FEAT_MAX, "", 0}, + {"memtag", AArch64::AEK_MTE, "+mte", "-mte", FEAT_MEMTAG, "", 440}, + {"memtag2", AArch64::AEK_NONE, {}, {}, FEAT_MEMTAG2, "+mte", 450}, + {"memtag3", AArch64::AEK_NONE, {}, {}, FEAT_MEMTAG3, "+mte", 460}, + {"mops", AArch64::AEK_MOPS, "+mops", "-mops", FEAT_MAX, "", 0}, + {"pauth", AArch64::AEK_PAUTH, "+pauth", "-pauth", FEAT_MAX, "", 0}, + {"pmull", AArch64::AEK_NONE, {}, {}, FEAT_PMULL, "+aes,+fp-armv8,+neon", 160}, + {"pmuv3", AArch64::AEK_PERFMON, "+perfmon", "-perfmon", FEAT_MAX, "", 0}, + {"predres", AArch64::AEK_PREDRES, "+predres", "-predres", FEAT_PREDRES, "+predres", 480}, + {"predres2", AArch64::AEK_SPECRES2, "+specres2", "-specres2", FEAT_MAX, "", 0}, + {"profile", AArch64::AEK_PROFILE, "+spe", "-spe", FEAT_MAX, "", 0}, + {"ras", AArch64::AEK_RAS, "+ras", "-ras", FEAT_MAX, "", 0}, + {"rasv2", AArch64::AEK_RASv2, "+rasv2", "-rasv2", FEAT_MAX, "", 0}, + {"rcpc", AArch64::AEK_RCPC, "+rcpc", "-rcpc", FEAT_RCPC, "+rcpc", 230}, + {"rcpc2", AArch64::AEK_NONE, {}, {}, FEAT_RCPC2, "+rcpc", 240}, + {"rcpc3", AArch64::AEK_RCPC3, "+rcpc3", "-rcpc3", FEAT_MAX, "", 0}, + {"rdm", AArch64::AEK_RDM, "+rdm", "-rdm", FEAT_RDM, "+rdm,+fp-armv8,+neon", 70}, + {"rng", AArch64::AEK_RAND, "+rand", "-rand", FEAT_RNG, "+rand", 10}, + {"rpres", AArch64::AEK_NONE, {}, {}, FEAT_RPRES, "", 300}, + {"sb", AArch64::AEK_SB, "+sb", "-sb", FEAT_SB, "+sb", 470}, + {"sha1", AArch64::AEK_NONE, {}, {}, FEAT_SHA1, "+fp-armv8,+neon", 120}, + {"sha2", AArch64::AEK_SHA2, "+sha2", "-sha2", FEAT_SHA2, "+sha2,+fp-armv8,+neon", 130}, + {"sha3", AArch64::AEK_SHA3, "+sha3", "-sha3", FEAT_SHA3, "+sha3,+sha2,+fp-armv8,+neon", 140}, + {"simd", AArch64::AEK_SIMD, "+neon", "-neon", FEAT_SIMD, "+fp-armv8,+neon", 100}, + {"sm4", AArch64::AEK_SM4, "+sm4", "-sm4", FEAT_SM4, "+sm4,+fp-armv8,+neon", 60}, + {"sme-f16f16", AArch64::AEK_SMEF16F16, "+sme-f16f16", "-sme-f16f16", FEAT_MAX, "", 0}, + {"sme-f64f64", AArch64::AEK_SMEF64F64, "+sme-f64f64", "-sme-f64f64", FEAT_SME_F64, "+sme,+sme-f64f64,+bf16", 560}, + {"sme-i16i64", AArch64::AEK_SMEI16I64, "+sme-i16i64", "-sme-i16i64", FEAT_SME_I64, "+sme,+sme-i16i64,+bf16", 570}, + {"sme", AArch64::AEK_SME, "+sme", "-sme", FEAT_SME, "+sme,+bf16", 430}, + {"sme2", AArch64::AEK_SME2, "+sme2", "-sme2", FEAT_SME2, "+sme2,+sme,+bf16", 580}, + {"sme2p1", AArch64::AEK_SME2p1, "+sme2p1", "-sme2p1", FEAT_MAX, "", 0}, + {"ssbs", AArch64::AEK_SSBS, "+ssbs", "-ssbs", FEAT_SSBS, "", 490}, + {"ssbs2", AArch64::AEK_NONE, {}, {}, FEAT_SSBS2, "+ssbs", 500}, + {"sve-bf16", AArch64::AEK_NONE, {}, {}, FEAT_SVE_BF16, "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 320}, + {"sve-ebf16", AArch64::AEK_NONE, {}, {}, FEAT_SVE_EBF16, "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 330}, + {"sve-i8mm", AArch64::AEK_NONE, {}, {}, FEAT_SVE_I8MM, "+sve,+i8mm,+fullfp16,+fp-armv8,+neon", 340}, + {"sve", AArch64::AEK_SVE, "+sve", "-sve", FEAT_SVE, "+sve,+fullfp16,+fp-armv8,+neon", 310}, + {"sve2-aes", AArch64::AEK_SVE2AES, "+sve2-aes", "-sve2-aes", FEAT_SVE_AES, "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 380}, + {"sve2-bitperm", AArch64::AEK_SVE2BITPERM, "+sve2-bitperm", "-sve2-bitperm", FEAT_SVE_BITPERM, "+sve2,+sve,+sve2-bitperm,+fullfp16,+fp-armv8,+neon", 400}, + {"sve2-pmull128", AArch64::AEK_NONE, {}, {}, FEAT_SVE_PMULL128, "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 390}, + {"sve2-sha3", AArch64::AEK_SVE2SHA3, "+sve2-sha3", "-sve2-sha3", FEAT_SVE_SHA3, "+sve2,+sve,+sve2-sha3,+fullfp16,+fp-armv8,+neon", 410}, + {"sve2-sm4", AArch64::AEK_SVE2SM4, "+sve2-sm4", "-sve2-sm4", FEAT_SVE_SM4, "+sve2,+sve,+sve2-sm4,+fullfp16,+fp-armv8,+neon", 420}, + {"sve2", AArch64::AEK_SVE2, "+sve2", "-sve2", FEAT_SVE2, "+sve2,+sve,+fullfp16,+fp-armv8,+neon", 370}, + {"sve2p1", AArch64::AEK_SVE2p1, "+sve2p1", "-sve2p1", FEAT_MAX, "", 0}, + {"the", AArch64::AEK_THE, "+the", "-the", FEAT_MAX, "", 0}, + {"tme", AArch64::AEK_TME, "+tme", "-tme", FEAT_MAX, "", 0}, + {"wfxt", AArch64::AEK_NONE, {}, {}, FEAT_WFXT, "+wfxt", 550}, + // Special cases + {"none", AArch64::AEK_NONE, {}, {}, FEAT_MAX, "", ExtensionInfo::MaxFMVPriority}, + {"invalid", AArch64::AEK_INVALID, {}, {}, FEAT_MAX, "", 0}, +}; +// clang-format on + +enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' }; + +// Information about a specific architecture, e.g. V8.1-A +struct ArchInfo { + VersionTuple Version; // Architecture version, major + minor. + ArchProfile Profile; // Architecuture profile + StringRef Name; // Human readable name, e.g. "armv8.1-a" + StringRef ArchFeature; // Command line feature flag, e.g. +v8a + uint64_t DefaultExts; // bitfield of default extensions ArchExtKind + + bool operator==(const ArchInfo &Other) const { + return this->Name == Other.Name; + } + bool operator!=(const ArchInfo &Other) const { + return this->Name != Other.Name; + } + + // Defines the following partial order, indicating when an architecture is + // a superset of another: + // + // v9.4a > v9.3a > v9.3a > v9.3a > v9a; + // v v v v v + // v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > v8.4a > ... > v8a; + // + // v8r and INVALID have no relation to anything. This is used to + // determine which features to enable for a given architecture. See + // AArch64TargetInfo::setFeatureEnabled. + bool implies(const ArchInfo &Other) const { + if (this->Profile != Other.Profile) + return false; // ARMV8R and INVALID + if (this->Version.getMajor() == Other.Version.getMajor()) { + return this->Version > Other.Version; + } + if (this->Version.getMajor() == 9 && Other.Version.getMajor() == 8) { + return this->Version.getMinor().value() + 5 >= + Other.Version.getMinor().value(); + } + return false; + } // Return ArchFeature without the leading "+". StringRef getSubArch() const { return ArchFeature.substr(1); } -}; -const ArchNames AArch64ARCHNames[] = { -#define AARCH64_ARCH(NAME, ID, ARCH_FEATURE, ARCH_BASE_EXT) \ - {NAME, ARCH_FEATURE, ARCH_BASE_EXT, AArch64::ArchKind::ID}, -#include "AArch64TargetParser.def" + // Search for ArchInfo by SubArch name + static const ArchInfo &findBySubArch(StringRef SubArch); }; -// List of Arch Extension names. -struct ExtName { - StringRef Name; - uint64_t ID; - StringRef Feature; - StringRef NegFeature; -}; +// clang-format off +inline constexpr ArchInfo INVALID = { VersionTuple{0, 0}, AProfile, "invalid", "+", (AArch64::AEK_NONE)}; +inline constexpr ArchInfo ARMV8A = { VersionTuple{8, 0}, AProfile, "armv8-a", "+v8a", (AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD), }; +inline constexpr ArchInfo ARMV8_1A = { VersionTuple{8, 1}, AProfile, "armv8.1-a", "+v8.1a", (ARMV8A.DefaultExts | AArch64::AEK_CRC | AArch64::AEK_LSE | AArch64::AEK_RDM)}; +inline constexpr ArchInfo ARMV8_2A = { VersionTuple{8, 2}, AProfile, "armv8.2-a", "+v8.2a", (ARMV8_1A.DefaultExts | AArch64::AEK_RAS)}; +inline constexpr ArchInfo ARMV8_3A = { VersionTuple{8, 3}, AProfile, "armv8.3-a", "+v8.3a", (ARMV8_2A.DefaultExts | AArch64::AEK_RCPC)}; +inline constexpr ArchInfo ARMV8_4A = { VersionTuple{8, 4}, AProfile, "armv8.4-a", "+v8.4a", (ARMV8_3A.DefaultExts | AArch64::AEK_DOTPROD)}; +inline constexpr ArchInfo ARMV8_5A = { VersionTuple{8, 5}, AProfile, "armv8.5-a", "+v8.5a", (ARMV8_4A.DefaultExts)}; +constexpr unsigned BaseNoCrypto = ARMV8_5A.DefaultExts ^ AArch64::AEK_CRYPTO; // 8.6 onwards has no AEK_CRYPTO +inline constexpr ArchInfo ARMV8_6A = { VersionTuple{8, 6}, AProfile, "armv8.6-a", "+v8.6a", (BaseNoCrypto | AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 | AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM)}; +inline constexpr ArchInfo ARMV8_7A = { VersionTuple{8, 7}, AProfile, "armv8.7-a", "+v8.7a", (ARMV8_6A.DefaultExts)}; +inline constexpr ArchInfo ARMV8_8A = { VersionTuple{8, 8}, AProfile, "armv8.8-a", "+v8.8a", (ARMV8_7A.DefaultExts)}; +inline constexpr ArchInfo ARMV8_9A = { VersionTuple{8, 9}, AProfile, "armv8.9-a", "+v8.9a", (ARMV8_8A.DefaultExts)}; +inline constexpr ArchInfo ARMV9A = { VersionTuple{9, 0}, AProfile, "armv9-a", "+v9a", (BaseNoCrypto | AArch64::AEK_SVE | AArch64::AEK_SVE2)}; +inline constexpr ArchInfo ARMV9_1A = { VersionTuple{9, 1}, AProfile, "armv9.1-a", "+v9.1a", (ARMV9A.DefaultExts | AArch64::AEK_BF16 | AArch64::AEK_I8MM)}; +inline constexpr ArchInfo ARMV9_2A = { VersionTuple{9, 2}, AProfile, "armv9.2-a", "+v9.2a", (ARMV9_1A.DefaultExts)}; +inline constexpr ArchInfo ARMV9_3A = { VersionTuple{9, 3}, AProfile, "armv9.3-a", "+v9.3a", (ARMV9_2A.DefaultExts)}; +inline constexpr ArchInfo ARMV9_4A = { VersionTuple{9, 4}, AProfile, "armv9.4-a", "+v9.4a", (ARMV9_3A.DefaultExts)}; +// For v8-R, we do not enable crypto and align with GCC that enables a more minimal set of optional architecture extensions. +inline constexpr ArchInfo ARMV8R = { VersionTuple{8, 0}, RProfile, "armv8-r", "+v8r", ((BaseNoCrypto ^ AArch64::AEK_LSE) | AArch64::AEK_SSBS | AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SB), }; +// clang-format on -const ExtName AArch64ARCHExtNames[] = { -#define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE, FMV_ID, \ - DEP_FEATURES, FMV_PRIORITY) \ - {NAME, ID, FEATURE, NEGFEATURE}, -#include "AArch64TargetParser.def" +// The set of all architectures +static constexpr std::array ArchInfos = { + &INVALID, &ARMV8A, &ARMV8_1A, &ARMV8_2A, &ARMV8_3A, &ARMV8_4A, + &ARMV8_5A, &ARMV8_6A, &ARMV8_7A, &ARMV8_8A, &ARMV8_9A, &ARMV9A, + &ARMV9_1A, &ARMV9_2A, &ARMV9_3A, &ARMV9_4A, &ARMV8R, }; -// 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. -struct CpuNames { - StringRef Name; - ArchKind ArchID; - uint64_t DefaultExtensions; +// Details of a specific CPU. +struct CpuInfo { + StringRef Name; // Name, as written for -mcpu. + const ArchInfo &Arch; + uint64_t DefaultExtensions; // Default extensions for this CPU. These will be + // ORd with the architecture defaults. }; -const CpuNames AArch64CPUNames[] = { -#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_EXT) \ - {NAME, AArch64::ArchKind::ID, DEFAULT_EXT}, -#include "AArch64TargetParser.def" +inline constexpr CpuInfo CpuInfos[] = { + {"cortex-a34", ARMV8A, (AArch64::AEK_CRC)}, + {"cortex-a35", ARMV8A, (AArch64::AEK_CRC)}, + {"cortex-a53", ARMV8A, (AArch64::AEK_CRC)}, + {"cortex-a55", ARMV8_2A, + (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC)}, + {"cortex-a510", ARMV9A, + (AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SB | + AArch64::AEK_PAUTH | AArch64::AEK_MTE | AArch64::AEK_SSBS | + AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM | + AArch64::AEK_FP16FML)}, + {"cortex-a57", ARMV8A, (AArch64::AEK_CRC)}, + {"cortex-a65", ARMV8_2A, + (AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | AArch64::AEK_RCPC | + AArch64::AEK_SSBS)}, + {"cortex-a65ae", ARMV8_2A, + (AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | AArch64::AEK_RCPC | + AArch64::AEK_SSBS)}, + {"cortex-a72", ARMV8A, (AArch64::AEK_CRC)}, + {"cortex-a73", ARMV8A, (AArch64::AEK_CRC)}, + {"cortex-a75", ARMV8_2A, + (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC)}, + {"cortex-a76", ARMV8_2A, + (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | + AArch64::AEK_SSBS)}, + {"cortex-a76ae", ARMV8_2A, + (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | + AArch64::AEK_SSBS)}, + {"cortex-a77", ARMV8_2A, + (AArch64::AEK_FP16 | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | + AArch64::AEK_SSBS)}, + {"cortex-a78", ARMV8_2A, + (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | + AArch64::AEK_SSBS | AArch64::AEK_PROFILE)}, + {"cortex-a78c", ARMV8_2A, + (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | + AArch64::AEK_SSBS | AArch64::AEK_PROFILE | AArch64::AEK_FLAGM | + AArch64::AEK_PAUTH | AArch64::AEK_FP16FML)}, + {"cortex-a710", ARMV9A, + (AArch64::AEK_MTE | AArch64::AEK_PAUTH | AArch64::AEK_FLAGM | + AArch64::AEK_SB | AArch64::AEK_I8MM | AArch64::AEK_FP16FML | + AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM | + AArch64::AEK_BF16)}, + {"cortex-a715", ARMV9A, + (AArch64::AEK_SB | AArch64::AEK_SSBS | AArch64::AEK_MTE | + AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_PAUTH | + AArch64::AEK_I8MM | AArch64::AEK_PREDRES | AArch64::AEK_PERFMON | + AArch64::AEK_PROFILE | AArch64::AEK_SVE | AArch64::AEK_SVE2BITPERM | + AArch64::AEK_BF16 | AArch64::AEK_FLAGM)}, + {"cortex-r82", ARMV8R, (AArch64::AEK_LSE)}, + {"cortex-x1", ARMV8_2A, + (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | + AArch64::AEK_SSBS | AArch64::AEK_PROFILE)}, + {"cortex-x1c", ARMV8_2A, + (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | + AArch64::AEK_SSBS | AArch64::AEK_PAUTH | AArch64::AEK_PROFILE)}, + {"cortex-x2", ARMV9A, + (AArch64::AEK_MTE | AArch64::AEK_BF16 | AArch64::AEK_I8MM | + AArch64::AEK_PAUTH | AArch64::AEK_SSBS | AArch64::AEK_SB | + AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM | + AArch64::AEK_FP16FML)}, + {"cortex-x3", ARMV9A, + (AArch64::AEK_SVE | AArch64::AEK_PERFMON | AArch64::AEK_PROFILE | + AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_MTE | + AArch64::AEK_SVE2BITPERM | AArch64::AEK_SB | AArch64::AEK_PAUTH | + AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_PREDRES | + AArch64::AEK_FLAGM | AArch64::AEK_SSBS)}, + {"neoverse-e1", ARMV8_2A, + (AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | AArch64::AEK_RCPC | + AArch64::AEK_SSBS)}, + {"neoverse-n1", ARMV8_2A, + (AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | AArch64::AEK_PROFILE | + AArch64::AEK_RCPC | AArch64::AEK_SSBS)}, + {"neoverse-n2", ARMV8_5A, + (AArch64::AEK_BF16 | AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | + AArch64::AEK_I8MM | AArch64::AEK_MTE | AArch64::AEK_SB | + AArch64::AEK_SSBS | AArch64::AEK_SVE | AArch64::AEK_SVE2 | + AArch64::AEK_SVE2BITPERM)}, + {"neoverse-512tvb", ARMV8_4A, + (AArch64::AEK_SVE | AArch64::AEK_SSBS | AArch64::AEK_FP16 | + AArch64::AEK_BF16 | AArch64::AEK_DOTPROD | AArch64::AEK_PROFILE | + AArch64::AEK_RAND | AArch64::AEK_FP16FML | AArch64::AEK_I8MM)}, + {"neoverse-v1", ARMV8_4A, + (AArch64::AEK_SVE | AArch64::AEK_SSBS | AArch64::AEK_FP16 | + AArch64::AEK_BF16 | AArch64::AEK_DOTPROD | AArch64::AEK_PROFILE | + AArch64::AEK_RAND | AArch64::AEK_FP16FML | AArch64::AEK_I8MM)}, + {"neoverse-v2", ARMV9A, + (AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SSBS | + AArch64::AEK_FP16 | AArch64::AEK_BF16 | AArch64::AEK_RAND | + AArch64::AEK_DOTPROD | AArch64::AEK_PROFILE | AArch64::AEK_SVE2BITPERM | + AArch64::AEK_FP16FML | AArch64::AEK_I8MM | AArch64::AEK_MTE)}, + {"cyclone", ARMV8A, (AArch64::AEK_NONE)}, + {"apple-a7", ARMV8A, (AArch64::AEK_NONE)}, + {"apple-a8", ARMV8A, (AArch64::AEK_NONE)}, + {"apple-a9", ARMV8A, (AArch64::AEK_NONE)}, + {"apple-a10", ARMV8A, (AArch64::AEK_CRC | AArch64::AEK_RDM)}, + {"apple-a11", ARMV8_2A, (AArch64::AEK_FP16)}, + {"apple-a12", ARMV8_3A, (AArch64::AEK_FP16)}, + {"apple-a13", ARMV8_4A, + (AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3)}, + {"apple-a14", ARMV8_5A, + (AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3)}, + {"apple-a15", ARMV8_5A, + (AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3 | + AArch64::AEK_BF16 | AArch64::AEK_I8MM)}, + {"apple-a16", ARMV8_5A, + (AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3 | + AArch64::AEK_BF16 | AArch64::AEK_I8MM)}, + {"apple-m1", ARMV8_5A, + (AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3)}, + {"apple-m2", ARMV8_5A, + (AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3 | + AArch64::AEK_BF16 | AArch64::AEK_I8MM)}, + {"apple-s4", ARMV8_3A, (AArch64::AEK_FP16)}, + {"apple-s5", ARMV8_3A, (AArch64::AEK_FP16)}, + {"exynos-m3", ARMV8A, (AArch64::AEK_CRC)}, + {"exynos-m4", ARMV8_2A, (AArch64::AEK_DOTPROD | AArch64::AEK_FP16)}, + {"exynos-m5", ARMV8_2A, (AArch64::AEK_DOTPROD | AArch64::AEK_FP16)}, + {"falkor", ARMV8A, (AArch64::AEK_CRC | AArch64::AEK_RDM)}, + {"saphira", ARMV8_3A, (AArch64::AEK_PROFILE)}, + {"kryo", ARMV8A, (AArch64::AEK_CRC)}, + {"thunderx2t99", ARMV8_1A, (AArch64::AEK_NONE)}, + {"thunderx3t110", ARMV8_3A, (AArch64::AEK_NONE)}, + {"thunderx", ARMV8A, (AArch64::AEK_CRC)}, + {"thunderxt88", ARMV8A, (AArch64::AEK_CRC)}, + {"thunderxt81", ARMV8A, (AArch64::AEK_CRC)}, + {"thunderxt83", ARMV8A, (AArch64::AEK_CRC)}, + {"tsv110", ARMV8_2A, + (AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | AArch64::AEK_FP16FML | + AArch64::AEK_PROFILE)}, + {"a64fx", ARMV8_2A, (AArch64::AEK_FP16 | AArch64::AEK_SVE)}, + {"carmel", ARMV8_2A, (AArch64::AEK_FP16)}, + {"ampere1", ARMV8_6A, + (AArch64::AEK_FP16 | AArch64::AEK_SB | AArch64::AEK_SSBS)}, + // Invalid CPU + {"invalid", INVALID, (AArch64::AEK_INVALID)}, }; -const struct { +// An alias for a CPU. +struct CpuAlias { StringRef Alias; StringRef Name; -} AArch64CPUAliases[] = { -#define AARCH64_CPU_ALIAS(ALIAS, NAME) {ALIAS, NAME}, -#include "AArch64TargetParser.def" }; -const ArchKind ArchKinds[] = { -#define AARCH64_ARCH(NAME, ID, ARCH_FEATURE, ARCH_BASE_EXT) ArchKind::ID, -#include "AArch64TargetParser.def" -}; - -inline ArchKind &operator--(ArchKind &Kind) { - if ((Kind == ArchKind::INVALID) || (Kind == ArchKind::ARMV8A) || - (Kind == ArchKind::ARMV9A) || (Kind == ArchKind::ARMV8R)) - Kind = ArchKind::INVALID; - else { - unsigned KindAsInteger = static_cast(Kind); - Kind = static_cast(--KindAsInteger); - } - return Kind; -} +inline constexpr CpuAlias CpuAliases[] = {{"grace", "neoverse-v2"}}; bool getExtensionFeatures(uint64_t Extensions, std::vector &Features); -StringRef getArchFeature(ArchKind AK); -StringRef getArchName(ArchKind AK); -StringRef getSubArch(ArchKind AK); -StringRef getArchExtName(unsigned ArchExtKind); StringRef getArchExtFeature(StringRef ArchExt); -ArchKind convertV9toV8(ArchKind AK); StringRef resolveCPUAlias(StringRef CPU); // Information by Name -uint64_t getDefaultExtensions(StringRef CPU, ArchKind AK); +uint64_t getDefaultExtensions(StringRef CPU, const ArchInfo &AI); void getFeatureOption(StringRef Name, std::string &Feature); -ArchKind getCPUArchKind(StringRef CPU); -ArchKind getSubArchArchKind(StringRef SubArch); +const ArchInfo &getArchForCpu(StringRef CPU); // Parser -ArchKind parseArch(StringRef Arch); +const ArchInfo &parseArch(StringRef Arch); ArchExtKind parseArchExt(StringRef ArchExt); -ArchKind parseCPUArch(StringRef CPU); +// Given the name of a CPU or alias, return the correponding CpuInfo. +const CpuInfo &parseCpu(StringRef Name); // Used by target parser tests void fillValidCPUArchList(SmallVectorImpl &Values); @@ -255,4 +509,4 @@ uint64_t getCpuSupportsMask(ArrayRef FeatureStrs); } // namespace AArch64 } // namespace llvm -#endif +#endif \ No newline at end of file diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 7d52185..1ef3ada 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -6822,67 +6822,48 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) { return false; } -static void ExpandCryptoAEK(AArch64::ArchKind ArchKind, +static void ExpandCryptoAEK(const AArch64::ArchInfo &ArchInfo, SmallVector &RequestedExtensions) { const bool NoCrypto = llvm::is_contained(RequestedExtensions, "nocrypto"); const bool Crypto = llvm::is_contained(RequestedExtensions, "crypto"); if (!NoCrypto && Crypto) { - switch (ArchKind) { - default: - // Map 'generic' (and others) to sha2 and aes, because - // that was the traditional meaning of crypto. - case AArch64::ArchKind::ARMV8_1A: - case AArch64::ArchKind::ARMV8_2A: - case AArch64::ArchKind::ARMV8_3A: + // Map 'generic' (and others) to sha2 and aes, because + // that was the traditional meaning of crypto. + if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A || + ArchInfo == AArch64::ARMV8_3A) { RequestedExtensions.push_back("sha2"); RequestedExtensions.push_back("aes"); - break; - case AArch64::ArchKind::ARMV8_4A: - case AArch64::ArchKind::ARMV8_5A: - case AArch64::ArchKind::ARMV8_6A: - case AArch64::ArchKind::ARMV8_7A: - case AArch64::ArchKind::ARMV8_8A: - case AArch64::ArchKind::ARMV8_9A: - case AArch64::ArchKind::ARMV9A: - case AArch64::ArchKind::ARMV9_1A: - case AArch64::ArchKind::ARMV9_2A: - case AArch64::ArchKind::ARMV9_3A: - case AArch64::ArchKind::ARMV9_4A: - case AArch64::ArchKind::ARMV8R: + } + if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A || + ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A || + ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A || + ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A || + ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A || + ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) { RequestedExtensions.push_back("sm4"); RequestedExtensions.push_back("sha3"); RequestedExtensions.push_back("sha2"); RequestedExtensions.push_back("aes"); - break; } } else if (NoCrypto) { - switch (ArchKind) { - default: - // Map 'generic' (and others) to sha2 and aes, because - // that was the traditional meaning of crypto. - case AArch64::ArchKind::ARMV8_1A: - case AArch64::ArchKind::ARMV8_2A: - case AArch64::ArchKind::ARMV8_3A: + // Map 'generic' (and others) to sha2 and aes, because + // that was the traditional meaning of crypto. + if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A || + ArchInfo == AArch64::ARMV8_3A) { RequestedExtensions.push_back("nosha2"); RequestedExtensions.push_back("noaes"); - break; - case AArch64::ArchKind::ARMV8_4A: - case AArch64::ArchKind::ARMV8_5A: - case AArch64::ArchKind::ARMV8_6A: - case AArch64::ArchKind::ARMV8_7A: - case AArch64::ArchKind::ARMV8_8A: - case AArch64::ArchKind::ARMV8_9A: - case AArch64::ArchKind::ARMV9A: - case AArch64::ArchKind::ARMV9_1A: - case AArch64::ArchKind::ARMV9_2A: - case AArch64::ArchKind::ARMV9_3A: - case AArch64::ArchKind::ARMV9_4A: + } + if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A || + ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A || + ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A || + ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A || + ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A || + ArchInfo == AArch64::ARMV9_4A) { RequestedExtensions.push_back("nosm4"); RequestedExtensions.push_back("nosha3"); RequestedExtensions.push_back("nosha2"); RequestedExtensions.push_back("noaes"); - break; } } } @@ -6896,8 +6877,8 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) { std::tie(Arch, ExtensionString) = getParser().parseStringToEndOfStatement().trim().split('+'); - AArch64::ArchKind ID = AArch64::parseArch(Arch); - if (ID == AArch64::ArchKind::INVALID) + const AArch64::ArchInfo &ArchInfo = AArch64::parseArch(Arch); + if (ArchInfo == AArch64::INVALID) return Error(ArchLoc, "unknown arch name"); if (parseToken(AsmToken::EndOfStatement)) @@ -6905,9 +6886,9 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) { // Get the architecture and extension features. std::vector AArch64Features; - AArch64Features.push_back(AArch64::getArchFeature(ID)); - AArch64::getExtensionFeatures(AArch64::getDefaultExtensions("generic", ID), - AArch64Features); + AArch64Features.push_back(ArchInfo.ArchFeature); + AArch64::getExtensionFeatures( + AArch64::getDefaultExtensions("generic", ArchInfo), AArch64Features); MCSubtargetInfo &STI = copySTI(); std::vector ArchFeatures(AArch64Features.begin(), AArch64Features.end()); @@ -6918,7 +6899,7 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) { if (!ExtensionString.empty()) ExtensionString.split(RequestedExtensions, '+'); - ExpandCryptoAEK(ID, RequestedExtensions); + ExpandCryptoAEK(ArchInfo, RequestedExtensions); FeatureBitset Features = STI.getFeatureBits(); for (auto Name : RequestedExtensions) { @@ -7014,7 +6995,7 @@ bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) { STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, ""); CurLoc = incrementLoc(CurLoc, CPU.size()); - ExpandCryptoAEK(llvm::AArch64::getCPUArchKind(CPU), RequestedExtensions); + ExpandCryptoAEK(llvm::AArch64::getArchForCpu(CPU), RequestedExtensions); for (auto Name : RequestedExtensions) { // Advance source location past '+'. diff --git a/llvm/lib/TargetParser/AArch64TargetParser.cpp b/llvm/lib/TargetParser/AArch64TargetParser.cpp index baa6cbf..41d5c25 100644 --- a/llvm/lib/TargetParser/AArch64TargetParser.cpp +++ b/llvm/lib/TargetParser/AArch64TargetParser.cpp @@ -25,131 +25,95 @@ static unsigned checkArchVersion(llvm::StringRef Arch) { return 0; } -uint64_t AArch64::getDefaultExtensions(StringRef CPU, AArch64::ArchKind AK) { +uint64_t AArch64::getDefaultExtensions(StringRef CPU, + const AArch64::ArchInfo &AI) { if (CPU == "generic") - return AArch64ARCHNames[static_cast(AK)].ArchBaseExtensions; - - return StringSwitch(CPU) -#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_EXT) \ - .Case(NAME, AArch64ARCHNames[static_cast(ArchKind::ID)] \ - .ArchBaseExtensions | \ - DEFAULT_EXT) -#include "../../include/llvm/TargetParser/AArch64TargetParser.def" - .Default(AArch64::AEK_INVALID); + return AI.DefaultExts; + + // Note: this now takes cpu aliases into account + const CpuInfo &Cpu = parseCpu(CPU); + return Cpu.Arch.DefaultExts | Cpu.DefaultExtensions; } void AArch64::getFeatureOption(StringRef Name, std::string &Feature) { - Feature = llvm::StringSwitch(Name.substr(1)) -#define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE, FMV_ID, \ - DEP_FEATURES, FMV_PRIORITY) \ - .Case(NAME, FEATURE) -#include "../../include/llvm/TargetParser/AArch64TargetParser.def" - .Default(Name.str()); + for (const auto &E : llvm::AArch64::Extensions) { + if (Name == E.Name) { + Feature = E.Feature; + return; + } + } + Feature = Name.str(); } -AArch64::ArchKind AArch64::getCPUArchKind(StringRef CPU) { +const AArch64::ArchInfo &AArch64::getArchForCpu(StringRef CPU) { if (CPU == "generic") - return ArchKind::ARMV8A; + return ARMV8A; - return StringSwitch(CPU) -#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_EXT) .Case(NAME, ArchKind::ID) -#include "../../include/llvm/TargetParser/AArch64TargetParser.def" - .Default(ArchKind::INVALID); + // Note: this now takes cpu aliases into account + const CpuInfo &Cpu = parseCpu(CPU); + return Cpu.Arch; } -AArch64::ArchKind AArch64::getSubArchArchKind(StringRef SubArch) { - for (const auto &A : AArch64ARCHNames) - if (A.getSubArch() == SubArch) - return A.ID; - return ArchKind::INVALID; +const AArch64::ArchInfo &AArch64::ArchInfo::findBySubArch(StringRef SubArch) { + for (const auto *A : AArch64::ArchInfos) + if (A->getSubArch() == SubArch) + return *A; + return AArch64::INVALID; } uint64_t AArch64::getCpuSupportsMask(ArrayRef FeatureStrs) { uint64_t FeaturesMask = 0; for (const StringRef &FeatureStr : FeatureStrs) { - unsigned Feature = StringSwitch(FeatureStr) -#define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE, FMV_ID, \ - DEP_FEATURES, FMV_PRIORITY) \ - .Case(NAME, llvm::AArch64::FEAT_##FMV_ID) -#include "../../include/llvm/TargetParser/AArch64TargetParser.def" - ; - FeaturesMask |= (1ULL << Feature); + for (const auto &E : llvm::AArch64::Extensions) + if (FeatureStr == E.Name) { + FeaturesMask |= (1ULL << E.CPUFeature); + break; + } } return FeaturesMask; } -bool AArch64::getExtensionFeatures(uint64_t Extensions, +bool AArch64::getExtensionFeatures(uint64_t InputExts, std::vector &Features) { - if (Extensions == AArch64::AEK_INVALID) + if (InputExts == AArch64::AEK_INVALID) return false; -#define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE, FMV_ID, \ - DEP_FEATURES, FMV_PRIORITY) \ - if (Extensions & ID) { \ - const char *feature = FEATURE; \ - /* INVALID and NONE have no feature name. */ \ - if (feature) \ - Features.push_back(feature); \ - } -#include "llvm/TargetParser/AArch64TargetParser.def" + for (const auto &E : Extensions) + /* INVALID and NONE have no feature name. */ + if ((InputExts & E.ID) && !E.Feature.empty()) + Features.push_back(E.Feature); return true; } -StringRef AArch64::resolveCPUAlias(StringRef CPU) { - return StringSwitch(CPU) -#define AARCH64_CPU_ALIAS(ALIAS, NAME) .Case(ALIAS, NAME) -#include "../../include/llvm/TargetParser/AArch64TargetParser.def" - .Default(CPU); -} - -StringRef AArch64::getArchFeature(AArch64::ArchKind AK) { - return AArch64ARCHNames[static_cast(AK)].ArchFeature; -} - -StringRef AArch64::getArchName(AArch64::ArchKind AK) { - return AArch64ARCHNames[static_cast(AK)].Name; -} - -StringRef AArch64::getSubArch(AArch64::ArchKind AK) { - return AArch64ARCHNames[static_cast(AK)].getSubArch(); +StringRef AArch64::resolveCPUAlias(StringRef Name) { + for (const auto &A : CpuAliases) + if (A.Alias == Name) + return A.Name; + return Name; } StringRef AArch64::getArchExtFeature(StringRef ArchExt) { if (ArchExt.startswith("no")) { StringRef ArchExtBase(ArchExt.substr(2)); - for (const auto &AE : AArch64ARCHExtNames) { + for (const auto &AE : Extensions) { if (!AE.NegFeature.empty() && ArchExtBase == AE.Name) return AE.NegFeature; } } - for (const auto &AE : AArch64ARCHExtNames) + for (const auto &AE : Extensions) if (!AE.Feature.empty() && ArchExt == AE.Name) return AE.Feature; return StringRef(); } -AArch64::ArchKind AArch64::convertV9toV8(AArch64::ArchKind AK) { - if (AK == AArch64::ArchKind::INVALID) - return AK; - if (AK < AArch64::ArchKind::ARMV9A) - return AK; - if (AK >= AArch64::ArchKind::ARMV8R) - return AArch64::ArchKind::INVALID; - unsigned AK_v8 = static_cast(AArch64::ArchKind::ARMV8_5A); - AK_v8 += static_cast(AK) - - static_cast(AArch64::ArchKind::ARMV9A); - return static_cast(AK_v8); -} - void AArch64::fillValidCPUArchList(SmallVectorImpl &Values) { - for (const auto &Arch : AArch64CPUNames) { - if (Arch.ArchID != ArchKind::INVALID) - Values.push_back(Arch.Name); - } + for (const auto &C : CpuInfos) + if (C.Arch != INVALID) + Values.push_back(C.Name); - for (const auto &Alias: AArch64CPUAliases) + for (const auto &Alias : CpuAliases) Values.push_back(Alias.Alias); } @@ -159,39 +123,37 @@ bool AArch64::isX18ReservedByDefault(const Triple &TT) { } // Allows partial match, ex. "v8a" matches "armv8a". -AArch64::ArchKind AArch64::parseArch(StringRef Arch) { +const AArch64::ArchInfo &AArch64::parseArch(StringRef Arch) { Arch = llvm::ARM::getCanonicalArchName(Arch); if (checkArchVersion(Arch) < 8) - return ArchKind::INVALID; + return AArch64::INVALID; StringRef Syn = llvm::ARM::getArchSynonym(Arch); - for (const auto &A : AArch64ARCHNames) { - if (A.Name.endswith(Syn)) - return A.ID; + for (const auto *A : ArchInfos) { + if (A->Name.endswith(Syn)) + return *A; } - return ArchKind::INVALID; + return AArch64::INVALID; } AArch64::ArchExtKind AArch64::parseArchExt(StringRef ArchExt) { - for (const auto &A : AArch64ARCHExtNames) { + for (const auto &A : Extensions) { if (ArchExt == A.Name) return static_cast(A.ID); } return AArch64::AEK_INVALID; } -AArch64::ArchKind AArch64::parseCPUArch(StringRef CPU) { +const AArch64::CpuInfo &AArch64::parseCpu(StringRef Name) { // Resolve aliases first. - for (const auto &Alias : AArch64CPUAliases) { - if (CPU == Alias.Alias) { - CPU = Alias.Name; - break; - } - } + Name = resolveCPUAlias(Name); + // Then find the CPU name. - for (const auto &C : AArch64CPUNames) - if (CPU == C.Name) - return C.ArchID; + for (const auto &C : CpuInfos) + if (Name == C.Name) + return C; - return ArchKind::INVALID; + // "generic" returns invalid. + assert(Name != "invalid" && "Unexpected recursion."); + return parseCpu("invalid"); } diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp index 69e6a73..7bf20ef 100644 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -953,11 +953,11 @@ class AArch64CPUTestFixture TEST_P(AArch64CPUTestFixture, testAArch64CPU) { ARMCPUTestParams params = GetParam(); - AArch64::ArchKind AK = AArch64::parseCPUArch(params.CPUName); - EXPECT_EQ(params.ExpectedArch, AArch64::getArchName(AK)); + const AArch64::ArchInfo &AI = AArch64::parseCpu(params.CPUName).Arch; + EXPECT_EQ(params.ExpectedArch, AI.Name); uint64_t default_extensions = - AArch64::getDefaultExtensions(params.CPUName, AK); + AArch64::getDefaultExtensions(params.CPUName, AI); EXPECT_PRED_FORMAT2(AssertSameExtensionFlags, params.ExpectedFlags, default_extensions); } @@ -1403,14 +1403,14 @@ TEST(TargetParserTest, testAArch64CPUArchList) { // valid, and match the expected 'magic' count. EXPECT_EQ(List.size(), NumAArch64CPUArchs); for(StringRef CPU : List) { - EXPECT_NE(AArch64::parseCPUArch(CPU), AArch64::ArchKind::INVALID); + EXPECT_NE(AArch64::parseCpu(CPU).Arch, AArch64::INVALID); } } bool testAArch64Arch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch, unsigned ArchAttr) { - AArch64::ArchKind AK = AArch64::parseArch(Arch); - return AK != AArch64::ArchKind::INVALID; + const AArch64::ArchInfo &AI = AArch64::parseArch(Arch); + return AI != AArch64::INVALID; } TEST(TargetParserTest, testAArch64Arch) { @@ -1446,148 +1446,81 @@ TEST(TargetParserTest, testAArch64Arch) { ARMBuildAttrs::CPUArch::v8_A)); } -bool testAArch64Extension(StringRef CPUName, AArch64::ArchKind AK, +bool testAArch64Extension(StringRef CPUName, const AArch64::ArchInfo &AI, StringRef ArchExt) { - return AArch64::getDefaultExtensions(CPUName, AK) & + return AArch64::getDefaultExtensions(CPUName, AI) & AArch64::parseArchExt(ArchExt); } TEST(TargetParserTest, testAArch64Extension) { - EXPECT_FALSE(testAArch64Extension("cortex-a34", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_FALSE(testAArch64Extension("cortex-a35", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_FALSE(testAArch64Extension("cortex-a53", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("cortex-a55", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("cortex-a55", - AArch64::ArchKind::INVALID, "fp16")); - EXPECT_FALSE(testAArch64Extension("cortex-a55", - AArch64::ArchKind::INVALID, "fp16fml")); - EXPECT_TRUE(testAArch64Extension("cortex-a55", - AArch64::ArchKind::INVALID, "dotprod")); - EXPECT_FALSE(testAArch64Extension("cortex-a57", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_FALSE(testAArch64Extension("cortex-a72", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_FALSE(testAArch64Extension("cortex-a73", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("cortex-a75", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("cortex-a75", - AArch64::ArchKind::INVALID, "fp16")); - EXPECT_FALSE(testAArch64Extension("cortex-a75", - AArch64::ArchKind::INVALID, "fp16fml")); - EXPECT_TRUE(testAArch64Extension("cortex-a75", - AArch64::ArchKind::INVALID, "dotprod")); - EXPECT_TRUE(testAArch64Extension("cortex-r82", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("cortex-r82", - AArch64::ArchKind::INVALID, "fp16")); - EXPECT_TRUE(testAArch64Extension("cortex-r82", - AArch64::ArchKind::INVALID, "fp16fml")); - EXPECT_TRUE(testAArch64Extension("cortex-r82", - AArch64::ArchKind::INVALID, "dotprod")); - EXPECT_TRUE(testAArch64Extension("cortex-r82", - AArch64::ArchKind::INVALID, "lse")); - EXPECT_FALSE(testAArch64Extension("cyclone", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_FALSE(testAArch64Extension("exynos-m3", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("exynos-m4", - AArch64::ArchKind::INVALID, "dotprod")); - EXPECT_TRUE(testAArch64Extension("exynos-m4", - AArch64::ArchKind::INVALID, "fp16")); - EXPECT_TRUE(testAArch64Extension("exynos-m4", - AArch64::ArchKind::INVALID, "lse")); - EXPECT_TRUE(testAArch64Extension("exynos-m4", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("exynos-m4", - AArch64::ArchKind::INVALID, "rdm")); - EXPECT_TRUE(testAArch64Extension("exynos-m5", - AArch64::ArchKind::INVALID, "dotprod")); - EXPECT_TRUE(testAArch64Extension("exynos-m5", - AArch64::ArchKind::INVALID, "fp16")); - EXPECT_TRUE(testAArch64Extension("exynos-m5", - AArch64::ArchKind::INVALID, "lse")); - EXPECT_TRUE(testAArch64Extension("exynos-m5", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("exynos-m5", - AArch64::ArchKind::INVALID, "rdm")); - EXPECT_TRUE(testAArch64Extension("falkor", - AArch64::ArchKind::INVALID, "rdm")); - EXPECT_FALSE(testAArch64Extension("kryo", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("saphira", - AArch64::ArchKind::INVALID, "crc")); - EXPECT_TRUE(testAArch64Extension("saphira", - AArch64::ArchKind::INVALID, "lse")); - EXPECT_TRUE(testAArch64Extension("saphira", - AArch64::ArchKind::INVALID, "rdm")); - EXPECT_TRUE(testAArch64Extension("saphira", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("saphira", - AArch64::ArchKind::INVALID, "rcpc")); - EXPECT_TRUE(testAArch64Extension("saphira", - AArch64::ArchKind::INVALID, "profile")); - EXPECT_FALSE(testAArch64Extension("saphira", - AArch64::ArchKind::INVALID, "fp16")); - EXPECT_FALSE(testAArch64Extension("thunderx2t99", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_FALSE(testAArch64Extension("thunderx", - AArch64::ArchKind::INVALID, "lse")); - EXPECT_FALSE(testAArch64Extension("thunderxt81", - AArch64::ArchKind::INVALID, "lse")); - EXPECT_FALSE(testAArch64Extension("thunderxt83", - AArch64::ArchKind::INVALID, "lse")); - EXPECT_FALSE(testAArch64Extension("thunderxt88", - AArch64::ArchKind::INVALID, "lse")); - EXPECT_TRUE(testAArch64Extension("tsv110", - AArch64::ArchKind::INVALID, "crypto")); - EXPECT_FALSE(testAArch64Extension("tsv110", - AArch64::ArchKind::INVALID, "sha3")); - EXPECT_FALSE(testAArch64Extension("tsv110", - AArch64::ArchKind::INVALID, "sm4")); - EXPECT_TRUE(testAArch64Extension("tsv110", - AArch64::ArchKind::INVALID, "ras")); - EXPECT_TRUE(testAArch64Extension("tsv110", - AArch64::ArchKind::INVALID, "profile")); - EXPECT_TRUE(testAArch64Extension("tsv110", - AArch64::ArchKind::INVALID, "fp16")); - EXPECT_TRUE(testAArch64Extension("tsv110", - AArch64::ArchKind::INVALID, "fp16fml")); - EXPECT_TRUE(testAArch64Extension("tsv110", - AArch64::ArchKind::INVALID, "dotprod")); - EXPECT_TRUE(testAArch64Extension("a64fx", - AArch64::ArchKind::INVALID, "fp16")); - EXPECT_TRUE(testAArch64Extension("a64fx", - AArch64::ArchKind::INVALID, "sve")); - EXPECT_FALSE(testAArch64Extension("a64fx", - AArch64::ArchKind::INVALID, "sve2")); - EXPECT_TRUE( - testAArch64Extension("carmel", AArch64::ArchKind::INVALID, "crypto")); - EXPECT_TRUE( - testAArch64Extension("carmel", AArch64::ArchKind::INVALID, "fp16")); - - EXPECT_FALSE(testAArch64Extension( - "generic", AArch64::ArchKind::ARMV8A, "ras")); - EXPECT_FALSE(testAArch64Extension( - "generic", AArch64::ArchKind::ARMV8_1A, "ras")); - EXPECT_FALSE(testAArch64Extension( - "generic", AArch64::ArchKind::ARMV8_2A, "profile")); - EXPECT_FALSE(testAArch64Extension( - "generic", AArch64::ArchKind::ARMV8_2A, "fp16")); - EXPECT_FALSE(testAArch64Extension( - "generic", AArch64::ArchKind::ARMV8_2A, "fp16fml")); - EXPECT_FALSE(testAArch64Extension( - "generic", AArch64::ArchKind::ARMV8_3A, "fp16")); - EXPECT_FALSE(testAArch64Extension( - "generic", AArch64::ArchKind::ARMV8_3A, "fp16fml")); - EXPECT_FALSE(testAArch64Extension( - "generic", AArch64::ArchKind::ARMV8_4A, "fp16")); - EXPECT_FALSE(testAArch64Extension( - "generic", AArch64::ArchKind::ARMV8_4A, "fp16fml")); + EXPECT_FALSE(testAArch64Extension("cortex-a34", AArch64::INVALID, "ras")); + EXPECT_FALSE(testAArch64Extension("cortex-a35", AArch64::INVALID, "ras")); + EXPECT_FALSE(testAArch64Extension("cortex-a53", AArch64::INVALID, "ras")); + EXPECT_TRUE(testAArch64Extension("cortex-a55", AArch64::INVALID, "ras")); + EXPECT_TRUE(testAArch64Extension("cortex-a55", AArch64::INVALID, "fp16")); + EXPECT_FALSE(testAArch64Extension("cortex-a55", AArch64::INVALID, "fp16fml")); + EXPECT_TRUE(testAArch64Extension("cortex-a55", AArch64::INVALID, "dotprod")); + EXPECT_FALSE(testAArch64Extension("cortex-a57", AArch64::INVALID, "ras")); + EXPECT_FALSE(testAArch64Extension("cortex-a72", AArch64::INVALID, "ras")); + EXPECT_FALSE(testAArch64Extension("cortex-a73", AArch64::INVALID, "ras")); + EXPECT_TRUE(testAArch64Extension("cortex-a75", AArch64::INVALID, "ras")); + EXPECT_TRUE(testAArch64Extension("cortex-a75", AArch64::INVALID, "fp16")); + EXPECT_FALSE(testAArch64Extension("cortex-a75", AArch64::INVALID, "fp16fml")); + EXPECT_TRUE(testAArch64Extension("cortex-a75", AArch64::INVALID, "dotprod")); + EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "ras")); + EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "fp16")); + EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "fp16fml")); + EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "dotprod")); + EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "lse")); + EXPECT_FALSE(testAArch64Extension("cyclone", AArch64::INVALID, "ras")); + EXPECT_FALSE(testAArch64Extension("exynos-m3", AArch64::INVALID, "ras")); + EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "dotprod")); + EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "fp16")); + EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "lse")); + EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "ras")); + EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "rdm")); + EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "dotprod")); + EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "fp16")); + EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "lse")); + EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "ras")); + EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "rdm")); + EXPECT_TRUE(testAArch64Extension("falkor", AArch64::INVALID, "rdm")); + EXPECT_FALSE(testAArch64Extension("kryo", AArch64::INVALID, "ras")); + EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "crc")); + EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "lse")); + EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "rdm")); + EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "ras")); + EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "rcpc")); + EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "profile")); + EXPECT_FALSE(testAArch64Extension("saphira", AArch64::INVALID, "fp16")); + EXPECT_FALSE(testAArch64Extension("thunderx2t99", AArch64::INVALID, "ras")); + EXPECT_FALSE(testAArch64Extension("thunderx", AArch64::INVALID, "lse")); + EXPECT_FALSE(testAArch64Extension("thunderxt81", AArch64::INVALID, "lse")); + EXPECT_FALSE(testAArch64Extension("thunderxt83", AArch64::INVALID, "lse")); + EXPECT_FALSE(testAArch64Extension("thunderxt88", AArch64::INVALID, "lse")); + EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "crypto")); + EXPECT_FALSE(testAArch64Extension("tsv110", AArch64::INVALID, "sha3")); + EXPECT_FALSE(testAArch64Extension("tsv110", AArch64::INVALID, "sm4")); + EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "ras")); + EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "profile")); + EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "fp16")); + EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "fp16fml")); + EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "dotprod")); + EXPECT_TRUE(testAArch64Extension("a64fx", AArch64::INVALID, "fp16")); + EXPECT_TRUE(testAArch64Extension("a64fx", AArch64::INVALID, "sve")); + EXPECT_FALSE(testAArch64Extension("a64fx", AArch64::INVALID, "sve2")); + EXPECT_TRUE(testAArch64Extension("carmel", AArch64::INVALID, "crypto")); + EXPECT_TRUE(testAArch64Extension("carmel", AArch64::INVALID, "fp16")); + + EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8A, "ras")); + EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_1A, "ras")); + EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_2A, "profile")); + EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_2A, "fp16")); + EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_2A, "fp16fml")); + EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_3A, "fp16")); + EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_3A, "fp16fml")); + EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_4A, "fp16")); + EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_4A, "fp16fml")); } TEST(TargetParserTest, AArch64ExtensionFeatures) { @@ -1691,44 +1624,81 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { } TEST(TargetParserTest, AArch64ArchFeatures) { - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::INVALID), "+"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8A), "+v8a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_1A), "+v8.1a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_2A), "+v8.2a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_3A), "+v8.3a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_4A), "+v8.4a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_5A), "+v8.5a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_6A), "+v8.6a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_7A), "+v8.7a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_8A), "+v8.8a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_9A), "+v8.9a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV9A), "+v9a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV9_1A), "+v9.1a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV9_2A), "+v9.2a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV9_3A), "+v9.3a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV9_4A), "+v9.4a"); - EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8R), "+v8r"); + EXPECT_EQ(AArch64::INVALID.ArchFeature, "+"); + EXPECT_EQ(AArch64::ARMV8A.ArchFeature, "+v8a"); + EXPECT_EQ(AArch64::ARMV8_1A.ArchFeature, "+v8.1a"); + EXPECT_EQ(AArch64::ARMV8_2A.ArchFeature, "+v8.2a"); + EXPECT_EQ(AArch64::ARMV8_3A.ArchFeature, "+v8.3a"); + EXPECT_EQ(AArch64::ARMV8_4A.ArchFeature, "+v8.4a"); + EXPECT_EQ(AArch64::ARMV8_5A.ArchFeature, "+v8.5a"); + EXPECT_EQ(AArch64::ARMV8_6A.ArchFeature, "+v8.6a"); + EXPECT_EQ(AArch64::ARMV8_7A.ArchFeature, "+v8.7a"); + EXPECT_EQ(AArch64::ARMV8_8A.ArchFeature, "+v8.8a"); + EXPECT_EQ(AArch64::ARMV8_9A.ArchFeature, "+v8.9a"); + EXPECT_EQ(AArch64::ARMV9A.ArchFeature, "+v9a"); + EXPECT_EQ(AArch64::ARMV9_1A.ArchFeature, "+v9.1a"); + EXPECT_EQ(AArch64::ARMV9_2A.ArchFeature, "+v9.2a"); + EXPECT_EQ(AArch64::ARMV9_3A.ArchFeature, "+v9.3a"); + EXPECT_EQ(AArch64::ARMV9_4A.ArchFeature, "+v9.4a"); + EXPECT_EQ(AArch64::ARMV8R.ArchFeature, "+v8r"); } -TEST(TargetParserTest, AArch64ArchV9toV8Conversion) { - for (auto AK : AArch64::ArchKinds) { - if (AK == AArch64::ArchKind::INVALID) - EXPECT_EQ(AK, AArch64::convertV9toV8(AK)); - else if (AK < AArch64::ArchKind::ARMV9A) - EXPECT_EQ(AK, AArch64::convertV9toV8(AK)); - else if (AK >= AArch64::ArchKind::ARMV8R) - EXPECT_EQ(AArch64::ArchKind::INVALID, AArch64::convertV9toV8(AK)); - else - EXPECT_TRUE(AArch64::convertV9toV8(AK) < AArch64::ArchKind::ARMV9A); +TEST(TargetParserTest, AArch64ArchPartialOrder) { + EXPECT_FALSE(AArch64::INVALID.implies(AArch64::INVALID)); + + for (const auto *A : AArch64::ArchInfos) { + EXPECT_EQ(*A, *A); + if (!(*A == *A)) { + EXPECT_NE(*A, *A); + } + // Comparison with invalid is always false + EXPECT_FALSE(A->implies(AArch64::INVALID)); + EXPECT_FALSE(AArch64::INVALID.implies(*A)); + + // v8r has no relation to other valid architectures + if (*A != AArch64::ARMV8R) { + EXPECT_FALSE(A->implies(AArch64::ARMV8R)); + EXPECT_FALSE(AArch64::ARMV8R.implies(*A)); + } } - EXPECT_EQ(AArch64::ArchKind::ARMV8_5A, - AArch64::convertV9toV8(AArch64::ArchKind::ARMV9A)); - EXPECT_EQ(AArch64::ArchKind::ARMV8_6A, - AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_1A)); - EXPECT_EQ(AArch64::ArchKind::ARMV8_7A, - AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_2A)); - EXPECT_EQ(AArch64::ArchKind::ARMV8_8A, - AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_3A)); + + for (const auto *A : { + &AArch64::ARMV8_1A, + &AArch64::ARMV8_2A, + &AArch64::ARMV8_3A, + &AArch64::ARMV8_4A, + &AArch64::ARMV8_5A, + &AArch64::ARMV8_6A, + &AArch64::ARMV8_7A, + &AArch64::ARMV8_8A, + &AArch64::ARMV8_9A, + }) + EXPECT_TRUE(A->implies(AArch64::ARMV8A)); + + for (const auto *A : {&AArch64::ARMV9_1A, &AArch64::ARMV9_2A, + &AArch64::ARMV9_3A, &AArch64::ARMV9_4A}) + EXPECT_TRUE(A->implies(AArch64::ARMV9A)); + + EXPECT_TRUE(AArch64::ARMV8_1A.implies(AArch64::ARMV8A)); + EXPECT_TRUE(AArch64::ARMV8_2A.implies(AArch64::ARMV8_1A)); + EXPECT_TRUE(AArch64::ARMV8_3A.implies(AArch64::ARMV8_2A)); + EXPECT_TRUE(AArch64::ARMV8_4A.implies(AArch64::ARMV8_3A)); + EXPECT_TRUE(AArch64::ARMV8_5A.implies(AArch64::ARMV8_4A)); + EXPECT_TRUE(AArch64::ARMV8_6A.implies(AArch64::ARMV8_5A)); + EXPECT_TRUE(AArch64::ARMV8_7A.implies(AArch64::ARMV8_6A)); + EXPECT_TRUE(AArch64::ARMV8_8A.implies(AArch64::ARMV8_7A)); + EXPECT_TRUE(AArch64::ARMV8_9A.implies(AArch64::ARMV8_8A)); + + EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV9A)); + EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV9_1A)); + EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV9_2A)); + EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV9_3A)); + + EXPECT_TRUE(AArch64::ARMV9A.implies(AArch64::ARMV8_5A)); + EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV8_6A)); + EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV8_7A)); + EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV8_8A)); + EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV8_9A)); } TEST(TargetParserTest, AArch64ArchExtFeature) { -- 2.7.4