[AArch64] Reland "Improve TargetParser API"
authorTomas Matheson <tomas.matheson@arm.com>
Fri, 9 Dec 2022 11:36:06 +0000 (11:36 +0000)
committerTomas Matheson <tomas.matheson@arm.com>
Sat, 14 Jan 2023 14:43:38 +0000 (14:43 +0000)
Reworked after several other major changes to the TargetParser since
this was reverted. Combined with several other changes.

Inline calls for the following macros and delete AArch64TargetParser.def:
 AARCH64_ARCH,  AARCH64_CPU_NAME,  AARCH64_CPU_ALIAS, AARCH64_ARCH_EXT_NAME

Squashed changes from D139278 and D139102.

Differential Revision: https://reviews.llvm.org/D138792

13 files changed:
clang/lib/Basic/Targets/AArch64.cpp
clang/lib/Basic/Targets/AArch64.h
clang/lib/Driver/ToolChains/Arch/AArch64.cpp
clang/test/Preprocessor/aarch64-target-features.c
flang/test/Driver/target-cpu-features.f90
lldb/test/Shell/Commands/command-disassemble-aarch64-extensions.s
llvm/include/llvm/ADT/StringRef.h
llvm/include/llvm/Support/VersionTuple.h
llvm/include/llvm/TargetParser/AArch64TargetParser.def [deleted file]
llvm/include/llvm/TargetParser/AArch64TargetParser.h
llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
llvm/lib/TargetParser/AArch64TargetParser.cpp
llvm/unittests/TargetParser/TargetParserTest.cpp

index a4b27bb..d7893c1 100644 (file)
@@ -47,69 +47,58 @@ static constexpr Builtin::Info BuiltinInfo[] = {
 #include "clang/Basic/BuiltinsAArch64.def"
 };
 
