[clang] 491a1cd - [AArch64]: Refactor target parser to use Bitset. (#65423)

via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 12 06:54:39 PDT 2023


Author: hassnaaHamdi
Date: 2023-09-12T14:54:33+01:00
New Revision: 491a1cd09eec43b5fab036b2a4571e906f020603

URL: https://github.com/llvm/llvm-project/commit/491a1cd09eec43b5fab036b2a4571e906f020603
DIFF: https://github.com/llvm/llvm-project/commit/491a1cd09eec43b5fab036b2a4571e906f020603.diff

LOG: [AArch64]: Refactor target parser to use Bitset. (#65423)

Use Bitset instead of BitMasking for the Architecture Extensions,
as the number of extensions will exceed the bitmask bits eventually.

Added: 
    

Modified: 
    clang/lib/Basic/Targets/AArch64.cpp
    clang/lib/Driver/ToolChains/Arch/AArch64.cpp
    llvm/include/llvm/TargetParser/AArch64TargetParser.h
    llvm/lib/TargetParser/AArch64TargetParser.cpp
    llvm/unittests/TargetParser/TargetParserTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index bdf5c4d98ebcea4..cccdf0e3861d0da 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -979,7 +979,7 @@ bool AArch64TargetInfo::initFeatureMap(
   // Parse the CPU and add any implied features.
   std::optional<llvm::AArch64::CpuInfo> CpuInfo = llvm::AArch64::parseCpu(CPU);
   if (CpuInfo) {
-    uint64_t Exts = CpuInfo->getImpliedExtensions();
+    llvm::Bitset Exts = CpuInfo->getImpliedExtensions();
     std::vector<StringRef> CPUFeats;
     llvm::AArch64::getExtensionFeatures(Exts, CPUFeats);
     for (auto F : CPUFeats) {

diff  --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index 507ad9247704103..19d454dd8bf3643 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -158,7 +158,7 @@ static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
 
     Features.push_back(ArchInfo->ArchFeature);
 
-    uint64_t Extension = CpuInfo->getImpliedExtensions();
+    llvm::Bitset Extension = CpuInfo->getImpliedExtensions();
     if (!llvm::AArch64::getExtensionFeatures(Extension, Features))
       return false;
   }

diff  --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index ba5c5fffd5f250c..44987da8276a371 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -15,6 +15,7 @@
 #define LLVM_TARGETPARSER_AARCH64TARGETPARSER_H
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Bitset.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/VersionTuple.h"
 #include <array>
@@ -96,65 +97,67 @@ static_assert(FEAT_MAX <= 64,
 // Arch extension modifiers for CPUs. These are labelled with their Arm ARM
 // feature name (though the canonical reference for those is AArch64.td)
 // clang-format off
-enum ArchExtKind : uint64_t {
-  AEK_NONE =        1,
-  AEK_CRC =         1 << 1,  // FEAT_CRC32
-  AEK_CRYPTO =      1 << 2,
-  AEK_FP =          1 << 3,  // FEAT_FP
-  AEK_SIMD =        1 << 4,  // FEAT_AdvSIMD
-  AEK_FP16 =        1 << 5,  // FEAT_FP16
-  AEK_PROFILE =     1 << 6,  // FEAT_SPE
-  AEK_RAS =         1 << 7,  // FEAT_RAS, FEAT_RASv1p1
-  AEK_LSE =         1 << 8,  // FEAT_LSE
-  AEK_SVE =         1 << 9,  // FEAT_SVE
-  AEK_DOTPROD =     1 << 10, // FEAT_DotProd
-  AEK_RCPC =        1 << 11, // FEAT_LRCPC
-  AEK_RDM =         1 << 12, // FEAT_RDM
-  AEK_SM4 =         1 << 13, // FEAT_SM4, FEAT_SM3
-  AEK_SHA3 =        1 << 14, // FEAT_SHA3, FEAT_SHA512
-  AEK_SHA2 =        1 << 15, // FEAT_SHA1, FEAT_SHA256
-  AEK_AES =         1 << 16, // FEAT_AES, FEAT_PMULL
-  AEK_FP16FML =     1 << 17, // FEAT_FHM
-  AEK_RAND =        1 << 18, // FEAT_RNG
-  AEK_MTE =         1 << 19, // FEAT_MTE, FEAT_MTE2
-  AEK_SSBS =        1 << 20, // FEAT_SSBS, FEAT_SSBS2
-  AEK_SB =          1 << 21, // FEAT_SB
-  AEK_PREDRES =     1 << 22, // FEAT_SPECRES
-  AEK_SVE2 =        1 << 23, // FEAT_SVE2
-  AEK_SVE2AES =     1 << 24, // FEAT_SVE_AES, FEAT_SVE_PMULL128
-  AEK_SVE2SM4 =     1 << 25, // FEAT_SVE_SM4
-  AEK_SVE2SHA3 =    1 << 26, // FEAT_SVE_SHA3
-  AEK_SVE2BITPERM = 1 << 27, // FEAT_SVE_BitPerm
-  AEK_TME =         1 << 28, // FEAT_TME
-  AEK_BF16 =        1 << 29, // FEAT_BF16
-  AEK_I8MM =        1 << 30, // FEAT_I8MM
-  AEK_F32MM =       1ULL << 31, // FEAT_F32MM
-  AEK_F64MM =       1ULL << 32, // FEAT_F64MM
-  AEK_LS64 =        1ULL << 33, // FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA
-  AEK_BRBE =        1ULL << 34, // FEAT_BRBE
-  AEK_PAUTH =       1ULL << 35, // FEAT_PAuth
-  AEK_FLAGM =       1ULL << 36, // FEAT_FlagM
-  AEK_SME =         1ULL << 37, // FEAT_SME
-  AEK_SMEF64F64 =   1ULL << 38, // FEAT_SME_F64F64
-  AEK_SMEI16I64 =   1ULL << 39, // FEAT_SME_I16I64
-  AEK_HBC =         1ULL << 40, // FEAT_HBC
-  AEK_MOPS =        1ULL << 41, // FEAT_MOPS
-  AEK_PERFMON =     1ULL << 42, // FEAT_PMUv3
-  AEK_SME2 =        1ULL << 43, // FEAT_SME2
-  AEK_SVE2p1 =      1ULL << 44, // FEAT_SVE2p1
-  AEK_SME2p1 =      1ULL << 45, // FEAT_SME2p1
-  AEK_B16B16 =      1ULL << 46, // FEAT_B16B16
-  AEK_SMEF16F16 =   1ULL << 47, // FEAT_SMEF16F16
-  AEK_CSSC =        1ULL << 48, // FEAT_CSSC
-  AEK_RCPC3 =       1ULL << 49, // FEAT_LRCPC3
-  AEK_THE =         1ULL << 50, // FEAT_THE
-  AEK_D128 =        1ULL << 51, // FEAT_D128
-  AEK_LSE128 =      1ULL << 52, // FEAT_LSE128
-  AEK_SPECRES2 =    1ULL << 53, // FEAT_SPECRES2
-  AEK_RASv2 =       1ULL << 54, // FEAT_RASv2
-  AEK_ITE =         1ULL << 55, // FEAT_ITE
-  AEK_GCS =         1ULL << 56, // FEAT_GCS
+enum ArchExtKind : unsigned {
+  AEK_NONE =          1,
+  AEK_CRC =           2,  // FEAT_CRC32
+  AEK_CRYPTO =        3,
+  AEK_FP =            4,  // FEAT_FP
+  AEK_SIMD =          5,  // FEAT_AdvSIMD
+  AEK_FP16 =          6,  // FEAT_FP16
+  AEK_PROFILE =       7,  // FEAT_SPE
+  AEK_RAS =           8,  // FEAT_RAS, FEAT_RASv1p1
+  AEK_LSE =           9,  // FEAT_LSE
+  AEK_SVE =           10,  // FEAT_SVE
+  AEK_DOTPROD =       11, // FEAT_DotProd
+  AEK_RCPC =          12, // FEAT_LRCPC
+  AEK_RDM =           13, // FEAT_RDM
+  AEK_SM4 =           14, // FEAT_SM4, FEAT_SM3
+  AEK_SHA3 =          15, // FEAT_SHA3, FEAT_SHA512
+  AEK_SHA2 =          16, // FEAT_SHA1, FEAT_SHA256
+  AEK_AES =           17, // FEAT_AES, FEAT_PMULL
+  AEK_FP16FML =       18, // FEAT_FHM
+  AEK_RAND =          19, // FEAT_RNG
+  AEK_MTE =           20, // FEAT_MTE, FEAT_MTE2
+  AEK_SSBS =          21, // FEAT_SSBS, FEAT_SSBS2
+  AEK_SB =            22, // FEAT_SB
+  AEK_PREDRES =       23, // FEAT_SPECRES
+  AEK_SVE2 =          24, // FEAT_SVE2
+  AEK_SVE2AES =       25, // FEAT_SVE_AES, FEAT_SVE_PMULL128
+  AEK_SVE2SM4 =       26, // FEAT_SVE_SM4
+  AEK_SVE2SHA3 =      27, // FEAT_SVE_SHA3
+  AEK_SVE2BITPERM =   28, // FEAT_SVE_BitPerm
+  AEK_TME =           29, // FEAT_TME
+  AEK_BF16 =          30, // FEAT_BF16
+  AEK_I8MM =          31, // FEAT_I8MM
+  AEK_F32MM =         32, // FEAT_F32MM
+  AEK_F64MM =         33, // FEAT_F64MM
+  AEK_LS64 =          34, // FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA
+  AEK_BRBE =          35, // FEAT_BRBE
+  AEK_PAUTH =         36, // FEAT_PAuth
+  AEK_FLAGM =         37, // FEAT_FlagM
+  AEK_SME =           38, // FEAT_SME
+  AEK_SMEF64F64 =     39, // FEAT_SME_F64F64
+  AEK_SMEI16I64 =     40, // FEAT_SME_I16I64
+  AEK_HBC =           41, // FEAT_HBC
+  AEK_MOPS =          42, // FEAT_MOPS
+  AEK_PERFMON =       43, // FEAT_PMUv3
+  AEK_SME2 =          44, // FEAT_SME2
+  AEK_SVE2p1 =        45, // FEAT_SVE2p1
+  AEK_SME2p1 =        46, // FEAT_SME2p1
+  AEK_B16B16 =        47, // FEAT_B16B16
+  AEK_SMEF16F16 =     48, // FEAT_SMEF16F16
+  AEK_CSSC =          49, // FEAT_CSSC
+  AEK_RCPC3 =         50, // FEAT_LRCPC3
+  AEK_THE =           51, // FEAT_THE
+  AEK_D128 =          52, // FEAT_D128
+  AEK_LSE128 =        53, // FEAT_LSE128
+  AEK_SPECRES2 =      54, // FEAT_SPECRES2
+  AEK_RASv2 =         55, // FEAT_RASv2
+  AEK_ITE =           56, // FEAT_ITE
+  AEK_GCS =           57, // FEAT_GCS
+  AEK_NUM_EXTENSIONS =  AEK_GCS + 1
 };
+using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>;
 // clang-format on
 
 // Represents an extension that can be enabled with -march=<arch>+<extension>.
@@ -273,7 +276,8 @@ struct ArchInfo {
   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
+  AArch64::ExtensionBitset
+      DefaultExts; // bitfield of default extensions ArchExtKind
 
   bool operator==(const ArchInfo &Other) const {
     return this->Name == Other.Name;
@@ -315,23 +319,37 @@ struct ArchInfo {
 };
 
 // clang-format off
-inline constexpr ArchInfo ARMV8A    = { VersionTuple{8, 0}, AProfile, "armv8-a", "+v8a", (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 ARMV8A    = { VersionTuple{8, 0}, AProfile, "armv8-a", "+v8a", (
+                                        AArch64::ExtensionBitset({AArch64::AEK_FP, AArch64::AEK_SIMD})), };
+inline constexpr ArchInfo ARMV8_1A  = { VersionTuple{8, 1}, AProfile, "armv8.1-a", "+v8.1a", (ARMV8A.DefaultExts |
+                                        AArch64::ExtensionBitset({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::ExtensionBitset({AArch64::AEK_RAS}))};
+inline constexpr ArchInfo ARMV8_3A  = { VersionTuple{8, 3}, AProfile, "armv8.3-a", "+v8.3a", (ARMV8_2A.DefaultExts |
+                                        AArch64::ExtensionBitset({AArch64::AEK_RCPC}))};
+inline constexpr ArchInfo ARMV8_4A  = { VersionTuple{8, 4}, AProfile, "armv8.4-a", "+v8.4a", (ARMV8_3A.DefaultExts |
+                                        AArch64::ExtensionBitset({AArch64::AEK_DOTPROD}))};
 inline constexpr ArchInfo ARMV8_5A  = { VersionTuple{8, 5}, AProfile, "armv8.5-a", "+v8.5a", (ARMV8_4A.DefaultExts)};
-inline constexpr ArchInfo ARMV8_6A  = { VersionTuple{8, 6}, AProfile, "armv8.6-a", "+v8.6a", (ARMV8_5A.DefaultExts | AArch64::AEK_BF16 | AArch64::AEK_I8MM)};
+inline constexpr ArchInfo ARMV8_6A  = { VersionTuple{8, 6}, AProfile, "armv8.6-a", "+v8.6a", (ARMV8_5A.DefaultExts |
+                                        AArch64::ExtensionBitset({AArch64::AEK_BF16, 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 | AArch64::AEK_MOPS | AArch64::AEK_HBC)};
-inline constexpr ArchInfo ARMV8_9A  = { VersionTuple{8, 9}, AProfile, "armv8.9-a", "+v8.9a", (ARMV8_8A.DefaultExts | AArch64::AEK_SPECRES2 | AArch64::AEK_CSSC | AArch64::AEK_RASv2)};
-inline constexpr ArchInfo ARMV9A    = { VersionTuple{9, 0}, AProfile, "armv9-a", "+v9a", (ARMV8_5A.DefaultExts | AArch64::AEK_FP16 | 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 ARMV8_8A  = { VersionTuple{8, 8}, AProfile, "armv8.8-a", "+v8.8a", (ARMV8_7A.DefaultExts |
+                                        AArch64::ExtensionBitset({AArch64::AEK_MOPS, AArch64::AEK_HBC}))};
+inline constexpr ArchInfo ARMV8_9A  = { VersionTuple{8, 9}, AProfile, "armv8.9-a", "+v8.9a", (ARMV8_8A.DefaultExts |
+                                        AArch64::ExtensionBitset({AArch64::AEK_SPECRES2, AArch64::AEK_CSSC, AArch64::AEK_RASv2}))};
+inline constexpr ArchInfo ARMV9A    = { VersionTuple{9, 0}, AProfile, "armv9-a", "+v9a", (ARMV8_5A.DefaultExts |
+                                        AArch64::ExtensionBitset({AArch64::AEK_FP16, AArch64::AEK_SVE, AArch64::AEK_SVE2}))};
+inline constexpr ArchInfo ARMV9_1A  = { VersionTuple{9, 1}, AProfile, "armv9.1-a", "+v9.1a", (ARMV9A.DefaultExts |
+                                        AArch64::ExtensionBitset({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 | AArch64::AEK_MOPS | AArch64::AEK_HBC)};
-inline constexpr ArchInfo ARMV9_4A  = { VersionTuple{9, 4}, AProfile, "armv9.4-a", "+v9.4a", (ARMV9_3A.DefaultExts | AArch64::AEK_SPECRES2 | AArch64::AEK_CSSC | AArch64::AEK_RASv2)};
+inline constexpr ArchInfo ARMV9_3A  = { VersionTuple{9, 3}, AProfile, "armv9.3-a", "+v9.3a", (ARMV9_2A.DefaultExts |
+                                        AArch64::ExtensionBitset({AArch64::AEK_MOPS, AArch64::AEK_HBC}))};
+inline constexpr ArchInfo ARMV9_4A  = { VersionTuple{9, 4}, AProfile, "armv9.4-a", "+v9.4a", (ARMV9_3A.DefaultExts |
+                                        AArch64::ExtensionBitset({AArch64::AEK_SPECRES2, AArch64::AEK_CSSC, 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.
-inline constexpr ArchInfo ARMV8R    = { VersionTuple{8, 0}, RProfile, "armv8-r", "+v8r", ((ARMV8_5A.DefaultExts ^ AArch64::AEK_LSE) | AArch64::AEK_SSBS | AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SB), };
+inline constexpr ArchInfo ARMV8R    = { VersionTuple{8, 0}, RProfile, "armv8-r", "+v8r", (Bitset(ARMV8_5A.DefaultExts) |
+                                        AArch64::ExtensionBitset({AArch64::AEK_SSBS,
+                                        AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_SB}).flip(AArch64::AEK_LSE))};
 // clang-format on
 
 // The set of all architectures
@@ -345,203 +363,271 @@ static constexpr std::array<const ArchInfo *, 16> ArchInfos = {
 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.
+  AArch64::ExtensionBitset
+      DefaultExtensions; // Default extensions for this CPU. These will be
+                         // ORd with the architecture defaults.
 
-  uint64_t getImpliedExtensions() const {
-    return DefaultExtensions | Arch.DefaultExts;
+  AArch64::ExtensionBitset getImpliedExtensions() const {
+    AArch64::ExtensionBitset ImpliedExts;
+    ImpliedExts |= DefaultExtensions;
+    ImpliedExts |= Arch.DefaultExts;
+    return ImpliedExts;
   }
 };
 
 inline constexpr CpuInfo CpuInfos[] = {
     {"cortex-a34", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
     {"cortex-a35", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
     {"cortex-a53", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
     {"cortex-a55", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 |
-      AArch64::AEK_DOTPROD | AArch64::AEK_RCPC)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, 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)},
+     (AArch64::ExtensionBitset(
+         {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_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
     {"cortex-a65", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD |
-      AArch64::AEK_FP16 | AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD,
+          AArch64::AEK_FP16, AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
     {"cortex-a65ae", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD |
-      AArch64::AEK_FP16 | AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD,
+          AArch64::AEK_FP16, AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
     {"cortex-a72", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
     {"cortex-a73", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
     {"cortex-a75", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 |
-      AArch64::AEK_DOTPROD | AArch64::AEK_RCPC)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
+          AArch64::AEK_DOTPROD, AArch64::AEK_RCPC}))},
     {"cortex-a76", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 |
-      AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
+          AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
     {"cortex-a76ae", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 |
-      AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
+          AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
     {"cortex-a77", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 |
-      AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_SSBS)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
+          AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_SSBS}))},
     {"cortex-a78", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 |
-      AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | AArch64::AEK_SSBS |
-      AArch64::AEK_PROFILE)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
+          AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS,
+          AArch64::AEK_PROFILE}))},
     {"cortex-a78c", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | 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::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, 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)},
+     (AArch64::ExtensionBitset(
+         {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)},
+     (AArch64::ExtensionBitset(
+         {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::ExtensionBitset({AArch64::AEK_LSE}))},
     {"cortex-x1", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 |
-      AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | AArch64::AEK_SSBS |
-      AArch64::AEK_PROFILE)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16,
+          AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS,
+          AArch64::AEK_PROFILE}))},
     {"cortex-x1c", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 |
-      AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | AArch64::AEK_SSBS |
-      AArch64::AEK_PAUTH | AArch64::AEK_PROFILE)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, 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)},
+     (AArch64::ExtensionBitset(
+         {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)},
+     (AArch64::ExtensionBitset(
+         {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_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD |
-      AArch64::AEK_FP16 | AArch64::AEK_RCPC | AArch64::AEK_SSBS)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD,
+          AArch64::AEK_FP16, AArch64::AEK_RCPC, AArch64::AEK_SSBS}))},
     {"neoverse-n1", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD |
-      AArch64::AEK_FP16 | AArch64::AEK_PROFILE | AArch64::AEK_RCPC |
-      AArch64::AEK_SSBS)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD,
+          AArch64::AEK_FP16, AArch64::AEK_PROFILE, AArch64::AEK_RCPC,
+          AArch64::AEK_SSBS}))},
     {"neoverse-n2", ARMV8_5A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-      AArch64::AEK_SM4 | 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::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3,
+          AArch64::AEK_SM4, 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_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-      AArch64::AEK_SM4 | 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::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3,
+          AArch64::AEK_SM4, 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_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-      AArch64::AEK_SM4 | 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::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3,
+          AArch64::AEK_SM4, 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)},
+     (AArch64::ExtensionBitset(
+         {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_AES | AArch64::AEK_SHA2 | AArch64::AEK_NONE)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE}))},
     {"apple-a7", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_NONE)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE}))},
     {"apple-a8", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_NONE)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE}))},
     {"apple-a9", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_NONE)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE}))},
     {"apple-a10", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC |
-      AArch64::AEK_RDM)},
+     (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+                                           AArch64::AEK_CRC,
+                                           AArch64::AEK_RDM}))},
     {"apple-a11", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16}))},
     {"apple-a12", ARMV8_3A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16}))},
     {"apple-a13", ARMV8_4A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-      AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3,
+          AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_SHA3}))},
     {"apple-a14", ARMV8_5A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-      AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3,
+          AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_SHA3}))},
     {"apple-a15", ARMV8_5A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-      AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3 |
-      AArch64::AEK_BF16 | AArch64::AEK_I8MM)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3,
+          AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_SHA3,
+          AArch64::AEK_BF16, AArch64::AEK_I8MM}))},
     {"apple-a16", ARMV8_5A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-      AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3 |
-      AArch64::AEK_BF16 | AArch64::AEK_I8MM)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3,
+          AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_SHA3,
+          AArch64::AEK_BF16, AArch64::AEK_I8MM}))},
     {"apple-m1", ARMV8_5A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-      AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3,
+          AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_SHA3}))},
     {"apple-m2", ARMV8_5A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-      AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3 |
-      AArch64::AEK_BF16 | AArch64::AEK_I8MM)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3,
+          AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_SHA3,
+          AArch64::AEK_BF16, AArch64::AEK_I8MM}))},
     {"apple-s4", ARMV8_3A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16}))},
     {"apple-s5", ARMV8_3A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16}))},
     {"exynos-m3", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
     {"exynos-m4", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD |
-      AArch64::AEK_FP16)},
+     (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+                                           AArch64::AEK_DOTPROD,
+                                           AArch64::AEK_FP16}))},
     {"exynos-m5", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD |
-      AArch64::AEK_FP16)},
+     (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+                                           AArch64::AEK_DOTPROD,
+                                           AArch64::AEK_FP16}))},
     {"falkor", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC |
-      AArch64::AEK_RDM)},
+     (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+                                           AArch64::AEK_CRC,
+                                           AArch64::AEK_RDM}))},
     {"saphira", ARMV8_3A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_PROFILE)},
