diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -76,10 +76,9 @@ 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/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -47,69 +47,58 @@ #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 @@ 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::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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -70,7 +70,7 @@ // 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 @@ // +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 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 @@ 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 @@ 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 --- 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 --- 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 --- 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 --- a/llvm/include/llvm/ADT/StringRef.h +++ b/llvm/include/llvm/ADT/StringRef.h @@ -561,7 +561,8 @@ /// \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 --- a/llvm/include/llvm/Support/VersionTuple.h +++ b/llvm/include/llvm/Support/VersionTuple.h @@ -41,24 +41,25 @@ 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.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h --- 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 @@ }; // 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 @@ } // namespace AArch64 } // namespace llvm -#endif +#endif \ No newline at end of file diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.def b/llvm/include/llvm/TargetParser/AArch64TargetParser.def deleted file mode 100644 --- 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/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -6822,67 +6822,48 @@ 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 @@ 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 @@ // 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 @@ if (!ExtensionString.empty()) ExtensionString.split(RequestedExtensions, '+'); - ExpandCryptoAEK(ID, RequestedExtensions); + ExpandCryptoAEK(ArchInfo, RequestedExtensions); FeatureBitset Features = STI.getFeatureBits(); for (auto Name : RequestedExtensions) { @@ -7014,7 +6995,7 @@ 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 --- a/llvm/lib/TargetParser/AArch64TargetParser.cpp +++ b/llvm/lib/TargetParser/AArch64TargetParser.cpp @@ -25,131 +25,95 @@ 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 @@ } // 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 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -953,11 +953,11 @@ 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 @@ // 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 @@ 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, 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) {