-static StringRef getArchVersionString(llvm::AArch64::ArchKind Kind) {
-  switch (Kind) {
-  case llvm::AArch64::ArchKind::ARMV9A:
-  case llvm::AArch64::ArchKind::ARMV9_1A:
-  case llvm::AArch64::ArchKind::ARMV9_2A:
-  case llvm::AArch64::ArchKind::ARMV9_3A:
-  case llvm::AArch64::ArchKind::ARMV9_4A:
-    return "9";
-  default:
-    return "8";
-  }
-}
-
 void AArch64TargetInfo::setArchFeatures() {
-  switch (ArchKind) {
-  case llvm::AArch64::ArchKind::ARMV8_9A:
-  case llvm::AArch64::ArchKind::ARMV8_8A:
-  case llvm::AArch64::ArchKind::ARMV8_7A:
-    HasWFxT = true;
-    LLVM_FALLTHROUGH;
-  case llvm::AArch64::ArchKind::ARMV8_6A:
-    HasBFloat16 = true;
-    HasMatMul = true;
-    LLVM_FALLTHROUGH;
-  case llvm::AArch64::ArchKind::ARMV8_5A:
-    HasAlternativeNZCV = true;
-    HasFRInt3264 = true;
-    HasSSBS = true;
-    HasSB = true;
-    HasPredRes = true;
-    HasBTI = true;
-    LLVM_FALLTHROUGH;
-  case llvm::AArch64::ArchKind::ARMV8_4A:
+  if (*ArchInfo == llvm::AArch64::ARMV8R) {
     HasDotProd = true;
     HasDIT = true;
     HasFlagM = true;
-    LLVM_FALLTHROUGH;
-  case llvm::AArch64::ArchKind::ARMV8_3A:
     HasRCPC = true;
     FPU |= NeonMode;
-    LLVM_FALLTHROUGH;
-  case llvm::AArch64::ArchKind::ARMV8_2A:
     HasCCPP = true;
-    LLVM_FALLTHROUGH;
-  case llvm::AArch64::ArchKind::ARMV8_1A:
     HasCRC = true;
     HasLSE = true;
     HasRDM = true;
-    return;
-  default:
-    break;
-  }
-  switch (ArchKind) {
-  case llvm::AArch64::ArchKind::ARMV9_4A:
-  case llvm::AArch64::ArchKind::ARMV9_3A:
-  case llvm::AArch64::ArchKind::ARMV9_2A:
-    HasWFxT = true;
-    LLVM_FALLTHROUGH;
-  case llvm::AArch64::ArchKind::ARMV9_1A:
-    HasBFloat16 = true;
-    HasMatMul = true;
-    LLVM_FALLTHROUGH;
-  case llvm::AArch64::ArchKind::ARMV9A:
+  } else if (ArchInfo->Version.getMajor() == 8) {
+    if (ArchInfo->Version.getMinor() >= 7) {
+      HasWFxT = true;
+    }
+    if (ArchInfo->Version.getMinor() >= 6) {
+      HasBFloat16 = true;
+      HasMatMul = true;
+    }
+    if (ArchInfo->Version.getMinor() >= 5) {
+      HasAlternativeNZCV = true;
+      HasFRInt3264 = true;
+      HasSSBS = true;
+      HasSB = true;
+      HasPredRes = true;
+      HasBTI = true;
+    }
+    if (ArchInfo->Version.getMinor() >= 4) {
+      HasDotProd = true;
+      HasDIT = true;
+      HasFlagM = true;
+    }
+    if (ArchInfo->Version.getMinor() >= 3) {
+      HasRCPC = true;
+      FPU |= NeonMode;
+    }
+    if (ArchInfo->Version.getMinor() >= 2) {
+      HasCCPP = true;
+    }
+    if (ArchInfo->Version.getMinor() >= 1) {
+      HasCRC = true;
+      HasLSE = true;
+      HasRDM = true;
+    }
+  } else if (ArchInfo->Version.getMajor() == 9) {
+    if (ArchInfo->Version.getMinor() >= 2) {
+      HasWFxT = true;
+    }
+    if (ArchInfo->Version.getMinor() >= 1) {
+      HasBFloat16 = true;
+      HasMatMul = true;
+    }
     FPU |= SveMode;
     HasSVE2 = true;
     HasFullFP16 = true;
@@ -128,29 +117,6 @@ void AArch64TargetInfo::setArchFeatures() {
     HasCRC = true;
     HasLSE = true;
     HasRDM = true;
-    return;
-  default:
-    break;
-  }
-  if (ArchKind == llvm::AArch64::ArchKind::ARMV8R) {
-    HasDotProd = true;
-    HasDIT = true;
-    HasFlagM = true;
-    HasRCPC = true;
-    FPU |= NeonMode;
-    HasCCPP = true;
-    HasCRC = true;
-    HasLSE = true;
-    HasRDM = true;
-  }
-}
-
-StringRef AArch64TargetInfo::getArchProfile() const {
-  switch (ArchKind) {
-  case llvm::AArch64::ArchKind::ARMV8R:
-    return "R";
-  default:
-    return "A";
   }
 }
 
@@ -257,7 +223,7 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
 
 bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
   return Name == "generic" ||
-         llvm::AArch64::parseCPUArch(Name) != llvm::AArch64::ArchKind::INVALID;
+         llvm::AArch64::parseCpu(Name).Arch != llvm::AArch64::INVALID;
 }
 
 bool AArch64TargetInfo::setCPU(const std::string &Name) {
@@ -387,8 +353,10 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
 
   // ACLE predefines. Many can only have one possible value on v8 AArch64.
   Builder.defineMacro("__ARM_ACLE", "200");
-  Builder.defineMacro("__ARM_ARCH", getArchVersionString(ArchKind));
-  Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + getArchProfile() + "'");
+  Builder.defineMacro("__ARM_ARCH",
+                      std::to_string(ArchInfo->Version.getMajor()));
+  Builder.defineMacro("__ARM_ARCH_PROFILE",
+                      std::string("'") + (char)ArchInfo->Profile + "'");
 
   Builder.defineMacro("__ARM_64BIT_STATE", "1");
   Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
@@ -559,52 +527,34 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
   if (HasD128)
     Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1");
 
-  switch (ArchKind) {
-  default:
-    break;
-  case llvm::AArch64::ArchKind::ARMV8_1A:
+  if (*ArchInfo == llvm::AArch64::ARMV8_1A)
     getTargetDefinesARMV81A(Opts, Builder);
-    break;
-  case llvm::AArch64::ArchKind::ARMV8_2A:
+  else if (*ArchInfo == llvm::AArch64::ARMV8_2A)
     getTargetDefinesARMV82A(Opts, Builder);
-    break;
-  case llvm::AArch64::ArchKind::ARMV8_3A:
+  else if (*ArchInfo == llvm::AArch64::ARMV8_3A)
     getTargetDefinesARMV83A(Opts, Builder);
-    break;
-  case llvm::AArch64::ArchKind::ARMV8_4A:
+  else if (*ArchInfo == llvm::AArch64::ARMV8_4A)
     getTargetDefinesARMV84A(Opts, Builder);
-    break;
-  case llvm::AArch64::ArchKind::ARMV8_5A:
+  else if (*ArchInfo == llvm::AArch64::ARMV8_5A)
     getTargetDefinesARMV85A(Opts, Builder);
-    break;
-  case llvm::AArch64::ArchKind::ARMV8_6A:
+  else if (*ArchInfo == llvm::AArch64::ARMV8_6A)
     getTargetDefinesARMV86A(Opts, Builder);
-    break;
-  case llvm::AArch64::ArchKind::ARMV8_7A:
+  else if (*ArchInfo == llvm::AArch64::ARMV8_7A)
     getTargetDefinesARMV87A(Opts, Builder);
-    break;
-  case llvm::AArch64::ArchKind::ARMV8_8A:
+  else if (*ArchInfo == llvm::AArch64::ARMV8_8A)
     getTargetDefinesARMV88A(Opts, Builder);
-    break;
-  case llvm::AArch64::ArchKind::ARMV8_9A:
+  else if (*ArchInfo == llvm::AArch64::ARMV8_9A)
     getTargetDefinesARMV89A(Opts, Builder);
-    break;
-  case llvm::AArch64::ArchKind::ARMV9A:
+  else if (*ArchInfo == llvm::AArch64::ARMV9A)
     getTargetDefinesARMV9A(Opts, Builder);
-    break;
-  case llvm::AArch64::ArchKind::ARMV9_1A:
+  else if (*ArchInfo == llvm::AArch64::ARMV9_1A)
     getTargetDefinesARMV91A(Opts, Builder);
-    break;
-  case llvm::AArch64::ArchKind::ARMV9_2A:
+  else if (*ArchInfo == llvm::AArch64::ARMV9_2A)
     getTargetDefinesARMV92A(Opts, Builder);
-    break;
-  case llvm::AArch64::ArchKind::ARMV9_3A:
+  else if (*ArchInfo == llvm::AArch64::ARMV9_3A)
     getTargetDefinesARMV93A(Opts, Builder);
-    break;
-  case llvm::AArch64::ArchKind::ARMV9_4A:
+  else if (*ArchInfo == llvm::AArch64::ARMV9_4A)
     getTargetDefinesARMV94A(Opts, Builder);
-    break;
-  }
 
   // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
   Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
@@ -645,42 +595,34 @@ AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
 unsigned AArch64TargetInfo::multiVersionSortPriority(StringRef Name) const {
   if (Name == "default")
     return 0;
-  unsigned Priority = llvm::StringSwitch<unsigned>(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<std::string>(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<unsigned>(FeatureStr)
-#define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE, FMV_ID,           \
-                              DEP_FEATURES, FMV_PRIORITY)                      \
-  .Case(NAME, llvm::AArch64::FEAT_##FMV_ID)
-#include "llvm/TargetParser/AArch64TargetParser.def"
-                      .Default(llvm::AArch64::FEAT_MAX);
-  return Feat != llvm::AArch64::FEAT_MAX;
+  for (const auto &E : llvm::AArch64::Extensions)
+    if (FeatureStr == E.Name)
+      return true;
+  return false;
 }
 
 bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
@@ -736,24 +678,21 @@ bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
 void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &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<StringRef> CPUFeats;
   if (llvm::AArch64::getExtensionFeatures(Extensions, CPUFeats)) {
     for (auto F : CPUFeats) {
@@ -899,38 +838,51 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
     if (Feature == "+strict-align")
       HasUnaligned = false;
     // All predecessor archs are added but select the latest one for ArchKind.
-    if (Feature == "+v8a" && ArchKind < llvm::AArch64::ArchKind::ARMV8A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV8A;
-    if (Feature == "+v8.1a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_1A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
-    if (Feature == "+v8.2a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_2A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
-    if (Feature == "+v8.3a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_3A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV8_3A;
-    if (Feature == "+v8.4a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_4A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV8_4A;
-    if (Feature == "+v8.5a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_5A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV8_5A;
-    if (Feature == "+v8.6a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_6A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV8_6A;
-    if (Feature == "+v8.7a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_7A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV8_7A;
-    if (Feature == "+v8.8a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_8A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV8_8A;
-    if (Feature == "+v8.9a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_9A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV8_9A;
-    if (Feature == "+v9a" && ArchKind < llvm::AArch64::ArchKind::ARMV9A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV9A;
-    if (Feature == "+v9.1a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_1A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV9_1A;
-    if (Feature == "+v9.2a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_2A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV9_2A;
-    if (Feature == "+v9.3a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_3A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV9_3A;
-    if (Feature == "+v9.4a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_4A)
-      ArchKind = llvm::AArch64::ArchKind::ARMV9_4A;
+    if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)
+      ArchInfo = &llvm::AArch64::ARMV8A;
+    if (Feature == "+v8.1a" &&
+        ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version)
+      ArchInfo = &llvm::AArch64::ARMV8_1A;
+    if (Feature == "+v8.2a" &&
+        ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version)
+      ArchInfo = &llvm::AArch64::ARMV8_2A;
+    if (Feature == "+v8.3a" &&
+        ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version)
+      ArchInfo = &llvm::AArch64::ARMV8_3A;
+    if (Feature == "+v8.4a" &&
+        ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version)
+      ArchInfo = &llvm::AArch64::ARMV8_4A;
+    if (Feature == "+v8.5a" &&
+        ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version)
+      ArchInfo = &llvm::AArch64::ARMV8_5A;
+    if (Feature == "+v8.6a" &&
+        ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version)
+      ArchInfo = &llvm::AArch64::ARMV8_6A;
+    if (Feature == "+v8.7a" &&
+        ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version)
+      ArchInfo = &llvm::AArch64::ARMV8_7A;
+    if (Feature == "+v8.8a" &&
+        ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version)
+      ArchInfo = &llvm::AArch64::ARMV8_8A;
+    if (Feature == "+v8.9a" &&
+        ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version)
+      ArchInfo = &llvm::AArch64::ARMV8_9A;
+    if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version)
+      ArchInfo = &llvm::AArch64::ARMV9A;
+    if (Feature == "+v9.1a" &&
+        ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version)
+      ArchInfo = &llvm::AArch64::ARMV9_1A;
+    if (Feature == "+v9.2a" &&
+        ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version)
+      ArchInfo = &llvm::AArch64::ARMV9_2A;
+    if (Feature == "+v9.3a" &&
+        ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version)
+      ArchInfo = &llvm::AArch64::ARMV9_3A;
+    if (Feature == "+v9.4a" &&
+        ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version)
+      ArchInfo = &llvm::AArch64::ARMV9_4A;
     if (Feature == "+v8r")
-      ArchKind = llvm::AArch64::ArchKind::ARMV8R;
+      ArchInfo = &llvm::AArch64::ARMV8R;
     if (Feature == "+fullfp16") {
       FPU |= NeonMode;
       HasFullFP16 = true;
@@ -998,8 +950,8 @@ bool AArch64TargetInfo::initFeatureMap(
     const std::vector<std::string> &FeaturesVec) const {
   std::vector<std::string> 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<StringRef> CPUFeats;
     llvm::AArch64::getExtensionFeatures(Exts, CPUFeats);
@@ -1082,13 +1034,13 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
       FoundArch = true;
       std::pair<StringRef, StringRef> 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=")) {
index 55e8a63..95edf69 100644 (file)
@@ -76,10 +76,9 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
   bool HasNoSVE = false;
   bool HasFMV = true;
 
-  llvm::AArch64::ArchKind ArchKind = llvm::AArch64::ArchKind::INVALID;
+  const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A;
 
   std::string ABI;
-  StringRef getArchProfile() const;
 
 public:
   AArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
index 2a12693..fcbf2e0 100644 (file)
@@ -70,7 +70,7 @@ std::string aarch64::getAArch64TargetCPU(const ArgList &Args,
 // Decode AArch64 features from string like +[no]featureA+[no]featureB+...
 static bool DecodeAArch64Features(const Driver &D, StringRef text,
                                   std::vector<StringRef> &Features,
-                                  llvm::AArch64::ArchKind ArchKind) {
+                                  const llvm::AArch64::ArchInfo &ArchInfo) {
   SmallVector<StringRef, 8> Split;
   text.split(Split, StringRef("+"), -1, false);
 
@@ -104,14 +104,14 @@ static bool DecodeAArch64Features(const Driver &D, StringRef text,
 
     // +sve implies +f32mm if the base architecture is >= v8.6A (except v9A)
     // It isn't the case in general that sve implies both f64mm and f32mm
-    if ((ArchKind == llvm::AArch64::ArchKind::ARMV8_6A ||
-         ArchKind == llvm::AArch64::ArchKind::ARMV8_7A ||
-         ArchKind == llvm::AArch64::ArchKind::ARMV8_8A ||
-         ArchKind == llvm::AArch64::ArchKind::ARMV8_9A ||
-         ArchKind == llvm::AArch64::ArchKind::ARMV9_1A ||
-         ArchKind == llvm::AArch64::ArchKind::ARMV9_2A ||
-         ArchKind == llvm::AArch64::ArchKind::ARMV9_3A ||
-         ArchKind == llvm::AArch64::ArchKind::ARMV9_4A) &&
+    if ((ArchInfo == llvm::AArch64::ARMV8_6A ||
+         ArchInfo == llvm::AArch64::ARMV8_7A ||
+         ArchInfo == llvm::AArch64::ARMV8_8A ||
+         ArchInfo == llvm::AArch64::ARMV8_9A ||
+         ArchInfo == llvm::AArch64::ARMV9_1A ||
+         ArchInfo == llvm::AArch64::ARMV9_2A ||
+         ArchInfo == llvm::AArch64::ARMV9_3A ||
+         ArchInfo == llvm::AArch64::ARMV9_4A) &&
         Feature == "sve")
       Features.push_back("+f32mm");
   }
@@ -123,10 +123,8 @@ static bool DecodeAArch64Features(const Driver &D, StringRef text,
 static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
                               std::vector<StringRef> &Features) {
   std::pair<StringRef, StringRef> Split = Mcpu.split("+");
-  CPU = Split.first;
-  llvm::AArch64::ArchKind ArchKind = llvm::AArch64::ArchKind::ARMV8A;
-
-  CPU = llvm::AArch64::resolveCPUAlias(CPU);
+  const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A;
+  CPU = llvm::AArch64::resolveCPUAlias(Split.first);
 
   if (CPU == "native")
     CPU = llvm::sys::getHostCPUName();
@@ -134,21 +132,21 @@ static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
   if (CPU == "generic") {
     Features.push_back("+neon");
   } else {
-    ArchKind = llvm::AArch64::parseCPUArch(CPU);
-    if (ArchKind == llvm::AArch64::ArchKind::INVALID)
+    ArchInfo = &llvm::AArch64::parseCpu(CPU).Arch;
+    if (*ArchInfo == llvm::AArch64::INVALID)
       return false;
-    Features.push_back(llvm::AArch64::getArchFeature(ArchKind));
+    Features.push_back(ArchInfo->ArchFeature);
 
-    uint64_t Extension = llvm::AArch64::getDefaultExtensions(CPU, ArchKind);
+    uint64_t Extension = llvm::AArch64::getDefaultExtensions(CPU, *ArchInfo);
     if (!llvm::AArch64::getExtensionFeatures(Extension, Features))
       return false;
-   }
+  }
 
-   if (Split.second.size() &&
-       !DecodeAArch64Features(D, Split.second, Features, ArchKind))
-     return false;
+  if (Split.second.size() &&
+      !DecodeAArch64Features(D, Split.second, Features, *ArchInfo))
+    return false;
 
-   return true;
+  return true;
 }
 
 static bool
@@ -158,25 +156,26 @@ getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
   std::string MarchLowerCase = March.lower();
   std::pair<StringRef, StringRef> 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;
index 3ec31e1..8ad5b3a 100644 (file)
 // 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
index 985a13d..0270448 100644 (file)
@@ -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"
index 480ed6b..e154f54 100644 (file)
 .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
index 032f42a..9fea390 100644 (file)
@@ -561,7 +561,8 @@ namespace llvm {
     /// \param N The number of characters to included in the substring. If N
     /// exceeds the number of characters remaining in the string, the string
     /// suffix (starting with \p Start) will be returned.
-    [[nodiscard]] StringRef substr(size_t Start, size_t N = npos) const {
+    [[nodiscard]] constexpr StringRef substr(size_t Start,
+                                             size_t N = npos) const {
       Start = std::min(Start, Length);
       return StringRef(Data + Start, std::min(N, Length - Start));
     }
index 1118754..828a6db 100644 (file)
@@ -41,24 +41,25 @@ class VersionTuple {
   unsigned HasBuild : 1;
 
 public:
-  VersionTuple()
+  constexpr VersionTuple()
       : Major(0), Minor(0), HasMinor(false), Subminor(0), HasSubminor(false),
         Build(0), HasBuild(false) {}
 
-  explicit VersionTuple(unsigned Major)
+  explicit constexpr VersionTuple(unsigned Major)
       : Major(Major), Minor(0), HasMinor(false), Subminor(0),
         HasSubminor(false), Build(0), HasBuild(false) {}
 
-  explicit VersionTuple(unsigned Major, unsigned Minor)
+  explicit constexpr VersionTuple(unsigned Major, unsigned Minor)
       : Major(Major), Minor(Minor), HasMinor(true), Subminor(0),
         HasSubminor(false), Build(0), HasBuild(false) {}
 
-  explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor)
+  explicit constexpr VersionTuple(unsigned Major, unsigned Minor,
+                                  unsigned Subminor)
       : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor),
         HasSubminor(true), Build(0), HasBuild(false) {}
 
-  explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor,
-                        unsigned Build)
+  explicit constexpr VersionTuple(unsigned Major, unsigned Minor,
+                                  unsigned Subminor, unsigned Build)
       : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor),
         HasSubminor(true), Build(Build), HasBuild(true) {}
 
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.def b/llvm/include/llvm/TargetParser/AArch64TargetParser.def
deleted file mode 100644 (file)
index 570172a..0000000
+++ /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
index 309e355..0ffec6b 100644 (file)
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/VersionTuple.h"
+#include <array>
 #include <vector>
 
-// FIXME:This should be made into class design,to avoid dupplication.
 namespace llvm {
 
 class Triple;
@@ -149,103 +150,356 @@ enum ArchExtKind : uint64_t {
 };
 // clang-format on
 
-enum class ArchKind {
-#define AARCH64_ARCH(NAME, ID, ARCH_FEATURE, ARCH_BASE_EXT) ID,
-#include "AArch64TargetParser.def"
+// Represents an extension that can be enabled with -march=<arch>+<extension>.
+// 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<const ArchInfo *, 17> 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<unsigned>(Kind);
-    Kind = static_cast<ArchKind>(--KindAsInteger);
-  }
-  return Kind;
-}
+inline constexpr CpuAlias CpuAliases[] = {{"grace", "neoverse-v2"}};
 
 bool getExtensionFeatures(uint64_t Extensions,
                           std::vector<StringRef> &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<StringRef> &Values);
 
@@ -255,4 +509,4 @@ uint64_t getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs);
 } // namespace AArch64
 } // namespace llvm
 
-#endif
+#endif
\ No newline at end of file
index 7d52185..1ef3ada 100644 (file)
@@ -6822,67 +6822,48 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
   return false;
 }
 
-static void ExpandCryptoAEK(AArch64::ArchKind ArchKind,
+static void ExpandCryptoAEK(const AArch64::ArchInfo &ArchInfo,
                             SmallVector<StringRef, 4> &RequestedExtensions) {
   const bool NoCrypto = llvm::is_contained(RequestedExtensions, "nocrypto");
   const bool Crypto = llvm::is_contained(RequestedExtensions, "crypto");
 
   if (!NoCrypto && Crypto) {
-    switch (ArchKind) {
-    default:
-      // Map 'generic' (and others) to sha2 and aes, because
-      // that was the traditional meaning of crypto.
-    case AArch64::ArchKind::ARMV8_1A:
-    case AArch64::ArchKind::ARMV8_2A:
-    case AArch64::ArchKind::ARMV8_3A:
+    // Map 'generic' (and others) to sha2 and aes, because
+    // that was the traditional meaning of crypto.
+    if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
+        ArchInfo == AArch64::ARMV8_3A) {
       RequestedExtensions.push_back("sha2");
       RequestedExtensions.push_back("aes");
-      break;
-    case AArch64::ArchKind::ARMV8_4A:
-    case AArch64::ArchKind::ARMV8_5A:
-    case AArch64::ArchKind::ARMV8_6A:
-    case AArch64::ArchKind::ARMV8_7A:
-    case AArch64::ArchKind::ARMV8_8A:
-    case AArch64::ArchKind::ARMV8_9A:
-    case AArch64::ArchKind::ARMV9A:
-    case AArch64::ArchKind::ARMV9_1A:
-    case AArch64::ArchKind::ARMV9_2A:
-    case AArch64::ArchKind::ARMV9_3A:
-    case AArch64::ArchKind::ARMV9_4A:
-    case AArch64::ArchKind::ARMV8R:
+    }
+    if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
+        ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
+        ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
+        ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
+        ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
+        ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
       RequestedExtensions.push_back("sm4");
       RequestedExtensions.push_back("sha3");
       RequestedExtensions.push_back("sha2");
       RequestedExtensions.push_back("aes");
-      break;
     }
   } else if (NoCrypto) {
-    switch (ArchKind) {
-    default:
-      // Map 'generic' (and others) to sha2 and aes, because
-      // that was the traditional meaning of crypto.
-    case AArch64::ArchKind::ARMV8_1A:
-    case AArch64::ArchKind::ARMV8_2A:
-    case AArch64::ArchKind::ARMV8_3A:
+    // Map 'generic' (and others) to sha2 and aes, because
+    // that was the traditional meaning of crypto.
+    if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
+        ArchInfo == AArch64::ARMV8_3A) {
       RequestedExtensions.push_back("nosha2");
       RequestedExtensions.push_back("noaes");
-      break;
-    case AArch64::ArchKind::ARMV8_4A:
-    case AArch64::ArchKind::ARMV8_5A:
-    case AArch64::ArchKind::ARMV8_6A:
-    case AArch64::ArchKind::ARMV8_7A:
-    case AArch64::ArchKind::ARMV8_8A:
-    case AArch64::ArchKind::ARMV8_9A:
-    case AArch64::ArchKind::ARMV9A:
-    case AArch64::ArchKind::ARMV9_1A:
-    case AArch64::ArchKind::ARMV9_2A:
-    case AArch64::ArchKind::ARMV9_3A:
-    case AArch64::ArchKind::ARMV9_4A:
+    }
+    if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
+        ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
+        ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
+        ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
+        ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
+        ArchInfo == AArch64::ARMV9_4A) {
       RequestedExtensions.push_back("nosm4");
       RequestedExtensions.push_back("nosha3");
       RequestedExtensions.push_back("nosha2");
       RequestedExtensions.push_back("noaes");
-      break;
     }
   }
 }
@@ -6896,8 +6877,8 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
   std::tie(Arch, ExtensionString) =
       getParser().parseStringToEndOfStatement().trim().split('+');
 
-  AArch64::ArchKind ID = AArch64::parseArch(Arch);
-  if (ID == AArch64::ArchKind::INVALID)
+  const AArch64::ArchInfo &ArchInfo = AArch64::parseArch(Arch);
+  if (ArchInfo == AArch64::INVALID)
     return Error(ArchLoc, "unknown arch name");
 
   if (parseToken(AsmToken::EndOfStatement))
@@ -6905,9 +6886,9 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
 
   // Get the architecture and extension features.
   std::vector<StringRef> 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<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
@@ -6918,7 +6899,7 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
   if (!ExtensionString.empty())
     ExtensionString.split(RequestedExtensions, '+');
 
-  ExpandCryptoAEK(ID, RequestedExtensions);
+  ExpandCryptoAEK(ArchInfo, RequestedExtensions);
 
   FeatureBitset Features = STI.getFeatureBits();
   for (auto Name : RequestedExtensions) {
@@ -7014,7 +6995,7 @@ bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
   STI.setDefaultFeatures(CPU, /*TuneCPU*/ CPU, "");
   CurLoc = incrementLoc(CurLoc, CPU.size());
 
-  ExpandCryptoAEK(llvm::AArch64::getCPUArchKind(CPU), RequestedExtensions);
+  ExpandCryptoAEK(llvm::AArch64::getArchForCpu(CPU), RequestedExtensions);
 
   for (auto Name : RequestedExtensions) {
     // Advance source location past '+'.
index baa6cbf..41d5c25 100644 (file)
@@ -25,131 +25,95 @@ static unsigned checkArchVersion(llvm::StringRef Arch) {
   return 0;
 }
 
-uint64_t AArch64::getDefaultExtensions(StringRef CPU, AArch64::ArchKind AK) {
+uint64_t AArch64::getDefaultExtensions(StringRef CPU,
+                                       const AArch64::ArchInfo &AI) {
   if (CPU == "generic")
-    return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
-
-  return StringSwitch<uint64_t>(CPU)
-#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_EXT)                                \
-  .Case(NAME, AArch64ARCHNames[static_cast<unsigned>(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<std::string>(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<AArch64::ArchKind>(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<StringRef> FeatureStrs) {
   uint64_t FeaturesMask = 0;
   for (const StringRef &FeatureStr : FeatureStrs) {
-    unsigned Feature = StringSwitch<unsigned>(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<StringRef> &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<StringRef>(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<unsigned>(AK)].ArchFeature;
-}
-
-StringRef AArch64::getArchName(AArch64::ArchKind AK) {
-  return AArch64ARCHNames[static_cast<unsigned>(AK)].Name;
-}
-
-StringRef AArch64::getSubArch(AArch64::ArchKind AK) {
-  return AArch64ARCHNames[static_cast<unsigned>(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<unsigned>(AArch64::ArchKind::ARMV8_5A);
-  AK_v8 += static_cast<unsigned>(AK) -
-           static_cast<unsigned>(AArch64::ArchKind::ARMV9A);
-  return static_cast<AArch64::ArchKind>(AK_v8);
-}
-
 void AArch64::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
-  for (const auto &Arch : AArch64CPUNames) {
-    if (Arch.ArchID != ArchKind::INVALID)
-      Values.push_back(Arch.Name);
-  }
+  for (const auto &C : CpuInfos)
+    if (C.Arch != INVALID)
+      Values.push_back(C.Name);
 
-  for (const auto &Alias: AArch64CPUAliases)
+  for (const auto &Alias : CpuAliases)
     Values.push_back(Alias.Alias);
 }
 
@@ -159,39 +123,37 @@ bool AArch64::isX18ReservedByDefault(const Triple &TT) {
 }
 
 // Allows partial match, ex. "v8a" matches "armv8a".
-AArch64::ArchKind AArch64::parseArch(StringRef Arch) {
+const AArch64::ArchInfo &AArch64::parseArch(StringRef Arch) {
   Arch = llvm::ARM::getCanonicalArchName(Arch);
   if (checkArchVersion(Arch) < 8)
-    return ArchKind::INVALID;
+    return AArch64::INVALID;
 
   StringRef Syn = llvm::ARM::getArchSynonym(Arch);
-  for (const auto &A : AArch64ARCHNames) {
-    if (A.Name.endswith(Syn))
-      return A.ID;
+  for (const auto *A : ArchInfos) {
+    if (A->Name.endswith(Syn))
+      return *A;
   }
-  return ArchKind::INVALID;
+  return AArch64::INVALID;
 }
 
 AArch64::ArchExtKind AArch64::parseArchExt(StringRef ArchExt) {
-  for (const auto &A : AArch64ARCHExtNames) {
+  for (const auto &A : Extensions) {
     if (ArchExt == A.Name)
       return static_cast<ArchExtKind>(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");
 }
index 69e6a73..7bf20ef 100644 (file)
@@ -953,11 +953,11 @@ class AArch64CPUTestFixture
 TEST_P(AArch64CPUTestFixture, testAArch64CPU) {
   ARMCPUTestParams params = GetParam();
 
-  AArch64::ArchKind AK = AArch64::parseCPUArch(params.CPUName);
-  EXPECT_EQ(params.ExpectedArch, AArch64::getArchName(AK));
+  const AArch64::ArchInfo &AI = AArch64::parseCpu(params.CPUName).Arch;
+  EXPECT_EQ(params.ExpectedArch, AI.Name);
 
   uint64_t default_extensions =
-      AArch64::getDefaultExtensions(params.CPUName, AK);
+      AArch64::getDefaultExtensions(params.CPUName, AI);
   EXPECT_PRED_FORMAT2(AssertSameExtensionFlags<ARM::ISAKind::AARCH64>,
                       params.ExpectedFlags, default_extensions);
 }
@@ -1403,14 +1403,14 @@ TEST(TargetParserTest, testAArch64CPUArchList) {
   // valid, and match the expected 'magic' count.
   EXPECT_EQ(List.size(), NumAArch64CPUArchs);
   for(StringRef CPU : List) {
-    EXPECT_NE(AArch64::parseCPUArch(CPU), AArch64::ArchKind::INVALID);
+    EXPECT_NE(AArch64::parseCpu(CPU).Arch, AArch64::INVALID);
   }
 }
 
 bool testAArch64Arch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch,
                      unsigned ArchAttr) {
-  AArch64::ArchKind AK = AArch64::parseArch(Arch);
-  return AK != AArch64::ArchKind::INVALID;
+  const AArch64::ArchInfo &AI = AArch64::parseArch(Arch);
+  return AI != AArch64::INVALID;
 }
 
 TEST(TargetParserTest, testAArch64Arch) {
@@ -1446,148 +1446,81 @@ TEST(TargetParserTest, testAArch64Arch) {
                               ARMBuildAttrs::CPUArch::v8_A));
 }
 
-bool testAArch64Extension(StringRef CPUName, AArch64::ArchKind AK,
+bool testAArch64Extension(StringRef CPUName, const AArch64::ArchInfo &AI,
                           StringRef ArchExt) {
-  return AArch64::getDefaultExtensions(CPUName, AK) &
+  return AArch64::getDefaultExtensions(CPUName, AI) &
          AArch64::parseArchExt(ArchExt);
 }
 
 TEST(TargetParserTest, testAArch64Extension) {
-  EXPECT_FALSE(testAArch64Extension("cortex-a34",
-                                    AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_FALSE(testAArch64Extension("cortex-a35",
-                                    AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_FALSE(testAArch64Extension("cortex-a53",
-                                    AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_TRUE(testAArch64Extension("cortex-a55",
-                                    AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_TRUE(testAArch64Extension("cortex-a55",
-                                    AArch64::ArchKind::INVALID, "fp16"));
-  EXPECT_FALSE(testAArch64Extension("cortex-a55",
-                                    AArch64::ArchKind::INVALID, "fp16fml"));
-  EXPECT_TRUE(testAArch64Extension("cortex-a55",
-                                    AArch64::ArchKind::INVALID, "dotprod"));
-  EXPECT_FALSE(testAArch64Extension("cortex-a57",
-                                    AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_FALSE(testAArch64Extension("cortex-a72",
-                                    AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_FALSE(testAArch64Extension("cortex-a73",
-                                    AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_TRUE(testAArch64Extension("cortex-a75",
-                                    AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_TRUE(testAArch64Extension("cortex-a75",
-                                    AArch64::ArchKind::INVALID, "fp16"));
-  EXPECT_FALSE(testAArch64Extension("cortex-a75",
-                                    AArch64::ArchKind::INVALID, "fp16fml"));
-  EXPECT_TRUE(testAArch64Extension("cortex-a75",
-                                   AArch64::ArchKind::INVALID, "dotprod"));
-  EXPECT_TRUE(testAArch64Extension("cortex-r82",
-                                   AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_TRUE(testAArch64Extension("cortex-r82",
-                                   AArch64::ArchKind::INVALID, "fp16"));
-  EXPECT_TRUE(testAArch64Extension("cortex-r82",
-                                   AArch64::ArchKind::INVALID, "fp16fml"));
-  EXPECT_TRUE(testAArch64Extension("cortex-r82",
-                                   AArch64::ArchKind::INVALID, "dotprod"));
-  EXPECT_TRUE(testAArch64Extension("cortex-r82",
-                                   AArch64::ArchKind::INVALID, "lse"));
-  EXPECT_FALSE(testAArch64Extension("cyclone",
-                                    AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_FALSE(testAArch64Extension("exynos-m3",
-                                    AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_TRUE(testAArch64Extension("exynos-m4",
-                                   AArch64::ArchKind::INVALID, "dotprod"));
-  EXPECT_TRUE(testAArch64Extension("exynos-m4",
-                                   AArch64::ArchKind::INVALID, "fp16"));
-  EXPECT_TRUE(testAArch64Extension("exynos-m4",
-                                   AArch64::ArchKind::INVALID, "lse"));
-  EXPECT_TRUE(testAArch64Extension("exynos-m4",
-                                   AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_TRUE(testAArch64Extension("exynos-m4",
-                                   AArch64::ArchKind::INVALID, "rdm"));
-  EXPECT_TRUE(testAArch64Extension("exynos-m5",
-                                   AArch64::ArchKind::INVALID, "dotprod"));
-  EXPECT_TRUE(testAArch64Extension("exynos-m5",
-                                   AArch64::ArchKind::INVALID, "fp16"));
-  EXPECT_TRUE(testAArch64Extension("exynos-m5",
-                                   AArch64::ArchKind::INVALID, "lse"));
-  EXPECT_TRUE(testAArch64Extension("exynos-m5",
-                                   AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_TRUE(testAArch64Extension("exynos-m5",
-                                   AArch64::ArchKind::INVALID, "rdm"));
-  EXPECT_TRUE(testAArch64Extension("falkor",
-                                   AArch64::ArchKind::INVALID, "rdm"));
-  EXPECT_FALSE(testAArch64Extension("kryo",
-                                    AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_TRUE(testAArch64Extension("saphira",
-                                    AArch64::ArchKind::INVALID, "crc"));
-  EXPECT_TRUE(testAArch64Extension("saphira",
-                                    AArch64::ArchKind::INVALID, "lse"));
-  EXPECT_TRUE(testAArch64Extension("saphira",
-                                   AArch64::ArchKind::INVALID, "rdm"));
-  EXPECT_TRUE(testAArch64Extension("saphira",
-                                   AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_TRUE(testAArch64Extension("saphira",
-                                   AArch64::ArchKind::INVALID, "rcpc"));
-  EXPECT_TRUE(testAArch64Extension("saphira",
-                                   AArch64::ArchKind::INVALID, "profile"));
-  EXPECT_FALSE(testAArch64Extension("saphira",
-                                    AArch64::ArchKind::INVALID, "fp16"));
-  EXPECT_FALSE(testAArch64Extension("thunderx2t99",
-                                    AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_FALSE(testAArch64Extension("thunderx",
-                                    AArch64::ArchKind::INVALID, "lse"));
-  EXPECT_FALSE(testAArch64Extension("thunderxt81",
-                                    AArch64::ArchKind::INVALID, "lse"));
-  EXPECT_FALSE(testAArch64Extension("thunderxt83",
-                                    AArch64::ArchKind::INVALID, "lse"));
-  EXPECT_FALSE(testAArch64Extension("thunderxt88",
-                                    AArch64::ArchKind::INVALID, "lse"));
-  EXPECT_TRUE(testAArch64Extension("tsv110",
-                                   AArch64::ArchKind::INVALID, "crypto"));
-  EXPECT_FALSE(testAArch64Extension("tsv110",
-                                    AArch64::ArchKind::INVALID, "sha3"));
-  EXPECT_FALSE(testAArch64Extension("tsv110",
-                                    AArch64::ArchKind::INVALID, "sm4"));
-  EXPECT_TRUE(testAArch64Extension("tsv110",
-                                   AArch64::ArchKind::INVALID, "ras"));
-  EXPECT_TRUE(testAArch64Extension("tsv110",
-                                   AArch64::ArchKind::INVALID, "profile"));
-  EXPECT_TRUE(testAArch64Extension("tsv110",
-                                   AArch64::ArchKind::INVALID, "fp16"));
-  EXPECT_TRUE(testAArch64Extension("tsv110",
-                                   AArch64::ArchKind::INVALID, "fp16fml"));
-  EXPECT_TRUE(testAArch64Extension("tsv110",
-                                   AArch64::ArchKind::INVALID, "dotprod"));
-  EXPECT_TRUE(testAArch64Extension("a64fx",
-                                   AArch64::ArchKind::INVALID, "fp16"));
-  EXPECT_TRUE(testAArch64Extension("a64fx",
-                                   AArch64::ArchKind::INVALID, "sve"));
-  EXPECT_FALSE(testAArch64Extension("a64fx",
-                                   AArch64::ArchKind::INVALID, "sve2"));
-  EXPECT_TRUE(
-      testAArch64Extension("carmel", AArch64::ArchKind::INVALID, "crypto"));
-  EXPECT_TRUE(
-      testAArch64Extension("carmel", AArch64::ArchKind::INVALID, "fp16"));
-
-  EXPECT_FALSE(testAArch64Extension(
-      "generic", AArch64::ArchKind::ARMV8A, "ras"));
-  EXPECT_FALSE(testAArch64Extension(
-      "generic", AArch64::ArchKind::ARMV8_1A, "ras"));
-  EXPECT_FALSE(testAArch64Extension(
-      "generic", AArch64::ArchKind::ARMV8_2A, "profile"));
-  EXPECT_FALSE(testAArch64Extension(
-      "generic", AArch64::ArchKind::ARMV8_2A, "fp16"));
-  EXPECT_FALSE(testAArch64Extension(
-      "generic", AArch64::ArchKind::ARMV8_2A, "fp16fml"));
-  EXPECT_FALSE(testAArch64Extension(
-      "generic", AArch64::ArchKind::ARMV8_3A, "fp16"));
-  EXPECT_FALSE(testAArch64Extension(
-      "generic", AArch64::ArchKind::ARMV8_3A, "fp16fml"));
-  EXPECT_FALSE(testAArch64Extension(
-      "generic", AArch64::ArchKind::ARMV8_4A, "fp16"));
-  EXPECT_FALSE(testAArch64Extension(
-      "generic", AArch64::ArchKind::ARMV8_4A, "fp16fml"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a34", AArch64::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a35", AArch64::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a53", AArch64::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("cortex-a55", AArch64::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("cortex-a55", AArch64::INVALID, "fp16"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a55", AArch64::INVALID, "fp16fml"));
+  EXPECT_TRUE(testAArch64Extension("cortex-a55", AArch64::INVALID, "dotprod"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a57", AArch64::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a72", AArch64::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a73", AArch64::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("cortex-a75", AArch64::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("cortex-a75", AArch64::INVALID, "fp16"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a75", AArch64::INVALID, "fp16fml"));
+  EXPECT_TRUE(testAArch64Extension("cortex-a75", AArch64::INVALID, "dotprod"));
+  EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "fp16"));
+  EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "fp16fml"));
+  EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "dotprod"));
+  EXPECT_TRUE(testAArch64Extension("cortex-r82", AArch64::INVALID, "lse"));
+  EXPECT_FALSE(testAArch64Extension("cyclone", AArch64::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("exynos-m3", AArch64::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "dotprod"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "fp16"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "lse"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m4", AArch64::INVALID, "rdm"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "dotprod"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "fp16"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "lse"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m5", AArch64::INVALID, "rdm"));
+  EXPECT_TRUE(testAArch64Extension("falkor", AArch64::INVALID, "rdm"));
+  EXPECT_FALSE(testAArch64Extension("kryo", AArch64::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "crc"));
+  EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "lse"));
+  EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "rdm"));
+  EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "rcpc"));
+  EXPECT_TRUE(testAArch64Extension("saphira", AArch64::INVALID, "profile"));
+  EXPECT_FALSE(testAArch64Extension("saphira", AArch64::INVALID, "fp16"));
+  EXPECT_FALSE(testAArch64Extension("thunderx2t99", AArch64::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("thunderx", AArch64::INVALID, "lse"));
+  EXPECT_FALSE(testAArch64Extension("thunderxt81", AArch64::INVALID, "lse"));
+  EXPECT_FALSE(testAArch64Extension("thunderxt83", AArch64::INVALID, "lse"));
+  EXPECT_FALSE(testAArch64Extension("thunderxt88", AArch64::INVALID, "lse"));
+  EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "crypto"));
+  EXPECT_FALSE(testAArch64Extension("tsv110", AArch64::INVALID, "sha3"));
+  EXPECT_FALSE(testAArch64Extension("tsv110", AArch64::INVALID, "sm4"));
+  EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "profile"));
+  EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "fp16"));
+  EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "fp16fml"));
+  EXPECT_TRUE(testAArch64Extension("tsv110", AArch64::INVALID, "dotprod"));
+  EXPECT_TRUE(testAArch64Extension("a64fx", AArch64::INVALID, "fp16"));
+  EXPECT_TRUE(testAArch64Extension("a64fx", AArch64::INVALID, "sve"));
+  EXPECT_FALSE(testAArch64Extension("a64fx", AArch64::INVALID, "sve2"));
+  EXPECT_TRUE(testAArch64Extension("carmel", AArch64::INVALID, "crypto"));
+  EXPECT_TRUE(testAArch64Extension("carmel", AArch64::INVALID, "fp16"));
+
+  EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8A, "ras"));
+  EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_1A, "ras"));
+  EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_2A, "profile"));
+  EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_2A, "fp16"));
+  EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_2A, "fp16fml"));
+  EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_3A, "fp16"));
+  EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_3A, "fp16fml"));
+  EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_4A, "fp16"));
+  EXPECT_FALSE(testAArch64Extension("generic", AArch64::ARMV8_4A, "fp16fml"));
 }
 
 TEST(TargetParserTest, AArch64ExtensionFeatures) {
@@ -1691,44 +1624,81 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
 }
 
 TEST(TargetParserTest, AArch64ArchFeatures) {
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::INVALID), "+");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8A), "+v8a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_1A), "+v8.1a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_2A), "+v8.2a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_3A), "+v8.3a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_4A), "+v8.4a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_5A), "+v8.5a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_6A), "+v8.6a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_7A), "+v8.7a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_8A), "+v8.8a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8_9A), "+v8.9a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV9A), "+v9a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV9_1A), "+v9.1a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV9_2A), "+v9.2a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV9_3A), "+v9.3a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV9_4A), "+v9.4a");
-  EXPECT_EQ(AArch64::getArchFeature(AArch64::ArchKind::ARMV8R), "+v8r");
+  EXPECT_EQ(AArch64::INVALID.ArchFeature, "+");
+  EXPECT_EQ(AArch64::ARMV8A.ArchFeature, "+v8a");
+  EXPECT_EQ(AArch64::ARMV8_1A.ArchFeature, "+v8.1a");
+  EXPECT_EQ(AArch64::ARMV8_2A.ArchFeature, "+v8.2a");
+  EXPECT_EQ(AArch64::ARMV8_3A.ArchFeature, "+v8.3a");
+  EXPECT_EQ(AArch64::ARMV8_4A.ArchFeature, "+v8.4a");
+  EXPECT_EQ(AArch64::ARMV8_5A.ArchFeature, "+v8.5a");
+  EXPECT_EQ(AArch64::ARMV8_6A.ArchFeature, "+v8.6a");
+  EXPECT_EQ(AArch64::ARMV8_7A.ArchFeature, "+v8.7a");
+  EXPECT_EQ(AArch64::ARMV8_8A.ArchFeature, "+v8.8a");
+  EXPECT_EQ(AArch64::ARMV8_9A.ArchFeature, "+v8.9a");
+  EXPECT_EQ(AArch64::ARMV9A.ArchFeature, "+v9a");
+  EXPECT_EQ(AArch64::ARMV9_1A.ArchFeature, "+v9.1a");
+  EXPECT_EQ(AArch64::ARMV9_2A.ArchFeature, "+v9.2a");
+  EXPECT_EQ(AArch64::ARMV9_3A.ArchFeature, "+v9.3a");
+  EXPECT_EQ(AArch64::ARMV9_4A.ArchFeature, "+v9.4a");
+  EXPECT_EQ(AArch64::ARMV8R.ArchFeature, "+v8r");
 }
 
-TEST(TargetParserTest, AArch64ArchV9toV8Conversion) {
-  for (auto AK : AArch64::ArchKinds) {
-    if (AK == AArch64::ArchKind::INVALID)
-      EXPECT_EQ(AK, AArch64::convertV9toV8(AK));
-    else if (AK < AArch64::ArchKind::ARMV9A)
-      EXPECT_EQ(AK, AArch64::convertV9toV8(AK));
-    else if (AK >= AArch64::ArchKind::ARMV8R)
-      EXPECT_EQ(AArch64::ArchKind::INVALID, AArch64::convertV9toV8(AK));
-    else
-      EXPECT_TRUE(AArch64::convertV9toV8(AK) < AArch64::ArchKind::ARMV9A);
+TEST(TargetParserTest, AArch64ArchPartialOrder) {
+  EXPECT_FALSE(AArch64::INVALID.implies(AArch64::INVALID));
+
+  for (const auto *A : AArch64::ArchInfos) {
+    EXPECT_EQ(*A, *A);
+    if (!(*A == *A)) {
+      EXPECT_NE(*A, *A);
+    }
+    // Comparison with invalid is always false
+    EXPECT_FALSE(A->implies(AArch64::INVALID));
+    EXPECT_FALSE(AArch64::INVALID.implies(*A));
+
+    // v8r has no relation to other valid architectures
+    if (*A != AArch64::ARMV8R) {
+      EXPECT_FALSE(A->implies(AArch64::ARMV8R));
+      EXPECT_FALSE(AArch64::ARMV8R.implies(*A));
+    }
   }
-  EXPECT_EQ(AArch64::ArchKind::ARMV8_5A,
-              AArch64::convertV9toV8(AArch64::ArchKind::ARMV9A));
-  EXPECT_EQ(AArch64::ArchKind::ARMV8_6A,
-              AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_1A));
-  EXPECT_EQ(AArch64::ArchKind::ARMV8_7A,
-              AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_2A));
-  EXPECT_EQ(AArch64::ArchKind::ARMV8_8A,
-              AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_3A));
+
+  for (const auto *A : {
+           &AArch64::ARMV8_1A,
+           &AArch64::ARMV8_2A,
+           &AArch64::ARMV8_3A,
+           &AArch64::ARMV8_4A,
+           &AArch64::ARMV8_5A,
+           &AArch64::ARMV8_6A,
+           &AArch64::ARMV8_7A,
+           &AArch64::ARMV8_8A,
+           &AArch64::ARMV8_9A,
+       })
+    EXPECT_TRUE(A->implies(AArch64::ARMV8A));
+
+  for (const auto *A : {&AArch64::ARMV9_1A, &AArch64::ARMV9_2A,
+                        &AArch64::ARMV9_3A, &AArch64::ARMV9_4A})
+    EXPECT_TRUE(A->implies(AArch64::ARMV9A));
+
+  EXPECT_TRUE(AArch64::ARMV8_1A.implies(AArch64::ARMV8A));
+  EXPECT_TRUE(AArch64::ARMV8_2A.implies(AArch64::ARMV8_1A));
+  EXPECT_TRUE(AArch64::ARMV8_3A.implies(AArch64::ARMV8_2A));
+  EXPECT_TRUE(AArch64::ARMV8_4A.implies(AArch64::ARMV8_3A));
+  EXPECT_TRUE(AArch64::ARMV8_5A.implies(AArch64::ARMV8_4A));
+  EXPECT_TRUE(AArch64::ARMV8_6A.implies(AArch64::ARMV8_5A));
+  EXPECT_TRUE(AArch64::ARMV8_7A.implies(AArch64::ARMV8_6A));
+  EXPECT_TRUE(AArch64::ARMV8_8A.implies(AArch64::ARMV8_7A));
+  EXPECT_TRUE(AArch64::ARMV8_9A.implies(AArch64::ARMV8_8A));
+
+  EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV9A));
+  EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV9_1A));
+  EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV9_2A));
+  EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV9_3A));
+
+  EXPECT_TRUE(AArch64::ARMV9A.implies(AArch64::ARMV8_5A));
+  EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV8_6A));
+  EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV8_7A));
+  EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV8_8A));
+  EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV8_9A));
 }
 
 TEST(TargetParserTest, AArch64ArchExtFeature) {