-    {"kryo", ARMV8A, (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)},
-    {"thunderx2t99", ARMV8_1A, (AArch64::AEK_AES | AArch64::AEK_SHA2)},
-    {"thunderx3t110", ARMV8_3A, (AArch64::AEK_AES | AArch64::AEK_SHA2)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_PROFILE}))},
+    {"kryo", ARMV8A,
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
+    {"thunderx2t99", ARMV8_1A,
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2}))},
+    {"thunderx3t110", ARMV8_3A,
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2}))},
     {"thunderx", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
     {"thunderxt88", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
     {"thunderxt81", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
     {"thunderxt83", ARMV8A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC}))},
     {"tsv110", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD |
-      AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_PROFILE)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD,
+          AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_PROFILE}))},
     {"a64fx", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 |
-      AArch64::AEK_SVE)},
+     (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+                                           AArch64::AEK_FP16,
+                                           AArch64::AEK_SVE}))},
     {"carmel", ARMV8_2A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16}))},
     {"ampere1", ARMV8_6A,
-     (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-      AArch64::AEK_FP16 | AArch64::AEK_SB | AArch64::AEK_SSBS |
-      AArch64::AEK_RAND)},
+     (AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2,
+                                           AArch64::AEK_SHA3, AArch64::AEK_FP16,
+                                           AArch64::AEK_SB, AArch64::AEK_SSBS,
+                                           AArch64::AEK_RAND}))},
     {"ampere1a", ARMV8_6A,
-     (AArch64::AEK_FP16 | AArch64::AEK_RAND | AArch64::AEK_SM4 |
-      AArch64::AEK_SHA3 | AArch64::AEK_SHA2 | AArch64::AEK_AES |
-      AArch64::AEK_MTE | AArch64::AEK_SB | AArch64::AEK_SSBS)},
+     (AArch64::ExtensionBitset(
+         {AArch64::AEK_FP16, AArch64::AEK_RAND, AArch64::AEK_SM4,
+          AArch64::AEK_SHA3, AArch64::AEK_SHA2, AArch64::AEK_AES,
+          AArch64::AEK_MTE, AArch64::AEK_SB, AArch64::AEK_SSBS}))},
 };
 
 // An alias for a CPU.
@@ -552,8 +638,9 @@ struct CpuAlias {
 
 inline constexpr CpuAlias CpuAliases[] = {{"grace", "neoverse-v2"}};
 
-bool getExtensionFeatures(uint64_t Extensions,
-                          std::vector<StringRef> &Features);
+bool getExtensionFeatures(
+    const AArch64::ExtensionBitset &Extensions,
+    std::vector<StringRef> &Features);
 
 StringRef getArchExtFeature(StringRef ArchExt);
 StringRef resolveCPUAlias(StringRef CPU);

diff  --git a/llvm/lib/TargetParser/AArch64TargetParser.cpp b/llvm/lib/TargetParser/AArch64TargetParser.cpp
index c4f689c5b497b50..166cf880ad4a895 100644
--- a/llvm/lib/TargetParser/AArch64TargetParser.cpp
+++ b/llvm/lib/TargetParser/AArch64TargetParser.cpp
@@ -55,11 +55,12 @@ uint64_t AArch64::getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs) {
   return FeaturesMask;
 }
 
-bool AArch64::getExtensionFeatures(uint64_t InputExts,
-                                   std::vector<StringRef> &Features) {
+bool AArch64::getExtensionFeatures(
+    const AArch64::ExtensionBitset &InputExts,
+    std::vector<StringRef> &Features) {
   for (const auto &E : Extensions)
     /* INVALID and NONE have no feature name. */
-    if ((InputExts & E.ID) && !E.Feature.empty())
+    if (InputExts.test(E.ID) && !E.Feature.empty())
       Features.push_back(E.Feature);
 
   return true;

diff  --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 60b235d8d2d6903..0c114d1b85a6935 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -18,6 +18,7 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include <optional>
+#include <sstream>
 #include <string>
 
 using namespace llvm;
@@ -42,21 +43,32 @@ const char *ARMArch[] = {
     "armv9.4a",
 };
 
-template <ARM::ISAKind ISAKind>
-std::string FormatExtensionFlags(uint64_t Flags) {
+std::string FormatExtensionFlags(int64_t Flags) {
   std::vector<StringRef> Features;
 
-  if (ISAKind == ARM::ISAKind::AARCH64) {
-    // AEK_NONE is not meant to be shown to the user so the target parser
-    // does not recognise it. It is relevant here though.
-    if (Flags & AArch64::AEK_NONE)
-      Features.push_back("none");
-    AArch64::getExtensionFeatures(Flags, Features);
-  } else {
-    if (Flags & ARM::AEK_NONE)
-      Features.push_back("none");
-    ARM::getExtensionFeatures(Flags, Features);
-  }
+  if (Flags & ARM::AEK_NONE)
+    Features.push_back("none");
+  ARM::getExtensionFeatures(Flags, Features);
+
+  // The target parser also includes every extension you don't have.
+  // E.g. if AEK_CRC is not set then it adds "-crc". Not useful here.
+  Features.erase(std::remove_if(Features.begin(), Features.end(),
+                                [](StringRef extension) {
+                                  return extension.startswith("-");
+                                }),
+                 Features.end());
+
+  return llvm::join(Features, ", ");
+}
+
+std::string FormatExtensionFlags(AArch64::ExtensionBitset Flags) {
+  std::vector<StringRef> Features;
+
+  // AEK_NONE is not meant to be shown to the user so the target parser
+  // does not recognise it. It is relevant here though.
+  if (Flags.test(AArch64::AEK_NONE))
+    Features.push_back("none");
+  AArch64::getExtensionFeatures(Flags, Features);
 
   // The target parser also includes every extension you don't have.
   // E.g. if AEK_CRC is not set then it adds "-crc". Not useful here.
@@ -69,6 +81,26 @@ std::string FormatExtensionFlags(uint64_t Flags) {
   return llvm::join(Features, ", ");
 }
 
+std::string SerializeExtensionFlags(AArch64::ExtensionBitset Flags) {
+  std::string SerializedFlags;
+  std::ostringstream ss;
+  int HexValue = 0;
+  for (unsigned int i = 0; i < AArch64::AEK_NUM_EXTENSIONS; i++) {
+    HexValue <<= 1;
+    HexValue |= (int)Flags[i];
+    if ((i + 1) % 4 == 0) {
+      ss << std::hex << HexValue;
+      HexValue = 0;
+    }
+  }
+  // check if there are remainig unhandled bits
+  if ((AArch64::AEK_NUM_EXTENSIONS % 4) != 0)
+      ss << std::hex << HexValue;
+
+  SerializedFlags = ss.str();
+  return SerializedFlags;
+}
+
 template <ARM::ISAKind ISAKind> struct AssertSameExtensionFlags {
   AssertSameExtensionFlags(StringRef CPUName) : CPUName(CPUName) {}
 
@@ -82,37 +114,59 @@ template <ARM::ISAKind ISAKind> struct AssertSameExtensionFlags {
                "CPU: {4}\n"
                "Expected extension flags: {0} ({1:x})\n"
                "     Got extension flags: {2} ({3:x})\n",
-               FormatExtensionFlags<ISAKind>(ExpectedFlags), ExpectedFlags,
-               FormatExtensionFlags<ISAKind>(GotFlags), GotFlags, CPUName);
+               FormatExtensionFlags(ExpectedFlags),
+               ExpectedFlags, FormatExtensionFlags(GotFlags),
+               ExpectedFlags, CPUName);
+  }
+
+  testing::AssertionResult
+  operator()(const char *m_expr, const char *n_expr,
+             AArch64::ExtensionBitset ExpectedFlags,
+             AArch64::ExtensionBitset GotFlags) {
+    if (ExpectedFlags == GotFlags)
+      return testing::AssertionSuccess();
+
+    return testing::AssertionFailure() << llvm::formatv(
+               "CPU: {4}\n"
+               "Expected extension flags: {0} ({1:x})\n"
+               "     Got extension flags: {2} ({3:x})\n",
+               FormatExtensionFlags(ExpectedFlags),
+               SerializeExtensionFlags(ExpectedFlags),
+               FormatExtensionFlags(GotFlags),
+               SerializeExtensionFlags(ExpectedFlags), CPUName);
   }
 
 private:
   StringRef CPUName;
 };
 
-struct ARMCPUTestParams {
+template <typename T> struct ARMCPUTestParams {
   ARMCPUTestParams(StringRef CPUName, StringRef ExpectedArch,
-                   StringRef ExpectedFPU, uint64_t ExpectedFlags,
-                   StringRef CPUAttr)
+                   StringRef ExpectedFPU, T ExpectedFlags, StringRef CPUAttr)
       : CPUName(CPUName), ExpectedArch(ExpectedArch), ExpectedFPU(ExpectedFPU),
         ExpectedFlags(ExpectedFlags), CPUAttr(CPUAttr) {}
 
   friend std::ostream &operator<<(std::ostream &os,
-                                  const ARMCPUTestParams &params) {
-    return os << "\"" << params.CPUName.str() << "\", \""
-              << params.ExpectedArch.str() << "\", \""
-              << params.ExpectedFPU.str() << "\", 0x" << std::hex
-              << params.ExpectedFlags << ", \"" << params.CPUAttr.str() << "\"";
+                                  const ARMCPUTestParams<T> &params) {
+    os << "\"" << params.CPUName.str() << "\", \"" << params.ExpectedArch.str()
+       << "\", \"" << params.ExpectedFPU.str() << "\", 0x";
+    if constexpr (std::is_same<T, uint64_t>::value)
+      os << std::hex << params.ExpectedFlags;
+    else
+      os << SerializeExtensionFlags(params.ExpectedFlags);
+    os << ", \"" << params.CPUAttr.str() << "\"";
+    return os;
   }
 
   StringRef CPUName;
   StringRef ExpectedArch;
   StringRef ExpectedFPU;
-  uint64_t ExpectedFlags;
+  T ExpectedFlags;
   StringRef CPUAttr;
 };
 
-class ARMCPUTestFixture : public ::testing::TestWithParam<ARMCPUTestParams> {};
+class ARMCPUTestFixture
+    : public ::testing::TestWithParam<ARMCPUTestParams<uint64_t>> {};
 
 TEST_P(ARMCPUTestFixture, ARMCPUTests) {
   auto params = GetParam();
@@ -138,287 +192,287 @@ TEST_P(ARMCPUTestFixture, ARMCPUTests) {
 INSTANTIATE_TEST_SUITE_P(
     ARMCPUTestsPart1, ARMCPUTestFixture,
     ::testing::Values(
-        ARMCPUTestParams("invalid", "invalid", "invalid", ARM::AEK_NONE, ""),
-        ARMCPUTestParams("generic", "invalid", "none", ARM::AEK_NONE, ""),
-
-        ARMCPUTestParams("arm8", "armv4", "none", ARM::AEK_NONE, "4"),
-        ARMCPUTestParams("arm810", "armv4", "none", ARM::AEK_NONE, "4"),
-        ARMCPUTestParams("strongarm", "armv4", "none", ARM::AEK_NONE, "4"),
-        ARMCPUTestParams("strongarm110", "armv4", "none", ARM::AEK_NONE, "4"),
-        ARMCPUTestParams("strongarm1100", "armv4", "none", ARM::AEK_NONE, "4"),
-        ARMCPUTestParams("strongarm1110", "armv4", "none", ARM::AEK_NONE, "4"),
-        ARMCPUTestParams("arm7tdmi", "armv4t", "none", ARM::AEK_NONE, "4T"),
-        ARMCPUTestParams("arm7tdmi-s", "armv4t", "none", ARM::AEK_NONE, "4T"),
-        ARMCPUTestParams("arm710t", "armv4t", "none", ARM::AEK_NONE, "4T"),
-        ARMCPUTestParams("arm720t", "armv4t", "none", ARM::AEK_NONE, "4T"),
-        ARMCPUTestParams("arm9", "armv4t", "none", ARM::AEK_NONE, "4T"),
-        ARMCPUTestParams("arm9tdmi", "armv4t", "none", ARM::AEK_NONE, "4T"),
-        ARMCPUTestParams("arm920", "armv4t", "none", ARM::AEK_NONE, "4T"),
-        ARMCPUTestParams("arm920t", "armv4t", "none", ARM::AEK_NONE, "4T"),
-        ARMCPUTestParams("arm922t", "armv4t", "none", ARM::AEK_NONE, "4T"),
-        ARMCPUTestParams("arm940t", "armv4t", "none", ARM::AEK_NONE, "4T"),
-        ARMCPUTestParams("ep9312", "armv4t", "none", ARM::AEK_NONE, "4T"),
-        ARMCPUTestParams("arm10tdmi", "armv5t", "none", ARM::AEK_NONE, "5T"),
-        ARMCPUTestParams("arm1020t", "armv5t", "none", ARM::AEK_NONE, "5T"),
-        ARMCPUTestParams("arm9e", "armv5te", "none",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
+        ARMCPUTestParams<uint64_t>("invalid", "invalid", "invalid", ARM::AEK_NONE, ""),
+        ARMCPUTestParams<uint64_t>("generic", "invalid", "none", ARM::AEK_NONE, ""),
+
+        ARMCPUTestParams<uint64_t>("arm8", "armv4", "none", ARM::AEK_NONE, "4"),
+        ARMCPUTestParams<uint64_t>("arm810", "armv4", "none", ARM::AEK_NONE, "4"),
+        ARMCPUTestParams<uint64_t>("strongarm", "armv4", "none", ARM::AEK_NONE, "4"),
+        ARMCPUTestParams<uint64_t>("strongarm110", "armv4", "none", ARM::AEK_NONE, "4"),
+        ARMCPUTestParams<uint64_t>("strongarm1100", "armv4", "none", ARM::AEK_NONE, "4"),
+        ARMCPUTestParams<uint64_t>("strongarm1110", "armv4", "none", ARM::AEK_NONE, "4"),
+        ARMCPUTestParams<uint64_t>("arm7tdmi", "armv4t", "none", ARM::AEK_NONE, "4T"),
+        ARMCPUTestParams<uint64_t>("arm7tdmi-s", "armv4t", "none", ARM::AEK_NONE, "4T"),
+        ARMCPUTestParams<uint64_t>("arm710t", "armv4t", "none", ARM::AEK_NONE, "4T"),
+        ARMCPUTestParams<uint64_t>("arm720t", "armv4t", "none", ARM::AEK_NONE, "4T"),
+        ARMCPUTestParams<uint64_t>("arm9", "armv4t", "none", ARM::AEK_NONE, "4T"),
+        ARMCPUTestParams<uint64_t>("arm9tdmi", "armv4t", "none", ARM::AEK_NONE, "4T"),
+        ARMCPUTestParams<uint64_t>("arm920", "armv4t", "none", ARM::AEK_NONE, "4T"),
+        ARMCPUTestParams<uint64_t>("arm920t", "armv4t", "none", ARM::AEK_NONE, "4T"),
+        ARMCPUTestParams<uint64_t>("arm922t", "armv4t", "none", ARM::AEK_NONE, "4T"),
+        ARMCPUTestParams<uint64_t>("arm940t", "armv4t", "none", ARM::AEK_NONE, "4T"),
+        ARMCPUTestParams<uint64_t>("ep9312", "armv4t", "none", ARM::AEK_NONE, "4T"),
+        ARMCPUTestParams<uint64_t>("arm10tdmi", "armv5t", "none", ARM::AEK_NONE, "5T"),
+        ARMCPUTestParams<uint64_t>("arm1020t", "armv5t", "none", ARM::AEK_NONE, "5T"),
+        ARMCPUTestParams<uint64_t>("arm9e", "armv5te", "none",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
         ARMCPUTestParams("arm946e-s", "armv5te", "none",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
-        ARMCPUTestParams("arm966e-s", "armv5te", "none",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
-        ARMCPUTestParams("arm968e-s", "armv5te", "none",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
-        ARMCPUTestParams("arm10e", "armv5te", "none",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
-        ARMCPUTestParams("arm1020e", "armv5te", "none",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
-        ARMCPUTestParams("arm1022e", "armv5te", "none",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
-        ARMCPUTestParams("arm926ej-s", "armv5tej", "none",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "5TEJ"),
-        ARMCPUTestParams("arm1136j-s", "armv6", "none",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "6"),
-        ARMCPUTestParams("arm1136jf-s", "armv6", "vfpv2",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "6"),
-        ARMCPUTestParams("arm1176jz-s", "armv6kz", "none",
-                         ARM::AEK_NONE | ARM::AEK_SEC | ARM::AEK_DSP, "6KZ"),
-        ARMCPUTestParams("mpcore", "armv6k", "vfpv2",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "6K"),
-        ARMCPUTestParams("mpcorenovfp", "armv6k", "none",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "6K"),
-        ARMCPUTestParams("arm1176jzf-s", "armv6kz", "vfpv2",
-                         ARM::AEK_NONE | ARM::AEK_SEC | ARM::AEK_DSP, "6KZ"),
-        ARMCPUTestParams("arm1156t2-s", "armv6t2", "none",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "6T2"),
-        ARMCPUTestParams("arm1156t2f-s", "armv6t2", "vfpv2",
-                         ARM::AEK_NONE | ARM::AEK_DSP, "6T2"),
-        ARMCPUTestParams("cortex-m0", "armv6-m", "none", ARM::AEK_NONE, "6-M"),
-        ARMCPUTestParams("cortex-m0plus", "armv6-m", "none", ARM::AEK_NONE,
-                         "6-M"),
-        ARMCPUTestParams("cortex-m1", "armv6-m", "none", ARM::AEK_NONE, "6-M"),
-        ARMCPUTestParams("sc000", "armv6-m", "none", ARM::AEK_NONE, "6-M"),
-        ARMCPUTestParams("cortex-a5", "armv7-a", "neon-vfpv4",
-                         ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP, "7-A"),
-        ARMCPUTestParams("cortex-a7", "armv7-a", "neon-vfpv4",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
+        ARMCPUTestParams<uint64_t>("arm966e-s", "armv5te", "none",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
+        ARMCPUTestParams<uint64_t>("arm968e-s", "armv5te", "none",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
+        ARMCPUTestParams<uint64_t>("arm10e", "armv5te", "none",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
+        ARMCPUTestParams<uint64_t>("arm1020e", "armv5te", "none",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
+        ARMCPUTestParams<uint64_t>("arm1022e", "armv5te", "none",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
+        ARMCPUTestParams<uint64_t>("arm926ej-s", "armv5tej", "none",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "5TEJ"),
+        ARMCPUTestParams<uint64_t>("arm1136j-s", "armv6", "none",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "6"),
+        ARMCPUTestParams<uint64_t>("arm1136jf-s", "armv6", "vfpv2",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "6"),
+        ARMCPUTestParams<uint64_t>("arm1176jz-s", "armv6kz", "none",
+                                   ARM::AEK_NONE | ARM::AEK_SEC | ARM::AEK_DSP, "6KZ"),
+        ARMCPUTestParams<uint64_t>("mpcore", "armv6k", "vfpv2",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "6K"),
+        ARMCPUTestParams<uint64_t>("mpcorenovfp", "armv6k", "none",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "6K"),
+        ARMCPUTestParams<uint64_t>("arm1176jzf-s", "armv6kz", "vfpv2",
+                                   ARM::AEK_NONE | ARM::AEK_SEC | ARM::AEK_DSP, "6KZ"),
+        ARMCPUTestParams<uint64_t>("arm1156t2-s", "armv6t2", "none",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "6T2"),
+        ARMCPUTestParams<uint64_t>("arm1156t2f-s", "armv6t2", "vfpv2",
+                                   ARM::AEK_NONE | ARM::AEK_DSP, "6T2"),
+        ARMCPUTestParams<uint64_t>("cortex-m0", "armv6-m", "none", ARM::AEK_NONE, "6-M"),
+        ARMCPUTestParams<uint64_t>("cortex-m0plus", "armv6-m", "none", ARM::AEK_NONE,
+                                   "6-M"),
+        ARMCPUTestParams<uint64_t>("cortex-m1", "armv6-m", "none", ARM::AEK_NONE, "6-M"),
+        ARMCPUTestParams<uint64_t>("sc000", "armv6-m", "none", ARM::AEK_NONE, "6-M"),
+        ARMCPUTestParams<uint64_t>("cortex-a5", "armv7-a", "neon-vfpv4",
+                                   ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP, "7-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a7", "armv7-a", "neon-vfpv4",
                          ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM | ARM::AEK_MP |
                              ARM::AEK_SEC | ARM::AEK_VIRT | ARM::AEK_DSP,
-                         "7-A"),
-        ARMCPUTestParams("cortex-a8", "armv7-a", "neon",
-                         ARM::AEK_SEC | ARM::AEK_DSP, "7-A")));
+                                   "7-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a8", "armv7-a", "neon",
+                                   ARM::AEK_SEC | ARM::AEK_DSP, "7-A")));
 
 // gtest in llvm has a limit of 50 test cases when using ::Values so we split
 // them into 2 blocks
 INSTANTIATE_TEST_SUITE_P(
     ARMCPUTestsPart2, ARMCPUTestFixture,
     ::testing::Values(
-        ARMCPUTestParams("cortex-a9", "armv7-a", "neon-fp16",
-                         ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP, "7-A"),
-        ARMCPUTestParams("cortex-a12", "armv7-a", "neon-vfpv4",
-                         ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
-                             ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
-                             ARM::AEK_DSP,
-                         "7-A"),
-        ARMCPUTestParams("cortex-a15", "armv7-a", "neon-vfpv4",
-                         ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
-                             ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
-                             ARM::AEK_DSP,
-                         "7-A"),
-        ARMCPUTestParams("cortex-a17", "armv7-a", "neon-vfpv4",
-                         ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
-                             ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
-                             ARM::AEK_DSP,
-                         "7-A"),
-        ARMCPUTestParams("krait", "armv7-a", "neon-vfpv4",
-                         ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
-                         "7-A"),
-        ARMCPUTestParams("cortex-r4", "armv7-r", "none",
-                         ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+        ARMCPUTestParams<uint64_t>("cortex-a9", "armv7-a", "neon-fp16",
+                                   ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP, "7-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a12", "armv7-a", "neon-vfpv4",
+                                   ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
+                                       ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+                                       ARM::AEK_DSP,
+                                   "7-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a15", "armv7-a", "neon-vfpv4",
+                                   ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
+                                       ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+                                       ARM::AEK_DSP,
+                                   "7-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a17", "armv7-a", "neon-vfpv4",
+                                   ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
+                                       ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+                                       ARM::AEK_DSP,
+                                   "7-A"),
+        ARMCPUTestParams<uint64_t>("krait", "armv7-a", "neon-vfpv4",
+                                   ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                                   "7-A"),
+        ARMCPUTestParams<uint64_t>("cortex-r4", "armv7-r", "none",
+                                   ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
                          "7-R"),
-        ARMCPUTestParams("cortex-r4f", "armv7-r", "vfpv3-d16",
+        ARMCPUTestParams<uint64_t>("cortex-r4f", "armv7-r", "vfpv3-d16",
                          ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
                          "7-R"),
-        ARMCPUTestParams("cortex-r5", "armv7-r", "vfpv3-d16",
-                         ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
-                             ARM::AEK_DSP,
-                         "7-R"),
-        ARMCPUTestParams("cortex-r7", "armv7-r", "vfpv3-d16-fp16",
+        ARMCPUTestParams<uint64_t>("cortex-r5", "armv7-r", "vfpv3-d16",
                          ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+                                       ARM::AEK_DSP,
+                                   "7-R"),
+        ARMCPUTestParams<uint64_t>("cortex-r7", "armv7-r", "vfpv3-d16-fp16",
+                                   ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+                                       ARM::AEK_DSP,
+                                   "7-R"),
+        ARMCPUTestParams<uint64_t>("cortex-r8", "armv7-r", "vfpv3-d16-fp16",
+                                   ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
                              ARM::AEK_DSP,
-                         "7-R"),
-        ARMCPUTestParams("cortex-r8", "armv7-r", "vfpv3-d16-fp16",
-                         ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
-                             ARM::AEK_DSP,
-                         "7-R"),
-        ARMCPUTestParams("cortex-r52", "armv8-r", "neon-fp-armv8",
-                         ARM::AEK_NONE | ARM::AEK_CRC | ARM::AEK_MP |
-                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
-                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
-                         "8-R"),
-        ARMCPUTestParams("sc300", "armv7-m", "none",
-                         ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "7-M"),
-        ARMCPUTestParams("cortex-m3", "armv7-m", "none",
-                         ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "7-M"),
-        ARMCPUTestParams("cortex-m4", "armv7e-m", "fpv4-sp-d16",
-                         ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
-                         "7E-M"),
-        ARMCPUTestParams("cortex-m7", "armv7e-m", "fpv5-d16",
-                         ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
-                         "7E-M"),
-        ARMCPUTestParams("cortex-a32", "armv8-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
-                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
-                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
-                         "8-A"),
-        ARMCPUTestParams("cortex-a35", "armv8-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
-                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
-                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
-                         "8-A"),
-        ARMCPUTestParams("cortex-a53", "armv8-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
-                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
-                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
-                         "8-A"),
-        ARMCPUTestParams("cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                                   "7-R"),
+        ARMCPUTestParams<uint64_t>("cortex-r52", "armv8-r", "neon-fp-armv8",
+                                   ARM::AEK_NONE | ARM::AEK_CRC | ARM::AEK_MP |
+                                       ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                                       ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                                   "8-R"),
+        ARMCPUTestParams<uint64_t>("sc300", "armv7-m", "none",
+                                   ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "7-M"),
+        ARMCPUTestParams<uint64_t>("cortex-m3", "armv7-m", "none",
+                                   ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "7-M"),
+        ARMCPUTestParams<uint64_t>("cortex-m4", "armv7e-m", "fpv4-sp-d16",
+                                   ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                                   "7E-M"),
+        ARMCPUTestParams<uint64_t>("cortex-m7", "armv7e-m", "fpv5-d16",
+                                   ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                                   "7E-M"),
+        ARMCPUTestParams<uint64_t>("cortex-a32", "armv8-a", "crypto-neon-fp-armv8",
+                                   ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                                       ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                                       ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                                   "8-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a35", "armv8-a", "crypto-neon-fp-armv8",
+                                   ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                                       ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                                       ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                                   "8-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a53", "armv8-a", "crypto-neon-fp-armv8",
+                                   ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                                       ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                                       ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                                   "8-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",
+            ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
                              ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
                              ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
-                             ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-a57", "armv8-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
-                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
-                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
-                         "8-A"),
-        ARMCPUTestParams("cortex-a72", "armv8-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
-                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
-                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
-                         "8-A"),
-        ARMCPUTestParams("cortex-a73", "armv8-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
-                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
-                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
-                         "8-A"),
-        ARMCPUTestParams("cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
+            "8.2-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a57", "armv8-a", "crypto-neon-fp-armv8",
+                                   ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                                       ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                                       ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                                   "8-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a72", "armv8-a", "crypto-neon-fp-armv8",
+                                   ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                                       ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                                       ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                                   "8-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a73", "armv8-a", "crypto-neon-fp-armv8",
+                                   ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                                       ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                                       ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                                   "8-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",
+            ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
                              ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
                              ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
-                             ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
+            "8.2-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8",
+            ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
                              ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
                              ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
-                             ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
+            "8.2-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",
+            ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
                              ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
                              ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
-                             ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-a78c", "armv8.2-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
+                ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
+            "8.2-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a78c", "armv8.2-a", "crypto-neon-fp-armv8",
+            ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
                              ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
                              ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS |
                              ARM::AEK_FP16 | ARM::AEK_DOTPROD,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-a710", "armv9-a", "neon-fp-armv8",
-                         ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
-                             ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
-                             ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS |
+            "8.2-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a710", "armv9-a", "neon-fp-armv8",
+                                   ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
+                                       ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+                                       ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS |
                              ARM::AEK_DOTPROD | ARM::AEK_FP16FML |
                              ARM::AEK_BF16 | ARM::AEK_I8MM | ARM::AEK_SB,
-                         "9-A"),
-        ARMCPUTestParams("cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                                   "9-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8",
+            ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
                              ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
                              ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
-                             ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_SEC |
-                             ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
-                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC |
+                ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
+            "8.2-A"),
+        ARMCPUTestParams<uint64_t>("cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8",
+            ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_SEC |
+                ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC |
                              ARM::AEK_RAS,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD |
+            "8.2-A"),
+        ARMCPUTestParams<uint64_t>("cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8",
+            ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD |
                              ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
                              ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
                              ARM::AEK_DSP | ARM::AEK_CRC,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8",
+            "8.2-A"),
+        ARMCPUTestParams<uint64_t>("cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8",
                          ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD |
                              ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
                              ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
                              ARM::AEK_DSP | ARM::AEK_CRC,
                          "8.2-A"),
-        ARMCPUTestParams("neoverse-n1", "armv8.2-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+        ARMCPUTestParams<uint64_t>("neoverse-n1", "armv8.2-a", "crypto-neon-fp-armv8",
+            ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
                              ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
                              ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
-                             ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
-                         "8.2-A"),
-        ARMCPUTestParams("neoverse-n2", "armv8.5-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_HWDIVTHUMB |
+                ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
+            "8.2-A"),
+        ARMCPUTestParams<uint64_t>("neoverse-n2", "armv8.5-a", "crypto-neon-fp-armv8",
+            ARM::AEK_CRC | ARM::AEK_HWDIVTHUMB |
                              ARM::AEK_HWDIVARM | ARM::AEK_MP | ARM::AEK_SEC |
                              ARM::AEK_VIRT | ARM::AEK_DSP | ARM::AEK_BF16 |
                              ARM::AEK_DOTPROD | ARM::AEK_RAS | ARM::AEK_I8MM |
                              ARM::AEK_SB,
-                         "8.5-A"),
-        ARMCPUTestParams("neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
+            "8.5-A"),
+        ARMCPUTestParams<uint64_t>("neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8",
+            ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
                              ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
                              ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS |
                              ARM::AEK_FP16 | ARM::AEK_BF16 | ARM::AEK_DOTPROD,
-                         "8.4-A"),
-        ARMCPUTestParams("cyclone", "armv8-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
-                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
-                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
-                         "8-A"),
-        ARMCPUTestParams("exynos-m3", "armv8-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
-                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
-                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
-                         "8-A"),
-        ARMCPUTestParams("exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+            "8.4-A"),
+        ARMCPUTestParams<uint64_t>("cyclone", "armv8-a", "crypto-neon-fp-armv8",
+                                   ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                                       ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                                       ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                                   "8-A"),
+        ARMCPUTestParams<uint64_t>("exynos-m3", "armv8-a", "crypto-neon-fp-armv8",
+                                   ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                                       ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                                       ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                                   "8-A"),
+        ARMCPUTestParams<uint64_t>("exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8",
+            ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
                              ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
                              ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
-                             ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS,
-                         "8.2-A"),
-        ARMCPUTestParams("exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
-                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS,
+            "8.2-A"),
+        ARMCPUTestParams<uint64_t>("exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
+            ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
                              ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
                              ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
-                             ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-m23", "armv8-m.base", "none",
-                         ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "8-M.Baseline"),
-        ARMCPUTestParams("cortex-m33", "armv8-m.main", "fpv5-sp-d16",
-                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "8-M.Mainline"),
-        ARMCPUTestParams("cortex-m35p", "armv8-m.main", "fpv5-sp-d16",
-                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "8-M.Mainline"),
-        ARMCPUTestParams("cortex-m55", "armv8.1-m.main",
+                ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS,
+            "8.2-A"),
+        ARMCPUTestParams<uint64_t>("cortex-m23", "armv8-m.base", "none",
+                                   ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "8-M.Baseline"),
+        ARMCPUTestParams<uint64_t>("cortex-m33", "armv8-m.main", "fpv5-sp-d16",
+                                   ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "8-M.Mainline"),
+        ARMCPUTestParams<uint64_t>("cortex-m35p", "armv8-m.main", "fpv5-sp-d16",
+                                   ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "8-M.Mainline"),
+        ARMCPUTestParams<uint64_t>("cortex-m55", "armv8.1-m.main",
                          "fp-armv8-fullfp16-d16",
-                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD |
+            ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD |
                              ARM::AEK_FP | ARM::AEK_RAS | ARM::AEK_LOB |
                              ARM::AEK_FP16,
-                         "8.1-M.Mainline"),
-        ARMCPUTestParams("cortex-m85", "armv8.1-m.main",
+            "8.1-M.Mainline"),
+        ARMCPUTestParams<uint64_t>("cortex-m85", "armv8.1-m.main",
                          "fp-armv8-fullfp16-d16",
-                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD |
+            ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD |
                              ARM::AEK_FP | ARM::AEK_RAS | ARM::AEK_LOB |
                              ARM::AEK_FP16 | ARM::AEK_PACBTI,
-                         "8.1-M.Mainline"),
-        ARMCPUTestParams("iwmmxt", "iwmmxt", "none", ARM::AEK_NONE, "iwmmxt"),
-        ARMCPUTestParams("xscale", "xscale", "none", ARM::AEK_NONE, "xscale"),
-        ARMCPUTestParams("swift", "armv7s", "neon-vfpv4",
-                         ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
-                         "7-S")));
+            "8.1-M.Mainline"),
+        ARMCPUTestParams<uint64_t>("iwmmxt", "iwmmxt", "none", ARM::AEK_NONE, "iwmmxt"),
+        ARMCPUTestParams<uint64_t>("xscale", "xscale", "none", ARM::AEK_NONE, "xscale"),
+        ARMCPUTestParams<uint64_t>("swift", "armv7s", "neon-vfpv4",
+                                   ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                                   "7-S")));
 
 static constexpr unsigned NumARMCPUArchs = 89;
 
@@ -957,7 +1011,8 @@ TEST(TargetParserTest, getARMCPUForArch) {
 }
 
 class AArch64CPUTestFixture
-    : public ::testing::TestWithParam<ARMCPUTestParams> {};
+    : public ::testing::TestWithParam<
+          ARMCPUTestParams<AArch64::ExtensionBitset>> {};
 
 TEST_P(AArch64CPUTestFixture, testAArch64CPU) {
   ARMCPUTestParams params = GetParam();
@@ -974,467 +1029,513 @@ TEST_P(AArch64CPUTestFixture, testAArch64CPU) {
 INSTANTIATE_TEST_SUITE_P(
     AArch64CPUTests, AArch64CPUTestFixture,
     ::testing::Values(
-        ARMCPUTestParams("cortex-a34", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD,
-                         "8-A"),
-        ARMCPUTestParams("cortex-a35", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD,
-                         "8-A"),
-        ARMCPUTestParams("cortex-a53", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD,
-                         "8-A"),
-        ARMCPUTestParams("cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD | AArch64::AEK_RAS |
-                             AArch64::AEK_LSE | AArch64::AEK_RDM |
-                             AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_RCPC,
-                         "8.2-A"),
-        ARMCPUTestParams(
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a34", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a35", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a53", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_RAS,
+                 AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_FP16,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-a510", "armv9-a", "neon-fp-armv8",
-            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_SVE2BITPERM | AArch64::AEK_PAUTH |
-                AArch64::AEK_MTE | AArch64::AEK_SSBS | AArch64::AEK_FP16 |
-                AArch64::AEK_FP16FML | AArch64::AEK_SB,
+            (AArch64::ExtensionBitset(
+                {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_SVE2BITPERM, AArch64::AEK_PAUTH, AArch64::AEK_MTE,
+                 AArch64::AEK_SSBS, AArch64::AEK_FP16, AArch64::AEK_FP16FML,
+                 AArch64::AEK_SB})),
             "9-A"),
-        ARMCPUTestParams("cortex-a57", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD,
-                         "8-A"),
-        ARMCPUTestParams("cortex-a65", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_FP | AArch64::AEK_FP16 |
-                             AArch64::AEK_LSE | AArch64::AEK_RAS |
-                             AArch64::AEK_RCPC | AArch64::AEK_RDM |
-                             AArch64::AEK_SIMD | AArch64::AEK_SSBS,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-a65ae", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_FP | AArch64::AEK_FP16 |
-                             AArch64::AEK_LSE | AArch64::AEK_RAS |
-                             AArch64::AEK_RCPC | AArch64::AEK_RDM |
-                             AArch64::AEK_SIMD | AArch64::AEK_SSBS,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-a72", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD,
-                         "8-A"),
-        ARMCPUTestParams("cortex-a73", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD,
-                         "8-A"),
-        ARMCPUTestParams("cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD | AArch64::AEK_RAS |
-                             AArch64::AEK_LSE | AArch64::AEK_RDM |
-                             AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_RCPC,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_RDM | AArch64::AEK_SIMD |
-                             AArch64::AEK_RAS | AArch64::AEK_LSE |
-                             AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_RCPC | AArch64::AEK_SSBS,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_RDM | AArch64::AEK_SIMD |
-                             AArch64::AEK_RAS | AArch64::AEK_LSE |
-                             AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_RCPC | AArch64::AEK_SSBS,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_RDM | AArch64::AEK_SIMD |
-                             AArch64::AEK_RAS | AArch64::AEK_LSE |
-                             AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_RCPC | AArch64::AEK_SSBS,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_RDM | AArch64::AEK_SIMD |
-                             AArch64::AEK_RAS | AArch64::AEK_LSE |
-                             AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_RCPC | AArch64::AEK_SSBS |
-                             AArch64::AEK_PROFILE,
-                         "8.2-A"),
-        ARMCPUTestParams(
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a57", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a65", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16,
+                 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RCPC,
+                 AArch64::AEK_RDM, AArch64::AEK_SIMD, AArch64::AEK_SSBS})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a65ae", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16,
+                 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RCPC,
+                 AArch64::AEK_RDM, AArch64::AEK_SIMD, AArch64::AEK_SSBS})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a72", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a73", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_RAS,
+                 AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_FP16,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD,
+                 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD,
+                 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD,
+                 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD,
+                 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS,
+                 AArch64::AEK_PROFILE})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-a78c", "armv8.2-a", "crypto-neon-fp-armv8",
-            AArch64::AEK_RAS | AArch64::AEK_CRC | AArch64::AEK_AES |
-                AArch64::AEK_SHA2 | AArch64::AEK_FP | AArch64::AEK_SIMD |
-                AArch64::AEK_RAS | AArch64::AEK_LSE | AArch64::AEK_RDM |
-                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::ExtensionBitset(
+                {AArch64::AEK_RAS, AArch64::AEK_CRC, AArch64::AEK_AES,
+                 AArch64::AEK_SHA2, AArch64::AEK_FP, AArch64::AEK_SIMD,
+                 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_RDM,
+                 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC,
+                 AArch64::AEK_SSBS, AArch64::AEK_PROFILE, AArch64::AEK_FLAGM,
+                 AArch64::AEK_PAUTH, AArch64::AEK_FP16FML})),
             "8.2-A"),
-        ARMCPUTestParams(
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-a710", "armv9-a", "neon-fp-armv8",
-            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_MTE |
-                AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SVE |
-                AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM |
-                AArch64::AEK_PAUTH | AArch64::AEK_FLAGM | AArch64::AEK_SB |
-                AArch64::AEK_I8MM | AArch64::AEK_BF16,
+            (AArch64::ExtensionBitset(
+                {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_MTE,
+                 AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_SVE,
+                 AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM,
+                 AArch64::AEK_PAUTH, AArch64::AEK_FLAGM, AArch64::AEK_SB,
+                 AArch64::AEK_I8MM, AArch64::AEK_BF16})),
             "9-A"),
-        ARMCPUTestParams(
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
             "cortex-a715", "armv9-a", "neon-fp-armv8",
-            AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_BF16 |
-                AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
-                AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
-                AArch64::AEK_MTE | AArch64::AEK_PAUTH | AArch64::AEK_SVE |
-                AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM |
-                AArch64::AEK_SSBS | AArch64::AEK_SB | AArch64::AEK_I8MM |
-                AArch64::AEK_PERFMON | AArch64::AEK_PREDRES |
-                AArch64::AEK_PROFILE | AArch64::AEK_FP16FML |
-                AArch64::AEK_FP16 | AArch64::AEK_FLAGM,
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC,     AArch64::AEK_FP,
+                 AArch64::AEK_BF16,    AArch64::AEK_SIMD,
+                 AArch64::AEK_RAS,     AArch64::AEK_LSE,
+                 AArch64::AEK_RDM,     AArch64::AEK_RCPC,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_MTE,
+                 AArch64::AEK_PAUTH,   AArch64::AEK_SVE,
+                 AArch64::AEK_SVE2,    AArch64::AEK_SVE2BITPERM,
+                 AArch64::AEK_SSBS,    AArch64::AEK_SB,
+                 AArch64::AEK_I8MM,    AArch64::AEK_PERFMON,
+                 AArch64::AEK_PREDRES, AArch64::AEK_PROFILE,
+                 AArch64::AEK_FP16FML, AArch64::AEK_FP16,
+                 AArch64::AEK_FLAGM})),
             "9-A"),
-        ARMCPUTestParams(
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
             "neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8",
-            AArch64::AEK_RAS | AArch64::AEK_SVE | AArch64::AEK_SSBS |
-                AArch64::AEK_RCPC | 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_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-                AArch64::AEK_SM4 | AArch64::AEK_FP16 | AArch64::AEK_BF16 |
-                AArch64::AEK_PROFILE | AArch64::AEK_RAND |
-                AArch64::AEK_FP16FML | AArch64::AEK_I8MM,
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_RAS,     AArch64::AEK_SVE,  AArch64::AEK_SSBS,
+                 AArch64::AEK_RCPC,    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_AES,     AArch64::AEK_SHA2, AArch64::AEK_SHA3,
+                 AArch64::AEK_SM4,     AArch64::AEK_FP16, AArch64::AEK_BF16,
+                 AArch64::AEK_PROFILE, AArch64::AEK_RAND, AArch64::AEK_FP16FML,
+                 AArch64::AEK_I8MM})),
             "8.4-A"),
-        ARMCPUTestParams("neoverse-v2", "armv9-a", "neon-fp-armv8",
-                         AArch64::AEK_RAS | AArch64::AEK_SVE |
-                             AArch64::AEK_SSBS | AArch64::AEK_RCPC |
-                             AArch64::AEK_CRC | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD | AArch64::AEK_MTE |
-                             AArch64::AEK_LSE | AArch64::AEK_RDM |
-                             AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_FP16 | AArch64::AEK_BF16 |
-                             AArch64::AEK_SVE2 | AArch64::AEK_PROFILE |
-                             AArch64::AEK_FP16FML | AArch64::AEK_I8MM |
-                             AArch64::AEK_SVE2BITPERM | AArch64::AEK_RAND,
-                         "9-A"),
-        ARMCPUTestParams("cortex-r82", "armv8-r", "crypto-neon-fp-armv8",
-                         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_LSE | AArch64::AEK_SB,
-                         "8-R"),
-        ARMCPUTestParams("cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_RDM | AArch64::AEK_SIMD |
-                             AArch64::AEK_RAS | AArch64::AEK_LSE |
-                             AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_RCPC | AArch64::AEK_SSBS |
-                             AArch64::AEK_PROFILE,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_RDM | AArch64::AEK_SIMD |
-                             AArch64::AEK_RAS | AArch64::AEK_LSE |
-                             AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_RCPC | AArch64::AEK_SSBS |
-                             AArch64::AEK_PAUTH | AArch64::AEK_PROFILE,
-                         "8.2-A"),
-        ARMCPUTestParams("cortex-x2", "armv9-a", "neon-fp-armv8",
-                         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_MTE | AArch64::AEK_PAUTH |
-                             AArch64::AEK_I8MM | AArch64::AEK_BF16 |
-                             AArch64::AEK_SVE | AArch64::AEK_SVE2 |
-                             AArch64::AEK_SVE2BITPERM | AArch64::AEK_SSBS |
-                             AArch64::AEK_SB | AArch64::AEK_FP16 |
-                             AArch64::AEK_FP16FML,
-                         "9-A"),
-        ARMCPUTestParams(
-            "cortex-x3",
-            "armv9-a", "neon-fp-armv8",
-            AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_BF16 |
-                AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
-                AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
-                AArch64::AEK_MTE | AArch64::AEK_PAUTH | AArch64::AEK_SVE |
-                AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM | AArch64::AEK_SB |
-                AArch64::AEK_PROFILE | AArch64::AEK_PERFMON |
-                AArch64::AEK_I8MM | AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
-                AArch64::AEK_PREDRES | AArch64::AEK_FLAGM | AArch64::AEK_SSBS,
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "neoverse-v2", "armv9-a", "neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_RAS,         AArch64::AEK_SVE,
+                 AArch64::AEK_SSBS,        AArch64::AEK_RCPC,
+                 AArch64::AEK_CRC,         AArch64::AEK_FP,
+                 AArch64::AEK_SIMD,        AArch64::AEK_MTE,
+                 AArch64::AEK_LSE,         AArch64::AEK_RDM,
+                 AArch64::AEK_RCPC,        AArch64::AEK_DOTPROD,
+                 AArch64::AEK_FP16,        AArch64::AEK_BF16,
+                 AArch64::AEK_SVE2,        AArch64::AEK_PROFILE,
+                 AArch64::AEK_FP16FML,     AArch64::AEK_I8MM,
+                 AArch64::AEK_SVE2BITPERM, AArch64::AEK_RAND})),
             "9-A"),
-        ARMCPUTestParams("cyclone", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_NONE | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD,
-                         "8-A"),
-        ARMCPUTestParams("apple-a7", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_NONE | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD,
-                         "8-A"),
-        ARMCPUTestParams("apple-a8", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_NONE | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD,
-                         "8-A"),
-        ARMCPUTestParams("apple-a9", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_NONE | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD,
-                         "8-A"),
-        ARMCPUTestParams("apple-a10", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_RDM | AArch64::AEK_SIMD,
-                         "8-A"),
-        ARMCPUTestParams("apple-a11", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_LSE | AArch64::AEK_RAS |
-                             AArch64::AEK_RDM | AArch64::AEK_SIMD |
-                             AArch64::AEK_FP16,
-                         "8.2-A"),
-        ARMCPUTestParams("apple-a12", "armv8.3-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD | AArch64::AEK_LSE |
-                             AArch64::AEK_RAS | AArch64::AEK_RDM |
-                             AArch64::AEK_RCPC | AArch64::AEK_FP16,
-                         "8.3-A"),
-        ARMCPUTestParams("apple-a13", "armv8.4-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-                             AArch64::AEK_FP | AArch64::AEK_SIMD |
-                             AArch64::AEK_LSE | AArch64::AEK_RAS |
-                             AArch64::AEK_RDM | AArch64::AEK_RCPC |
-                             AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
-                             AArch64::AEK_FP16FML | AArch64::AEK_SHA3,
-                         "8.4-A"),
-        ARMCPUTestParams("apple-a14", "armv8.5-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-                             AArch64::AEK_FP | AArch64::AEK_SIMD |
-                             AArch64::AEK_LSE | AArch64::AEK_RAS |
-                             AArch64::AEK_RDM | AArch64::AEK_RCPC |
-                             AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
-                             AArch64::AEK_FP16FML | AArch64::AEK_SHA3,
-                         "8.5-A"),
-        ARMCPUTestParams("apple-a15", "armv8.5-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-                             AArch64::AEK_FP | AArch64::AEK_SIMD |
-                             AArch64::AEK_LSE | AArch64::AEK_RAS |
-                             AArch64::AEK_RDM | AArch64::AEK_RCPC |
-                             AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
-                             AArch64::AEK_FP16FML | AArch64::AEK_SHA3 |
-                             AArch64::AEK_BF16 | AArch64::AEK_I8MM,
-                         "8.5-A"),
-        ARMCPUTestParams("apple-a16", "armv8.5-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-                             AArch64::AEK_FP | AArch64::AEK_SIMD |
-                             AArch64::AEK_LSE | AArch64::AEK_RAS |
-                             AArch64::AEK_RDM | AArch64::AEK_RCPC |
-                             AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
-                             AArch64::AEK_FP16FML | AArch64::AEK_SHA3 |
-                             AArch64::AEK_BF16 | AArch64::AEK_I8MM,
-                         "8.5-A"),
-        ARMCPUTestParams("apple-m1", "armv8.5-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-                             AArch64::AEK_FP | AArch64::AEK_SIMD |
-                             AArch64::AEK_LSE | AArch64::AEK_RAS |
-                             AArch64::AEK_RDM | AArch64::AEK_RCPC |
-                             AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
-                             AArch64::AEK_FP16FML | AArch64::AEK_SHA3,
-                         "8.5-A"),
-        ARMCPUTestParams("apple-m2", "armv8.5-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-                             AArch64::AEK_FP | AArch64::AEK_SIMD |
-                             AArch64::AEK_LSE | AArch64::AEK_RAS |
-                             AArch64::AEK_RDM | AArch64::AEK_RCPC |
-                             AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
-                             AArch64::AEK_FP16FML | AArch64::AEK_SHA3 |
-                             AArch64::AEK_BF16 | AArch64::AEK_I8MM,
-                         "8.5-A"),
-        ARMCPUTestParams("apple-s4", "armv8.3-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD | AArch64::AEK_LSE |
-                             AArch64::AEK_RAS | AArch64::AEK_RDM |
-                             AArch64::AEK_RCPC | AArch64::AEK_FP16,
-                         "8.3-A"),
-        ARMCPUTestParams("apple-s5", "armv8.3-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD | AArch64::AEK_LSE |
-                             AArch64::AEK_RAS | AArch64::AEK_RDM |
-                             AArch64::AEK_RCPC | AArch64::AEK_FP16,
-                         "8.3-A"),
-        ARMCPUTestParams("exynos-m3", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD,
-                         "8-A"),
-        ARMCPUTestParams("exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_FP | AArch64::AEK_FP16 |
-                             AArch64::AEK_LSE | AArch64::AEK_RAS |
-                             AArch64::AEK_RDM | AArch64::AEK_SIMD,
-                         "8.2-A"),
-        ARMCPUTestParams("exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_FP | AArch64::AEK_FP16 |
-                             AArch64::AEK_LSE | AArch64::AEK_RAS |
-                             AArch64::AEK_RDM | AArch64::AEK_SIMD,
-                         "8.2-A"),
-        ARMCPUTestParams("falkor", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD | AArch64::AEK_RDM,
-                         "8-A"),
-        ARMCPUTestParams("kryo", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD,
-                         "8-A"),
-        ARMCPUTestParams("neoverse-e1", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_FP | AArch64::AEK_FP16 |
-                             AArch64::AEK_LSE | AArch64::AEK_RAS |
-                             AArch64::AEK_RCPC | AArch64::AEK_RDM |
-                             AArch64::AEK_SIMD | AArch64::AEK_SSBS,
-                         "8.2-A"),
-        ARMCPUTestParams("neoverse-n1", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD |
-                             AArch64::AEK_FP | AArch64::AEK_FP16 |
-                             AArch64::AEK_LSE | AArch64::AEK_PROFILE |
-                             AArch64::AEK_RAS | AArch64::AEK_RCPC |
-                             AArch64::AEK_RDM | AArch64::AEK_SIMD |
-                             AArch64::AEK_SSBS,
-                         "8.2-A"),
-        ARMCPUTestParams(
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-r82", "armv8-r", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {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_LSE, AArch64::AEK_SB})),
+            "8-R"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD,
+                 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS,
+                 AArch64::AEK_PROFILE})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD,
+                 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS,
+                 AArch64::AEK_PAUTH, AArch64::AEK_PROFILE})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-x2", "armv9-a", "neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {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_MTE,
+                 AArch64::AEK_PAUTH, AArch64::AEK_I8MM, AArch64::AEK_BF16,
+                 AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM,
+                 AArch64::AEK_SSBS, AArch64::AEK_SB, AArch64::AEK_FP16,
+                 AArch64::AEK_FP16FML})),
+            "9-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cortex-x3", "armv9-a", "neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC,     AArch64::AEK_FP,
+                 AArch64::AEK_BF16,    AArch64::AEK_SIMD,
+                 AArch64::AEK_RAS,     AArch64::AEK_LSE,
+                 AArch64::AEK_RDM,     AArch64::AEK_RCPC,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_MTE,
+                 AArch64::AEK_PAUTH,   AArch64::AEK_SVE,
+                 AArch64::AEK_SVE2,    AArch64::AEK_SVE2BITPERM,
+                 AArch64::AEK_SB,      AArch64::AEK_PROFILE,
+                 AArch64::AEK_PERFMON, AArch64::AEK_I8MM,
+                 AArch64::AEK_FP16,    AArch64::AEK_FP16FML,
+                 AArch64::AEK_PREDRES, AArch64::AEK_FLAGM,
+                 AArch64::AEK_SSBS})),
+            "9-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "cyclone", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_NONE, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-a7", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_NONE, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-a8", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_NONE, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-a9", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_NONE, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-a10", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-a11", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_LSE, AArch64::AEK_RAS,
+                 AArch64::AEK_RDM, AArch64::AEK_SIMD, AArch64::AEK_FP16})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-a12", "armv8.3-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_LSE,
+                 AArch64::AEK_RAS, AArch64::AEK_RDM, AArch64::AEK_RCPC,
+                 AArch64::AEK_FP16})),
+            "8.3-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-a13", "armv8.4-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD,
+                 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
+                 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
+                 AArch64::AEK_FP16FML, AArch64::AEK_SHA3})),
+            "8.4-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-a14", "armv8.5-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD,
+                 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
+                 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
+                 AArch64::AEK_FP16FML, AArch64::AEK_SHA3})),
+            "8.5-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-a15", "armv8.5-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD,
+                 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
+                 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
+                 AArch64::AEK_FP16FML, AArch64::AEK_SHA3, AArch64::AEK_BF16,
+                 AArch64::AEK_I8MM})),
+            "8.5-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-a16", "armv8.5-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD,
+                 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
+                 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
+                 AArch64::AEK_FP16FML, AArch64::AEK_SHA3, AArch64::AEK_BF16,
+                 AArch64::AEK_I8MM})),
+            "8.5-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-m1", "armv8.5-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD,
+                 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
+                 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
+                 AArch64::AEK_FP16FML, AArch64::AEK_SHA3})),
+            "8.5-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-m2", "armv8.5-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD,
+                 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
+                 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
+                 AArch64::AEK_FP16FML, AArch64::AEK_SHA3, AArch64::AEK_BF16,
+                 AArch64::AEK_I8MM})),
+            "8.5-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-s4", "armv8.3-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_LSE,
+                 AArch64::AEK_RAS, AArch64::AEK_RDM, AArch64::AEK_RCPC,
+                 AArch64::AEK_FP16})),
+            "8.3-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "apple-s5", "armv8.3-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_LSE,
+                 AArch64::AEK_RAS, AArch64::AEK_RDM, AArch64::AEK_RCPC,
+                 AArch64::AEK_FP16})),
+            "8.3-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "exynos-m3", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16,
+                 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
+                 AArch64::AEK_SIMD})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16,
+                 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
+                 AArch64::AEK_SIMD})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "falkor", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_RDM})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "kryo", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "neoverse-e1", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16,
+                 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RCPC,
+                 AArch64::AEK_RDM, AArch64::AEK_SIMD, AArch64::AEK_SSBS})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "neoverse-n1", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16,
+                 AArch64::AEK_LSE, AArch64::AEK_PROFILE, AArch64::AEK_RAS,
+                 AArch64::AEK_RCPC, AArch64::AEK_RDM, AArch64::AEK_SIMD,
+                 AArch64::AEK_SSBS})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
             "neoverse-n2", "armv8.5-a", "crypto-neon-fp-armv8",
-            AArch64::AEK_CRC | AArch64::AEK_AES | AArch64::AEK_SHA2 |
-                AArch64::AEK_SHA3 | AArch64::AEK_SM4 | AArch64::AEK_FP |
-                AArch64::AEK_SIMD | AArch64::AEK_FP16 | AArch64::AEK_RAS |
-                AArch64::AEK_LSE | AArch64::AEK_SVE | AArch64::AEK_DOTPROD |
-                AArch64::AEK_RCPC | AArch64::AEK_RDM | AArch64::AEK_MTE |
-                AArch64::AEK_SSBS | AArch64::AEK_SB | AArch64::AEK_SVE2 |
-                AArch64::AEK_SVE2BITPERM | AArch64::AEK_BF16 |
-                AArch64::AEK_I8MM,
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC,         AArch64::AEK_AES,
+                 AArch64::AEK_SHA2,        AArch64::AEK_SHA3,
+                 AArch64::AEK_SM4,         AArch64::AEK_FP,
+                 AArch64::AEK_SIMD,        AArch64::AEK_FP16,
+                 AArch64::AEK_RAS,         AArch64::AEK_LSE,
+                 AArch64::AEK_SVE,         AArch64::AEK_DOTPROD,
+                 AArch64::AEK_RCPC,        AArch64::AEK_RDM,
+                 AArch64::AEK_MTE,         AArch64::AEK_SSBS,
+                 AArch64::AEK_SB,          AArch64::AEK_SVE2,
+                 AArch64::AEK_SVE2BITPERM, AArch64::AEK_BF16,
+                 AArch64::AEK_I8MM})),
             "8.5-A"),
-        ARMCPUTestParams(
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
             "ampere1", "armv8.6-a", "crypto-neon-fp-armv8",
-            AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_FP16 |
-                AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
-                AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
-                AArch64::AEK_SHA3 | AArch64::AEK_BF16 | AArch64::AEK_SHA2 |
-                AArch64::AEK_AES | AArch64::AEK_I8MM | AArch64::AEK_SSBS |
-                AArch64::AEK_SB | AArch64::AEK_RAND,
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_FP, AArch64::AEK_FP16,
+                 AArch64::AEK_SIMD, AArch64::AEK_RAS, AArch64::AEK_LSE,
+                 AArch64::AEK_RDM, AArch64::AEK_RCPC, AArch64::AEK_DOTPROD,
+                 AArch64::AEK_SHA3, AArch64::AEK_BF16, AArch64::AEK_SHA2,
+                 AArch64::AEK_AES, AArch64::AEK_I8MM, AArch64::AEK_SSBS,
+                 AArch64::AEK_SB, AArch64::AEK_RAND})),
             "8.6-A"),
-        ARMCPUTestParams(
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
             "ampere1a", "armv8.6-a", "crypto-neon-fp-armv8",
-            AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_FP16 |
-                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_SSBS | AArch64::AEK_SB | AArch64::AEK_RAND |
-                AArch64::AEK_MTE,
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_FP, AArch64::AEK_FP16,
+                 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_SSBS, AArch64::AEK_SB, AArch64::AEK_RAND,
+                 AArch64::AEK_MTE})),
             "8.6-A"),
-        ARMCPUTestParams(
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
             "neoverse-512tvb", "armv8.4-a", "crypto-neon-fp-armv8",
-            AArch64::AEK_RAS | AArch64::AEK_SVE | AArch64::AEK_SSBS |
-                AArch64::AEK_RCPC | 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_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 |
-                AArch64::AEK_SM4 | AArch64::AEK_FP16 | AArch64::AEK_BF16 |
-                AArch64::AEK_PROFILE | AArch64::AEK_RAND |
-                AArch64::AEK_FP16FML | AArch64::AEK_I8MM,
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_RAS,     AArch64::AEK_SVE,  AArch64::AEK_SSBS,
+                 AArch64::AEK_RCPC,    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_AES,     AArch64::AEK_SHA2, AArch64::AEK_SHA3,
+                 AArch64::AEK_SM4,     AArch64::AEK_FP16, AArch64::AEK_BF16,
+                 AArch64::AEK_PROFILE, AArch64::AEK_RAND, AArch64::AEK_FP16FML,
+                 AArch64::AEK_I8MM})),
             "8.4-A"),
-        ARMCPUTestParams("thunderx2t99", "armv8.1-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_LSE |
-                             AArch64::AEK_RDM | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD,
-                         "8.1-A"),
-        ARMCPUTestParams("thunderx3t110", "armv8.3-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_LSE |
-                             AArch64::AEK_RDM | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD | AArch64::AEK_RAS |
-                             AArch64::AEK_RCPC,
-                         "8.3-A"),
-        ARMCPUTestParams("thunderx", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_SIMD |
-                             AArch64::AEK_FP,
-                         "8-A"),
-        ARMCPUTestParams("thunderxt81", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_SIMD |
-                             AArch64::AEK_FP,
-                         "8-A"),
-        ARMCPUTestParams("thunderxt83", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_SIMD |
-                             AArch64::AEK_FP,
-                         "8-A"),
-        ARMCPUTestParams("thunderxt88", "armv8-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_SIMD |
-                             AArch64::AEK_FP,
-                         "8-A"),
-        ARMCPUTestParams("tsv110", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD | AArch64::AEK_RAS |
-                             AArch64::AEK_LSE | AArch64::AEK_RDM |
-                             AArch64::AEK_PROFILE | AArch64::AEK_FP16 |
-                             AArch64::AEK_FP16FML | AArch64::AEK_DOTPROD,
-                         "8.2-A"),
-        ARMCPUTestParams("a64fx", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD | AArch64::AEK_FP16 |
-                             AArch64::AEK_RAS | AArch64::AEK_LSE |
-                             AArch64::AEK_SVE | AArch64::AEK_RDM,
-                         "8.2-A"),
-        ARMCPUTestParams("carmel", "armv8.2-a", "crypto-neon-fp-armv8",
-                         AArch64::AEK_CRC | AArch64::AEK_AES |
-                             AArch64::AEK_SHA2 | AArch64::AEK_FP |
-                             AArch64::AEK_SIMD | AArch64::AEK_FP16 |
-                             AArch64::AEK_RAS | AArch64::AEK_LSE |
-                             AArch64::AEK_RDM,
-                         "8.2-A")));
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "thunderx2t99", "armv8.1-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_FP,
+                 AArch64::AEK_SIMD})),
+            "8.1-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "thunderx3t110", "armv8.3-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_FP,
+                 AArch64::AEK_SIMD, AArch64::AEK_RAS, AArch64::AEK_RCPC})),
+            "8.3-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "thunderx", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_SIMD, AArch64::AEK_FP})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "thunderxt81", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_SIMD, AArch64::AEK_FP})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "thunderxt83", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_SIMD, AArch64::AEK_FP})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "thunderxt88", "armv8-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_SIMD, AArch64::AEK_FP})),
+            "8-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "tsv110", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_RAS,
+                 AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_PROFILE,
+                 AArch64::AEK_FP16, AArch64::AEK_FP16FML,
+                 AArch64::AEK_DOTPROD})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "a64fx", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_FP16,
+                 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_SVE,
+                 AArch64::AEK_RDM})),
+            "8.2-A"),
+        ARMCPUTestParams<AArch64::ExtensionBitset>(
+            "carmel", "armv8.2-a", "crypto-neon-fp-armv8",
+            (AArch64::ExtensionBitset(
+                {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
+                 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_FP16,
+                 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_RDM})),
+            "8.2-A")));
 
 // Note: number of CPUs includes aliases.
 static constexpr unsigned NumAArch64CPUArchs = 62;
@@ -1446,7 +1547,7 @@ TEST(TargetParserTest, testAArch64CPUArchList) {
   // No list exists for these in this test suite, so ensure all are
   // valid, and match the expected 'magic' count.
   EXPECT_EQ(List.size(), NumAArch64CPUArchs);
-  for(StringRef CPU : List) {
+  for (StringRef CPU : List) {
     EXPECT_TRUE(AArch64::parseCpu(CPU));
   }
 }
@@ -1496,7 +1597,7 @@ bool testAArch64Extension(StringRef CPUName, StringRef ArchExt) {
   if (!Extension)
     return false;
   std::optional<AArch64::CpuInfo> CpuInfo = AArch64::parseCpu(CPUName);
-  return CpuInfo->getImpliedExtensions() & Extension->ID;
+  return CpuInfo->getImpliedExtensions().test(Extension->ID);
 }
 
 bool testAArch64Extension(const AArch64::ArchInfo &AI, StringRef ArchExt) {
@@ -1504,7 +1605,7 @@ bool testAArch64Extension(const AArch64::ArchInfo &AI, StringRef ArchExt) {
       AArch64::parseArchExtension(ArchExt);
   if (!Extension)
     return false;
-  return AI.DefaultExts & Extension->ID;
+  return AI.DefaultExts.test(Extension->ID);
 }
 
 TEST(TargetParserTest, testAArch64Extension) {
@@ -1605,13 +1706,14 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
 
   std::vector<StringRef> Features;
 
-  uint64_t ExtVal = 0;
+  AArch64::ExtensionBitset ExtVal;
   for (auto Ext : Extensions)
-    ExtVal |= Ext;
+    ExtVal.set(Ext);
 
   // NONE has no feature names.
   // We return True here because NONE is a valid choice.
-  EXPECT_TRUE(AArch64::getExtensionFeatures(AArch64::AEK_NONE, Features));
+  EXPECT_TRUE(AArch64::getExtensionFeatures(
+      AArch64::ExtensionBitset({AArch64::AEK_NONE}), Features));
   EXPECT_TRUE(!Features.size());
 
   AArch64::getExtensionFeatures(ExtVal, Features);
@@ -1677,7 +1779,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
   // result. (note that AEK_NONE doesn't have a name so it won't be in the
   // result despite its bit being set)
   std::vector<StringRef> AllFeatures;
-  EXPECT_TRUE(AArch64::getExtensionFeatures(-1, AllFeatures));
+  EXPECT_TRUE(AArch64::getExtensionFeatures(ExtVal, AllFeatures));
   EXPECT_THAT(Features, ::testing::ContainerEq(AllFeatures));
 }
 


        


More information about the cfe-commits mailing list