xref: /llvm-project/llvm/unittests/TargetParser/TargetParserTest.cpp (revision b9254ade77d41c7582a98e6754058c39fd456c2a)
1 //===----------- TargetParser.cpp - Target Parser -------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/TargetParser/TargetParser.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/StringExtras.h"
12 #include "llvm/ADT/StringMap.h"
13 #include "llvm/Support/ARMBuildAttributes.h"
14 #include "llvm/Support/Debug.h"
15 #include "llvm/Support/FormatVariadic.h"
16 #include "llvm/TargetParser/AArch64TargetParser.h"
17 #include "llvm/TargetParser/ARMTargetParser.h"
18 #include "llvm/TargetParser/ARMTargetParserCommon.h"
19 #include "llvm/TargetParser/Triple.h"
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22 #include <optional>
23 #include <sstream>
24 #include <string>
25 
26 using namespace llvm;
27 
28 using ::testing::Contains;
29 using ::testing::StrEq;
30 
31 namespace {
32 const char *ARMArch[] = {
33     "armv4",       "armv4t",    "armv5",        "armv5t",      "armv5e",
34     "armv5te",     "armv5tej",  "armv6",        "armv6j",      "armv6k",
35     "armv6hl",     "armv6t2",   "armv6kz",      "armv6z",      "armv6zk",
36     "armv6-m",     "armv6m",    "armv6sm",      "armv6s-m",    "armv7-a",
37     "armv7",       "armv7a",    "armv7ve",      "armv7hl",     "armv7l",
38     "armv7-r",     "armv7r",    "armv7-m",      "armv7m",      "armv7k",
39     "armv7s",      "armv7e-m",  "armv7em",      "armv8-a",     "armv8",
40     "armv8a",      "armv8l",    "armv8.1-a",    "armv8.1a",    "armv8.2-a",
41     "armv8.2a",    "armv8.3-a", "armv8.3a",     "armv8.4-a",   "armv8.4a",
42     "armv8.5-a",   "armv8.5a",  "armv8.6-a",    "armv8.6a",    "armv8.7-a",
43     "armv8.7a",    "armv8.8-a", "armv8.8a",     "armv8.9-a",   "armv8.9a",
44     "armv8-r",     "armv8r",    "armv8-m.base", "armv8m.base", "armv8-m.main",
45     "armv8m.main", "iwmmxt",    "iwmmxt2",      "xscale",      "armv8.1-m.main",
46     "armv9-a",     "armv9",     "armv9a",       "armv9.1-a",   "armv9.1a",
47     "armv9.2-a",   "armv9.2a",  "armv9.3-a",    "armv9.3a",    "armv9.4-a",
48     "armv9.4a",    "armv9.5-a", "armv9.5a",
49 };
50 
51 std::string FormatExtensionFlags(int64_t Flags) {
52   std::vector<StringRef> Features;
53 
54   if (Flags & ARM::AEK_NONE)
55     Features.push_back("none");
56   ARM::getExtensionFeatures(Flags, Features);
57 
58   // The target parser also includes every extension you don't have.
59   // E.g. if AEK_CRC is not set then it adds "-crc". Not useful here.
60   Features.erase(std::remove_if(Features.begin(), Features.end(),
61                                 [](StringRef extension) {
62                                   return extension.starts_with("-");
63                                 }),
64                  Features.end());
65 
66   return llvm::join(Features, ", ");
67 }
68 
69 std::string FormatExtensionFlags(AArch64::ExtensionBitset Flags) {
70   std::vector<StringRef> Features;
71   AArch64::getExtensionFeatures(Flags, Features);
72 
73   // The target parser also includes every extension you don't have.
74   // E.g. if AEK_CRC is not set then it adds "-crc". Not useful here.
75   Features.erase(std::remove_if(Features.begin(), Features.end(),
76                                 [](StringRef extension) {
77                                   return extension.starts_with("-");
78                                 }),
79                  Features.end());
80 
81   return llvm::join(Features, ", ");
82 }
83 
84 std::string SerializeExtensionFlags(AArch64::ExtensionBitset Flags) {
85   std::string SerializedFlags;
86   std::ostringstream ss;
87   int HexValue = 0;
88   for (unsigned int i = 0; i < AArch64::AEK_NUM_EXTENSIONS; i++) {
89     HexValue <<= 1;
90     HexValue |= (int)Flags[i];
91     if ((i + 1) % 4 == 0) {
92       ss << std::hex << HexValue;
93       HexValue = 0;
94     }
95   }
96   // check if there are remainig unhandled bits
97   if ((AArch64::AEK_NUM_EXTENSIONS % 4) != 0)
98     ss << std::hex << HexValue;
99 
100   SerializedFlags = ss.str();
101   return SerializedFlags;
102 }
103 
104 template <ARM::ISAKind ISAKind> struct AssertSameExtensionFlags {
105   AssertSameExtensionFlags(StringRef CPUName) : CPUName(CPUName) {}
106 
107   testing::AssertionResult operator()(const char *m_expr, const char *n_expr,
108                                       uint64_t ExpectedFlags,
109                                       uint64_t GotFlags) {
110     if (ExpectedFlags == GotFlags)
111       return testing::AssertionSuccess();
112 
113     return testing::AssertionFailure() << llvm::formatv(
114                "CPU: {4}\n"
115                "Expected extension flags: {0} ({1:x})\n"
116                "     Got extension flags: {2} ({3:x})\n",
117                FormatExtensionFlags(ExpectedFlags), ExpectedFlags,
118                FormatExtensionFlags(GotFlags), ExpectedFlags, CPUName);
119   }
120 
121   testing::AssertionResult operator()(const char *m_expr, const char *n_expr,
122                                       AArch64::ExtensionBitset ExpectedFlags,
123                                       AArch64::ExtensionBitset GotFlags) {
124     if (ExpectedFlags == GotFlags)
125       return testing::AssertionSuccess();
126 
127     return testing::AssertionFailure()
128            << llvm::formatv("CPU: {4}\n"
129                             "Expected extension flags: {0} ({1})\n"
130                             "     Got extension flags: {2} ({3})\n",
131                             FormatExtensionFlags(ExpectedFlags),
132                             SerializeExtensionFlags(ExpectedFlags),
133                             FormatExtensionFlags(GotFlags),
134                             SerializeExtensionFlags(ExpectedFlags), CPUName);
135   }
136 
137 private:
138   StringRef CPUName;
139 };
140 
141 template <typename T> struct ARMCPUTestParams {
142   ARMCPUTestParams(StringRef CPUName, StringRef ExpectedArch,
143                    StringRef ExpectedFPU, T ExpectedFlags, StringRef CPUAttr)
144       : CPUName(CPUName), ExpectedArch(ExpectedArch), ExpectedFPU(ExpectedFPU),
145         ExpectedFlags(ExpectedFlags), CPUAttr(CPUAttr) {}
146 
147   friend std::ostream &operator<<(std::ostream &os,
148                                   const ARMCPUTestParams<T> &params) {
149     os << "\"" << params.CPUName.str() << "\", \"" << params.ExpectedArch.str()
150        << "\", \"" << params.ExpectedFPU.str() << "\", 0x";
151     if constexpr (std::is_same<T, uint64_t>::value)
152       os << std::hex << params.ExpectedFlags;
153     else
154       os << SerializeExtensionFlags(params.ExpectedFlags);
155     os << ", \"" << params.CPUAttr.str() << "\"";
156     return os;
157   }
158 
159   /// Print a gtest-compatible facsimile of the CPUName, to make the test's name
160   /// human-readable.
161   ///
162   /// https://github.com/google/googletest/blob/main/docs/advanced.md#specifying-names-for-value-parameterized-test-parameters
163   static std::string PrintToStringParamName(
164       const testing::TestParamInfo<ARMCPUTestParams<T>> &Info) {
165     std::string Name = Info.param.CPUName.str();
166     for (char &C : Name)
167       if (!std::isalnum(C))
168         C = '_';
169     return Name;
170   }
171 
172   StringRef CPUName;
173   StringRef ExpectedArch;
174   StringRef ExpectedFPU;
175   T ExpectedFlags;
176   StringRef CPUAttr;
177 };
178 
179 class ARMCPUTestFixture
180     : public ::testing::TestWithParam<ARMCPUTestParams<uint64_t>> {};
181 
182 TEST_P(ARMCPUTestFixture, ARMCPUTests) {
183   auto params = GetParam();
184 
185   ARM::ArchKind AK = ARM::parseCPUArch(params.CPUName);
186   EXPECT_EQ(params.ExpectedArch, ARM::getArchName(AK));
187 
188   ARM::FPUKind FPUKind = ARM::getDefaultFPU(params.CPUName, AK);
189   EXPECT_EQ(params.ExpectedFPU, ARM::getFPUName(FPUKind));
190 
191   uint64_t default_extensions = ARM::getDefaultExtensions(params.CPUName, AK);
192   EXPECT_PRED_FORMAT2(
193       AssertSameExtensionFlags<ARM::ISAKind::ARM>(params.CPUName),
194       params.ExpectedFlags, default_extensions);
195 
196   EXPECT_EQ(params.CPUAttr, ARM::getCPUAttr(AK));
197 }
198 
199 // Note that we include ARM::AEK_NONE even when there are other extensions
200 // we expect. This is because the default extensions for a CPU are the sum
201 // of the default extensions for its architecture and for the CPU.
202 // So if a CPU has no extra extensions, it adds AEK_NONE.
203 INSTANTIATE_TEST_SUITE_P(
204     ARMCPUTestsPart1, ARMCPUTestFixture,
205     ::testing::Values(
206         ARMCPUTestParams<uint64_t>("invalid", "invalid", "invalid",
207                                    ARM::AEK_NONE, ""),
208         ARMCPUTestParams<uint64_t>("generic", "invalid", "none", ARM::AEK_NONE,
209                                    ""),
210 
211         ARMCPUTestParams<uint64_t>("arm8", "armv4", "none", ARM::AEK_NONE, "4"),
212         ARMCPUTestParams<uint64_t>("arm810", "armv4", "none", ARM::AEK_NONE,
213                                    "4"),
214         ARMCPUTestParams<uint64_t>("strongarm", "armv4", "none", ARM::AEK_NONE,
215                                    "4"),
216         ARMCPUTestParams<uint64_t>("strongarm110", "armv4", "none",
217                                    ARM::AEK_NONE, "4"),
218         ARMCPUTestParams<uint64_t>("strongarm1100", "armv4", "none",
219                                    ARM::AEK_NONE, "4"),
220         ARMCPUTestParams<uint64_t>("strongarm1110", "armv4", "none",
221                                    ARM::AEK_NONE, "4"),
222         ARMCPUTestParams<uint64_t>("arm7tdmi", "armv4t", "none", ARM::AEK_NONE,
223                                    "4T"),
224         ARMCPUTestParams<uint64_t>("arm7tdmi-s", "armv4t", "none",
225                                    ARM::AEK_NONE, "4T"),
226         ARMCPUTestParams<uint64_t>("arm710t", "armv4t", "none", ARM::AEK_NONE,
227                                    "4T"),
228         ARMCPUTestParams<uint64_t>("arm720t", "armv4t", "none", ARM::AEK_NONE,
229                                    "4T"),
230         ARMCPUTestParams<uint64_t>("arm9", "armv4t", "none", ARM::AEK_NONE,
231                                    "4T"),
232         ARMCPUTestParams<uint64_t>("arm9tdmi", "armv4t", "none", ARM::AEK_NONE,
233                                    "4T"),
234         ARMCPUTestParams<uint64_t>("arm920", "armv4t", "none", ARM::AEK_NONE,
235                                    "4T"),
236         ARMCPUTestParams<uint64_t>("arm920t", "armv4t", "none", ARM::AEK_NONE,
237                                    "4T"),
238         ARMCPUTestParams<uint64_t>("arm922t", "armv4t", "none", ARM::AEK_NONE,
239                                    "4T"),
240         ARMCPUTestParams<uint64_t>("arm940t", "armv4t", "none", ARM::AEK_NONE,
241                                    "4T"),
242         ARMCPUTestParams<uint64_t>("ep9312", "armv4t", "none", ARM::AEK_NONE,
243                                    "4T"),
244         ARMCPUTestParams<uint64_t>("arm10tdmi", "armv5t", "none", ARM::AEK_NONE,
245                                    "5T"),
246         ARMCPUTestParams<uint64_t>("arm1020t", "armv5t", "none", ARM::AEK_NONE,
247                                    "5T"),
248         ARMCPUTestParams<uint64_t>("arm9e", "armv5te", "none",
249                                    ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
250         ARMCPUTestParams<uint64_t>("arm946e-s", "armv5te", "none",
251                                    ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
252         ARMCPUTestParams<uint64_t>("arm966e-s", "armv5te", "none",
253                                    ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
254         ARMCPUTestParams<uint64_t>("arm968e-s", "armv5te", "none",
255                                    ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
256         ARMCPUTestParams<uint64_t>("arm10e", "armv5te", "none",
257                                    ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
258         ARMCPUTestParams<uint64_t>("arm1020e", "armv5te", "none",
259                                    ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
260         ARMCPUTestParams<uint64_t>("arm1022e", "armv5te", "none",
261                                    ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
262         ARMCPUTestParams<uint64_t>("arm926ej-s", "armv5tej", "none",
263                                    ARM::AEK_NONE | ARM::AEK_DSP, "5TEJ"),
264         ARMCPUTestParams<uint64_t>("arm1136j-s", "armv6", "none",
265                                    ARM::AEK_NONE | ARM::AEK_DSP, "6"),
266         ARMCPUTestParams<uint64_t>("arm1136jf-s", "armv6", "vfpv2",
267                                    ARM::AEK_NONE | ARM::AEK_DSP, "6"),
268         ARMCPUTestParams<uint64_t>("arm1176jz-s", "armv6kz", "none",
269                                    ARM::AEK_NONE | ARM::AEK_SEC | ARM::AEK_DSP,
270                                    "6KZ"),
271         ARMCPUTestParams<uint64_t>("mpcore", "armv6k", "vfpv2",
272                                    ARM::AEK_NONE | ARM::AEK_DSP, "6K"),
273         ARMCPUTestParams<uint64_t>("mpcorenovfp", "armv6k", "none",
274                                    ARM::AEK_NONE | ARM::AEK_DSP, "6K"),
275         ARMCPUTestParams<uint64_t>("arm1176jzf-s", "armv6kz", "vfpv2",
276                                    ARM::AEK_NONE | ARM::AEK_SEC | ARM::AEK_DSP,
277                                    "6KZ"),
278         ARMCPUTestParams<uint64_t>("arm1156t2-s", "armv6t2", "none",
279                                    ARM::AEK_NONE | ARM::AEK_DSP, "6T2"),
280         ARMCPUTestParams<uint64_t>("arm1156t2f-s", "armv6t2", "vfpv2",
281                                    ARM::AEK_NONE | ARM::AEK_DSP, "6T2"),
282         ARMCPUTestParams<uint64_t>("cortex-m0", "armv6-m", "none",
283                                    ARM::AEK_NONE, "6-M"),
284         ARMCPUTestParams<uint64_t>("cortex-m0plus", "armv6-m", "none",
285                                    ARM::AEK_NONE, "6-M"),
286         ARMCPUTestParams<uint64_t>("cortex-m1", "armv6-m", "none",
287                                    ARM::AEK_NONE, "6-M"),
288         ARMCPUTestParams<uint64_t>("sc000", "armv6-m", "none", ARM::AEK_NONE,
289                                    "6-M"),
290         ARMCPUTestParams<uint64_t>("cortex-a5", "armv7-a", "neon-vfpv4",
291                                    ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP,
292                                    "7-A"),
293         ARMCPUTestParams<uint64_t>("cortex-a7", "armv7-a", "neon-vfpv4",
294                                    ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM |
295                                        ARM::AEK_MP | ARM::AEK_SEC |
296                                        ARM::AEK_VIRT | ARM::AEK_DSP,
297                                    "7-A"),
298         ARMCPUTestParams<uint64_t>("cortex-a8", "armv7-a", "neon",
299                                    ARM::AEK_SEC | ARM::AEK_DSP, "7-A")),
300     ARMCPUTestParams<uint64_t>::PrintToStringParamName);
301 
302 // gtest in llvm has a limit of 50 test cases when using ::Values so we split
303 // them into 2 blocks
304 INSTANTIATE_TEST_SUITE_P(
305     ARMCPUTestsPart2, ARMCPUTestFixture,
306     ::testing::Values(
307         ARMCPUTestParams<uint64_t>("cortex-a9", "armv7-a", "neon-fp16",
308                                    ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP,
309                                    "7-A"),
310         ARMCPUTestParams<uint64_t>("cortex-a12", "armv7-a", "neon-vfpv4",
311                                    ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
312                                        ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
313                                        ARM::AEK_DSP,
314                                    "7-A"),
315         ARMCPUTestParams<uint64_t>("cortex-a15", "armv7-a", "neon-vfpv4",
316                                    ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
317                                        ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
318                                        ARM::AEK_DSP,
319                                    "7-A"),
320         ARMCPUTestParams<uint64_t>("cortex-a17", "armv7-a", "neon-vfpv4",
321                                    ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
322                                        ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
323                                        ARM::AEK_DSP,
324                                    "7-A"),
325         ARMCPUTestParams<uint64_t>("krait", "armv7-a", "neon-vfpv4",
326                                    ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
327                                        ARM::AEK_DSP,
328                                    "7-A"),
329         ARMCPUTestParams<uint64_t>("cortex-r4", "armv7-r", "none",
330                                    ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB |
331                                        ARM::AEK_DSP,
332                                    "7-R"),
333         ARMCPUTestParams<uint64_t>("cortex-r4f", "armv7-r", "vfpv3-d16",
334                                    ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB |
335                                        ARM::AEK_DSP,
336                                    "7-R"),
337         ARMCPUTestParams<uint64_t>("cortex-r5", "armv7-r", "vfpv3-d16",
338                                    ARM::AEK_MP | ARM::AEK_HWDIVARM |
339                                        ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
340                                    "7-R"),
341         ARMCPUTestParams<uint64_t>("cortex-r7", "armv7-r", "vfpv3-d16-fp16",
342                                    ARM::AEK_MP | ARM::AEK_HWDIVARM |
343                                        ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
344                                    "7-R"),
345         ARMCPUTestParams<uint64_t>("cortex-r8", "armv7-r", "vfpv3-d16-fp16",
346                                    ARM::AEK_MP | ARM::AEK_HWDIVARM |
347                                        ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
348                                    "7-R"),
349         ARMCPUTestParams<uint64_t>("cortex-r52", "armv8-r", "neon-fp-armv8",
350                                    ARM::AEK_NONE | ARM::AEK_CRC | ARM::AEK_MP |
351                                        ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
352                                        ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
353                                    "8-R"),
354         ARMCPUTestParams<uint64_t>("cortex-r52plus", "armv8-r", "neon-fp-armv8",
355                                    ARM::AEK_NONE | ARM::AEK_CRC | ARM::AEK_MP |
356                                        ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
357                                        ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
358                                    "8-R"),
359         ARMCPUTestParams<uint64_t>("sc300", "armv7-m", "none",
360                                    ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "7-M"),
361         ARMCPUTestParams<uint64_t>("cortex-m3", "armv7-m", "none",
362                                    ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "7-M"),
363         ARMCPUTestParams<uint64_t>("cortex-m4", "armv7e-m", "fpv4-sp-d16",
364                                    ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB |
365                                        ARM::AEK_DSP,
366                                    "7E-M"),
367         ARMCPUTestParams<uint64_t>("cortex-m7", "armv7e-m", "fpv5-d16",
368                                    ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB |
369                                        ARM::AEK_DSP,
370                                    "7E-M"),
371         ARMCPUTestParams<uint64_t>("cortex-a32", "armv8-a",
372                                    "crypto-neon-fp-armv8",
373                                    ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
374                                        ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
375                                        ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
376                                    "8-A"),
377         ARMCPUTestParams<uint64_t>("cortex-a35", "armv8-a",
378                                    "crypto-neon-fp-armv8",
379                                    ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
380                                        ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
381                                        ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
382                                    "8-A"),
383         ARMCPUTestParams<uint64_t>("cortex-a53", "armv8-a",
384                                    "crypto-neon-fp-armv8",
385                                    ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
386                                        ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
387                                        ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
388                                    "8-A"),
389         ARMCPUTestParams<uint64_t>(
390             "cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",
391             ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
392                 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
393                 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
394             "8.2-A"),
395         ARMCPUTestParams<uint64_t>("cortex-a57", "armv8-a",
396                                    "crypto-neon-fp-armv8",
397                                    ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
398                                        ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
399                                        ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
400                                    "8-A"),
401         ARMCPUTestParams<uint64_t>("cortex-a72", "armv8-a",
402                                    "crypto-neon-fp-armv8",
403                                    ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
404                                        ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
405                                        ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
406                                    "8-A"),
407         ARMCPUTestParams<uint64_t>("cortex-a73", "armv8-a",
408                                    "crypto-neon-fp-armv8",
409                                    ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
410                                        ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
411                                        ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
412                                    "8-A"),
413         ARMCPUTestParams<uint64_t>(
414             "cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",
415             ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
416                 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
417                 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
418             "8.2-A"),
419         ARMCPUTestParams<uint64_t>(
420             "cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8",
421             ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
422                 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
423                 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
424             "8.2-A"),
425         ARMCPUTestParams<uint64_t>(
426             "cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",
427             ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
428                 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
429                 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
430             "8.2-A"),
431         ARMCPUTestParams<uint64_t>(
432             "cortex-a78c", "armv8.2-a", "crypto-neon-fp-armv8",
433             ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
434                 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC |
435                 ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD,
436             "8.2-A"),
437         ARMCPUTestParams<uint64_t>("cortex-a710", "armv9-a", "neon-fp-armv8",
438                                    ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
439                                        ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
440                                        ARM::AEK_DSP | ARM::AEK_CRC |
441                                        ARM::AEK_RAS | ARM::AEK_DOTPROD |
442                                        ARM::AEK_FP16FML | ARM::AEK_BF16 |
443                                        ARM::AEK_I8MM | ARM::AEK_SB,
444                                    "9-A"),
445         ARMCPUTestParams<uint64_t>(
446             "cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8",
447             ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
448                 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
449                 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
450             "8.2-A"),
451         ARMCPUTestParams<uint64_t>(
452             "cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8",
453             ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_SEC | ARM::AEK_MP |
454                 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
455                 ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS,
456             "8.2-A"),
457         ARMCPUTestParams<uint64_t>(
458             "cortex-a78ae", "armv8.2-a", "crypto-neon-fp-armv8",
459             ARM::AEK_RAS | ARM::AEK_DOTPROD | ARM::AEK_SEC | ARM::AEK_MP |
460                 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
461                 ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS,
462             "8.2-A"),
463         ARMCPUTestParams<uint64_t>(
464             "cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8",
465             ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD | ARM::AEK_SEC |
466                 ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
467                 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC,
468             "8.2-A"),
469         ARMCPUTestParams<uint64_t>(
470             "cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8",
471             ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD | ARM::AEK_SEC |
472                 ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
473                 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC,
474             "8.2-A"),
475         ARMCPUTestParams<uint64_t>(
476             "neoverse-n1", "armv8.2-a", "crypto-neon-fp-armv8",
477             ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
478                 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
479                 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
480             "8.2-A"),
481         ARMCPUTestParams<uint64_t>(
482             "neoverse-n2", "armv9-a", "neon-fp-armv8",
483             ARM::AEK_CRC | ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM |
484                 ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_VIRT | ARM::AEK_DSP |
485                 ARM::AEK_BF16 | ARM::AEK_DOTPROD | ARM::AEK_RAS |
486                 ARM::AEK_I8MM | ARM::AEK_FP16FML | ARM::AEK_SB,
487             "9-A"),
488         ARMCPUTestParams<uint64_t>(
489             "neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8",
490             ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
491                 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC |
492                 ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_BF16 | ARM::AEK_DOTPROD,
493             "8.4-A"),
494         ARMCPUTestParams<uint64_t>("cyclone", "armv8-a", "crypto-neon-fp-armv8",
495                                    ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
496                                        ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
497                                        ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
498                                    "8-A"),
499         ARMCPUTestParams<uint64_t>("exynos-m3", "armv8-a",
500                                    "crypto-neon-fp-armv8",
501                                    ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
502                                        ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
503                                        ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
504                                    "8-A"),
505         ARMCPUTestParams<uint64_t>(
506             "exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8",
507             ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
508                 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
509                 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS,
510             "8.2-A"),
511         ARMCPUTestParams<uint64_t>(
512             "exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
513             ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
514                 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
515                 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS,
516             "8.2-A"),
517         ARMCPUTestParams<uint64_t>("cortex-m23", "armv8-m.base", "none",
518                                    ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB,
519                                    "8-M.Baseline"),
520         ARMCPUTestParams<uint64_t>("cortex-m33", "armv8-m.main", "fpv5-sp-d16",
521                                    ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
522                                    "8-M.Mainline"),
523         ARMCPUTestParams<uint64_t>("cortex-m35p", "armv8-m.main", "fpv5-sp-d16",
524                                    ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
525                                    "8-M.Mainline"),
526         ARMCPUTestParams<uint64_t>(
527             "cortex-m55", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
528             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP |
529                 ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16,
530             "8.1-M.Mainline"),
531         ARMCPUTestParams<uint64_t>(
532             "cortex-m85", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
533             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP |
534                 ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16 | ARM::AEK_PACBTI,
535             "8.1-M.Mainline"),
536         ARMCPUTestParams<uint64_t>(
537             "cortex-m52", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
538             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP |
539                 ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16 | ARM::AEK_PACBTI,
540             "8.1-M.Mainline"),
541         ARMCPUTestParams<uint64_t>("iwmmxt", "iwmmxt", "none", ARM::AEK_NONE,
542                                    "iwmmxt"),
543         ARMCPUTestParams<uint64_t>("xscale", "xscale", "none", ARM::AEK_NONE,
544                                    "xscale"),
545         ARMCPUTestParams<uint64_t>("swift", "armv7s", "neon-vfpv4",
546                                    ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
547                                        ARM::AEK_DSP,
548                                    "7-S")),
549     ARMCPUTestParams<uint64_t>::PrintToStringParamName);
550 
551 static constexpr unsigned NumARMCPUArchs = 92;
552 
553 TEST(TargetParserTest, testARMCPUArchList) {
554   SmallVector<StringRef, NumARMCPUArchs> List;
555   ARM::fillValidCPUArchList(List);
556 
557   // No list exists for these in this test suite, so ensure all are
558   // valid, and match the expected 'magic' count.
559   EXPECT_EQ(List.size(), NumARMCPUArchs);
560   for (StringRef CPU : List) {
561     EXPECT_NE(ARM::parseCPUArch(CPU), ARM::ArchKind::INVALID);
562   }
563 }
564 
565 TEST(TargetParserTest, testInvalidARMArch) {
566   auto InvalidArchStrings = {"armv", "armv99", "noarm"};
567   for (const char *InvalidArch : InvalidArchStrings)
568     EXPECT_EQ(ARM::parseArch(InvalidArch), ARM::ArchKind::INVALID);
569 }
570 
571 bool testARMArch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch,
572                  unsigned ArchAttr) {
573   ARM::ArchKind AK = ARM::parseArch(Arch);
574   bool Result = (AK != ARM::ArchKind::INVALID);
575   Result &= ARM::getDefaultCPU(Arch) == DefaultCPU;
576   Result &= ARM::getSubArch(AK) == SubArch;
577   Result &= (ARM::getArchAttr(AK) == ArchAttr);
578   return Result;
579 }
580 
581 TEST(TargetParserTest, testARMArch) {
582   EXPECT_TRUE(
583       testARMArch("armv4", "strongarm", "v4", ARMBuildAttrs::CPUArch::v4));
584   EXPECT_TRUE(
585       testARMArch("armv4t", "arm7tdmi", "v4t", ARMBuildAttrs::CPUArch::v4T));
586   EXPECT_TRUE(
587       testARMArch("armv5t", "arm10tdmi", "v5", ARMBuildAttrs::CPUArch::v5T));
588   EXPECT_TRUE(
589       testARMArch("armv5te", "arm1022e", "v5e", ARMBuildAttrs::CPUArch::v5TE));
590   EXPECT_TRUE(testARMArch("armv5tej", "arm926ej-s", "v5e",
591                           ARMBuildAttrs::CPUArch::v5TEJ));
592   EXPECT_TRUE(
593       testARMArch("armv6", "arm1136jf-s", "v6", ARMBuildAttrs::CPUArch::v6));
594   EXPECT_TRUE(
595       testARMArch("armv6k", "mpcore", "v6k", ARMBuildAttrs::CPUArch::v6K));
596   EXPECT_TRUE(testARMArch("armv6t2", "arm1156t2-s", "v6t2",
597                           ARMBuildAttrs::CPUArch::v6T2));
598   EXPECT_TRUE(testARMArch("armv6kz", "arm1176jzf-s", "v6kz",
599                           ARMBuildAttrs::CPUArch::v6KZ));
600   EXPECT_TRUE(
601       testARMArch("armv6-m", "cortex-m0", "v6m", ARMBuildAttrs::CPUArch::v6_M));
602   EXPECT_TRUE(
603       testARMArch("armv7-a", "generic", "v7", ARMBuildAttrs::CPUArch::v7));
604   EXPECT_TRUE(
605       testARMArch("armv7ve", "generic", "v7ve", ARMBuildAttrs::CPUArch::v7));
606   EXPECT_TRUE(
607       testARMArch("armv7-r", "cortex-r4", "v7r", ARMBuildAttrs::CPUArch::v7));
608   EXPECT_TRUE(
609       testARMArch("armv7-m", "cortex-m3", "v7m", ARMBuildAttrs::CPUArch::v7));
610   EXPECT_TRUE(testARMArch("armv7e-m", "cortex-m4", "v7em",
611                           ARMBuildAttrs::CPUArch::v7E_M));
612   EXPECT_TRUE(
613       testARMArch("armv8-a", "generic", "v8a", ARMBuildAttrs::CPUArch::v8_A));
614   EXPECT_TRUE(testARMArch("armv8.1-a", "generic", "v8.1a",
615                           ARMBuildAttrs::CPUArch::v8_A));
616   EXPECT_TRUE(testARMArch("armv8.2-a", "generic", "v8.2a",
617                           ARMBuildAttrs::CPUArch::v8_A));
618   EXPECT_TRUE(testARMArch("armv8.3-a", "generic", "v8.3a",
619                           ARMBuildAttrs::CPUArch::v8_A));
620   EXPECT_TRUE(testARMArch("armv8.4-a", "generic", "v8.4a",
621                           ARMBuildAttrs::CPUArch::v8_A));
622   EXPECT_TRUE(testARMArch("armv8.5-a", "generic", "v8.5a",
623                           ARMBuildAttrs::CPUArch::v8_A));
624   EXPECT_TRUE(testARMArch("armv8.6-a", "generic", "v8.6a",
625                           ARMBuildAttrs::CPUArch::v8_A));
626   EXPECT_TRUE(testARMArch("armv8.7-a", "generic", "v8.7a",
627                           ARMBuildAttrs::CPUArch::v8_A));
628   EXPECT_TRUE(testARMArch("armv8.8-a", "generic", "v8.8a",
629                           ARMBuildAttrs::CPUArch::v8_A));
630   EXPECT_TRUE(testARMArch("armv8.9-a", "generic", "v8.9a",
631                           ARMBuildAttrs::CPUArch::v8_A));
632   EXPECT_TRUE(
633       testARMArch("armv9-a", "generic", "v9a", ARMBuildAttrs::CPUArch::v9_A));
634   EXPECT_TRUE(testARMArch("armv9.1-a", "generic", "v9.1a",
635                           ARMBuildAttrs::CPUArch::v9_A));
636   EXPECT_TRUE(testARMArch("armv9.2-a", "generic", "v9.2a",
637                           ARMBuildAttrs::CPUArch::v9_A));
638   EXPECT_TRUE(testARMArch("armv9.3-a", "generic", "v9.3a",
639                           ARMBuildAttrs::CPUArch::v9_A));
640   EXPECT_TRUE(testARMArch("armv9.4-a", "generic", "v9.4a",
641                           ARMBuildAttrs::CPUArch::v9_A));
642   EXPECT_TRUE(testARMArch("armv9.5-a", "generic", "v9.5a",
643                           ARMBuildAttrs::CPUArch::v9_A));
644   EXPECT_TRUE(
645       testARMArch("armv8-r", "generic", "v8r", ARMBuildAttrs::CPUArch::v8_R));
646   EXPECT_TRUE(testARMArch("armv8-m.base", "generic", "v8m.base",
647                           ARMBuildAttrs::CPUArch::v8_M_Base));
648   EXPECT_TRUE(testARMArch("armv8-m.main", "generic", "v8m.main",
649                           ARMBuildAttrs::CPUArch::v8_M_Main));
650   EXPECT_TRUE(testARMArch("armv8.1-m.main", "generic", "v8.1m.main",
651                           ARMBuildAttrs::CPUArch::v8_1_M_Main));
652   EXPECT_TRUE(
653       testARMArch("iwmmxt", "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE));
654   EXPECT_TRUE(
655       testARMArch("iwmmxt2", "generic", "", ARMBuildAttrs::CPUArch::v5TE));
656   EXPECT_TRUE(
657       testARMArch("xscale", "xscale", "v5e", ARMBuildAttrs::CPUArch::v5TE));
658   EXPECT_TRUE(
659       testARMArch("armv7s", "swift", "v7s", ARMBuildAttrs::CPUArch::v7));
660   EXPECT_TRUE(
661       testARMArch("armv7k", "generic", "v7k", ARMBuildAttrs::CPUArch::v7));
662 }
663 
664 bool testARMExtension(StringRef CPUName, ARM::ArchKind ArchKind,
665                       StringRef ArchExt) {
666   return ARM::getDefaultExtensions(CPUName, ArchKind) &
667          ARM::parseArchExt(ArchExt);
668 }
669 
670 TEST(TargetParserTest, testARMExtension) {
671   EXPECT_FALSE(testARMExtension("strongarm", ARM::ArchKind::INVALID, "dsp"));
672   EXPECT_FALSE(testARMExtension("arm7tdmi", ARM::ArchKind::INVALID, "dsp"));
673   EXPECT_FALSE(testARMExtension("arm10tdmi", ARM::ArchKind::INVALID, "simd"));
674   EXPECT_FALSE(testARMExtension("arm1022e", ARM::ArchKind::INVALID, "simd"));
675   EXPECT_FALSE(testARMExtension("arm926ej-s", ARM::ArchKind::INVALID, "simd"));
676   EXPECT_FALSE(
677       testARMExtension("arm1136jf-s", ARM::ArchKind::INVALID, "crypto"));
678   EXPECT_FALSE(
679       testARMExtension("arm1156t2-s", ARM::ArchKind::INVALID, "crypto"));
680   EXPECT_FALSE(
681       testARMExtension("arm1176jzf-s", ARM::ArchKind::INVALID, "crypto"));
682   EXPECT_FALSE(testARMExtension("cortex-m0", ARM::ArchKind::INVALID, "crypto"));
683   EXPECT_FALSE(testARMExtension("cortex-a8", ARM::ArchKind::INVALID, "crypto"));
684   EXPECT_FALSE(testARMExtension("cortex-r4", ARM::ArchKind::INVALID, "crypto"));
685   EXPECT_FALSE(testARMExtension("cortex-m3", ARM::ArchKind::INVALID, "crypto"));
686   EXPECT_FALSE(testARMExtension("cortex-a53", ARM::ArchKind::INVALID, "ras"));
687   EXPECT_FALSE(testARMExtension("cortex-a53", ARM::ArchKind::INVALID, "fp16"));
688   EXPECT_TRUE(testARMExtension("cortex-a55", ARM::ArchKind::INVALID, "fp16"));
689   EXPECT_FALSE(
690       testARMExtension("cortex-a55", ARM::ArchKind::INVALID, "fp16fml"));
691   EXPECT_TRUE(testARMExtension("cortex-a75", ARM::ArchKind::INVALID, "fp16"));
692   EXPECT_FALSE(
693       testARMExtension("cortex-a75", ARM::ArchKind::INVALID, "fp16fml"));
694   EXPECT_FALSE(testARMExtension("cortex-r52", ARM::ArchKind::INVALID, "ras"));
695   EXPECT_FALSE(
696       testARMExtension("cortex-r52plus", ARM::ArchKind::INVALID, "ras"));
697   EXPECT_FALSE(testARMExtension("iwmmxt", ARM::ArchKind::INVALID, "crc"));
698   EXPECT_FALSE(testARMExtension("xscale", ARM::ArchKind::INVALID, "crc"));
699   EXPECT_FALSE(testARMExtension("swift", ARM::ArchKind::INVALID, "crc"));
700 
701   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4, "dsp"));
702   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4T, "dsp"));
703   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5T, "simd"));
704   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TE, "simd"));
705   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TEJ, "simd"));
706   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6, "crypto"));
707   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6K, "crypto"));
708   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6T2, "crypto"));
709   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6KZ, "crypto"));
710   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6M, "crypto"));
711   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7A, "crypto"));
712   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7R, "crypto"));
713   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7M, "crypto"));
714   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7EM, "crypto"));
715   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8A, "ras"));
716   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_1A, "ras"));
717   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "profile"));
718   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16"));
719   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16fml"));
720   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A, "fp16"));
721   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A, "fp16fml"));
722   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A, "fp16"));
723   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A, "fp16fml"));
724   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8R, "ras"));
725   EXPECT_FALSE(
726       testARMExtension("generic", ARM::ArchKind::ARMV8MBaseline, "crc"));
727   EXPECT_FALSE(
728       testARMExtension("generic", ARM::ArchKind::ARMV8MMainline, "crc"));
729   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT, "crc"));
730   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT2, "crc"));
731   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::XSCALE, "crc"));
732   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7S, "crypto"));
733   EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7K, "crypto"));
734 }
735 
736 TEST(TargetParserTest, ARMFPUVersion) {
737   for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
738        FK <= ARM::FPUKind::FK_LAST;
739        FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
740     if (FK == ARM::FK_LAST || ARM::getFPUName(FK) == "invalid" ||
741         ARM::getFPUName(FK) == "none" || ARM::getFPUName(FK) == "softvfp")
742       EXPECT_EQ(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK));
743     else
744       EXPECT_NE(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK));
745 }
746 
747 TEST(TargetParserTest, ARMFPUNeonSupportLevel) {
748   for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
749        FK <= ARM::FPUKind::FK_LAST;
750        FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
751     if (FK == ARM::FK_LAST ||
752         ARM::getFPUName(FK).find("neon") == std::string::npos)
753       EXPECT_EQ(ARM::NeonSupportLevel::None, ARM::getFPUNeonSupportLevel(FK));
754     else
755       EXPECT_NE(ARM::NeonSupportLevel::None, ARM::getFPUNeonSupportLevel(FK));
756 }
757 
758 TEST(TargetParserTest, ARMFPURestriction) {
759   for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
760        FK <= ARM::FPUKind::FK_LAST;
761        FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) {
762     if (FK == ARM::FK_LAST ||
763         (ARM::getFPUName(FK).find("d16") == std::string::npos &&
764          ARM::getFPUName(FK).find("vfpv3xd") == std::string::npos))
765       EXPECT_EQ(ARM::FPURestriction::None, ARM::getFPURestriction(FK));
766     else
767       EXPECT_NE(ARM::FPURestriction::None, ARM::getFPURestriction(FK));
768   }
769 }
770 
771 TEST(TargetParserTest, ARMExtensionFeatures) {
772   std::map<uint64_t, std::vector<StringRef>> Extensions;
773 
774   for (auto &Ext : ARM::ARCHExtNames) {
775     if (!Ext.Feature.empty() && !Ext.NegFeature.empty())
776       Extensions[Ext.ID] = {Ext.Feature, Ext.NegFeature};
777   }
778 
779   Extensions[ARM::AEK_HWDIVARM] = {"+hwdiv-arm", "-hwdiv-arm"};
780   Extensions[ARM::AEK_HWDIVTHUMB] = {"+hwdiv", "-hwdiv"};
781 
782   std::vector<StringRef> Features;
783 
784   EXPECT_FALSE(ARM::getExtensionFeatures(ARM::AEK_INVALID, Features));
785 
786   for (auto &E : Extensions) {
787     // test +extension
788     Features.clear();
789     ARM::getExtensionFeatures(E.first, Features);
790     EXPECT_TRUE(llvm::is_contained(Features, E.second.at(0)));
791     EXPECT_EQ(Extensions.size(), Features.size());
792 
793     // test -extension
794     Features.clear();
795     ARM::getExtensionFeatures(~E.first, Features);
796     EXPECT_TRUE(llvm::is_contained(Features, E.second.at(1)));
797     EXPECT_EQ(Extensions.size(), Features.size());
798   }
799 }
800 
801 TEST(TargetParserTest, ARMFPUFeatures) {
802   std::vector<StringRef> Features;
803   for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
804        FK <= ARM::FPUKind::FK_LAST;
805        FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) {
806     if (FK == ARM::FK_INVALID || FK >= ARM::FK_LAST)
807       EXPECT_FALSE(ARM::getFPUFeatures(FK, Features));
808     else
809       EXPECT_TRUE(ARM::getFPUFeatures(FK, Features));
810   }
811 }
812 
813 TEST(TargetParserTest, ARMArchExtFeature) {
814   const char *ArchExt[][4] = {{"crc", "nocrc", "+crc", "-crc"},
815                               {"crypto", "nocrypto", "+crypto", "-crypto"},
816                               {"dsp", "nodsp", "+dsp", "-dsp"},
817                               {"fp", "nofp", nullptr, nullptr},
818                               {"idiv", "noidiv", nullptr, nullptr},
819                               {"mp", "nomp", nullptr, nullptr},
820                               {"simd", "nosimd", nullptr, nullptr},
821                               {"sec", "nosec", nullptr, nullptr},
822                               {"virt", "novirt", nullptr, nullptr},
823                               {"fp16", "nofp16", "+fullfp16", "-fullfp16"},
824                               {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"},
825                               {"ras", "noras", "+ras", "-ras"},
826                               {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
827                               {"os", "noos", nullptr, nullptr},
828                               {"iwmmxt", "noiwmmxt", nullptr, nullptr},
829                               {"iwmmxt2", "noiwmmxt2", nullptr, nullptr},
830                               {"maverick", "maverick", nullptr, nullptr},
831                               {"xscale", "noxscale", nullptr, nullptr},
832                               {"sb", "nosb", "+sb", "-sb"},
833                               {"i8mm", "noi8mm", "+i8mm", "-i8mm"},
834                               {"mve", "nomve", "+mve", "-mve"},
835                               {"mve.fp", "nomve.fp", "+mve.fp", "-mve.fp"}};
836 
837   for (unsigned i = 0; i < std::size(ArchExt); i++) {
838     EXPECT_EQ(StringRef(ArchExt[i][2]), ARM::getArchExtFeature(ArchExt[i][0]));
839     EXPECT_EQ(StringRef(ArchExt[i][3]), ARM::getArchExtFeature(ArchExt[i][1]));
840   }
841 }
842 
843 static bool
844 testArchExtDependency(const char *ArchExt,
845                       const std::initializer_list<const char *> &Expected) {
846   std::vector<StringRef> Features;
847   ARM::FPUKind FPUKind;
848 
849   if (!ARM::appendArchExtFeatures("", ARM::ArchKind::ARMV8_1MMainline, ArchExt,
850                                   Features, FPUKind))
851     return false;
852 
853   return llvm::all_of(Expected, [&](StringRef Ext) {
854     return llvm::is_contained(Features, Ext);
855   });
856 }
857 
858 TEST(TargetParserTest, ARMArchExtDependencies) {
859   EXPECT_TRUE(testArchExtDependency("mve", {"+mve", "+dsp"}));
860   EXPECT_TRUE(testArchExtDependency("mve.fp", {"+mve.fp", "+mve", "+dsp"}));
861   EXPECT_TRUE(testArchExtDependency("nodsp", {"-dsp", "-mve", "-mve.fp"}));
862   EXPECT_TRUE(testArchExtDependency("nomve", {"-mve", "-mve.fp"}));
863 }
864 
865 TEST(TargetParserTest, ARMparseHWDiv) {
866   const char *hwdiv[] = {"thumb", "arm", "arm,thumb", "thumb,arm"};
867 
868   for (unsigned i = 0; i < std::size(hwdiv); i++)
869     EXPECT_NE(ARM::AEK_INVALID, ARM::parseHWDiv((StringRef)hwdiv[i]));
870 }
871 
872 TEST(TargetParserTest, ARMparseArchEndianAndISA) {
873   const char *Arch[] = {
874       "v2",        "v2a",    "v3",    "v3m",    "v4",       "v4t",
875       "v5",        "v5t",    "v5e",   "v5te",   "v5tej",    "v6",
876       "v6j",       "v6k",    "v6hl",  "v6t2",   "v6kz",     "v6z",
877       "v6zk",      "v6-m",   "v6m",   "v6sm",   "v6s-m",    "v7-a",
878       "v7",        "v7a",    "v7ve",  "v7hl",   "v7l",      "v7-r",
879       "v7r",       "v7-m",   "v7m",   "v7k",    "v7s",      "v7e-m",
880       "v7em",      "v8-a",   "v8",    "v8a",    "v8l",      "v8.1-a",
881       "v8.1a",     "v8.2-a", "v8.2a", "v8.3-a", "v8.3a",    "v8.4-a",
882       "v8.4a",     "v8.5-a", "v8.5a", "v8.6-a", "v8.6a",    "v8.7-a",
883       "v8.7a",     "v8.8-a", "v8.8a", "v8-r",   "v8m.base", "v8m.main",
884       "v8.1m.main"};
885 
886   for (unsigned i = 0; i < std::size(Arch); i++) {
887     std::string arm_1 = "armeb" + (std::string)(Arch[i]);
888     std::string arm_2 = "arm" + (std::string)(Arch[i]) + "eb";
889     std::string arm_3 = "arm" + (std::string)(Arch[i]);
890     std::string thumb_1 = "thumbeb" + (std::string)(Arch[i]);
891     std::string thumb_2 = "thumb" + (std::string)(Arch[i]) + "eb";
892     std::string thumb_3 = "thumb" + (std::string)(Arch[i]);
893 
894     EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_1));
895     EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_2));
896     EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(arm_3));
897 
898     EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_1));
899     EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_2));
900     EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_3));
901     if (i >= 4) {
902       EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_1));
903       EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_2));
904       EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(thumb_3));
905 
906       EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_1));
907       EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_2));
908       EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_3));
909     }
910   }
911 
912   EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("aarch64"));
913   EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("arm64_32"));
914   EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian("aarch64_be"));
915 
916   EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64"));
917   EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_be"));
918   EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64"));
919   EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_be"));
920   EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_32"));
921   EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_32"));
922 }
923 
924 TEST(TargetParserTest, ARMparseArchProfile) {
925   for (unsigned i = 0; i < std::size(ARMArch); i++) {
926     switch (ARM::parseArch(ARMArch[i])) {
927     case ARM::ArchKind::ARMV6M:
928     case ARM::ArchKind::ARMV7M:
929     case ARM::ArchKind::ARMV7EM:
930     case ARM::ArchKind::ARMV8MMainline:
931     case ARM::ArchKind::ARMV8MBaseline:
932     case ARM::ArchKind::ARMV8_1MMainline:
933       EXPECT_EQ(ARM::ProfileKind::M, ARM::parseArchProfile(ARMArch[i]));
934       break;
935     case ARM::ArchKind::ARMV7R:
936     case ARM::ArchKind::ARMV8R:
937       EXPECT_EQ(ARM::ProfileKind::R, ARM::parseArchProfile(ARMArch[i]));
938       break;
939     case ARM::ArchKind::ARMV7A:
940     case ARM::ArchKind::ARMV7VE:
941     case ARM::ArchKind::ARMV7K:
942     case ARM::ArchKind::ARMV8A:
943     case ARM::ArchKind::ARMV8_1A:
944     case ARM::ArchKind::ARMV8_2A:
945     case ARM::ArchKind::ARMV8_3A:
946     case ARM::ArchKind::ARMV8_4A:
947     case ARM::ArchKind::ARMV8_5A:
948     case ARM::ArchKind::ARMV8_6A:
949     case ARM::ArchKind::ARMV8_7A:
950     case ARM::ArchKind::ARMV8_8A:
951     case ARM::ArchKind::ARMV8_9A:
952     case ARM::ArchKind::ARMV9A:
953     case ARM::ArchKind::ARMV9_1A:
954     case ARM::ArchKind::ARMV9_2A:
955     case ARM::ArchKind::ARMV9_3A:
956     case ARM::ArchKind::ARMV9_4A:
957     case ARM::ArchKind::ARMV9_5A:
958       EXPECT_EQ(ARM::ProfileKind::A, ARM::parseArchProfile(ARMArch[i]));
959       break;
960     default:
961       EXPECT_EQ(ARM::ProfileKind::INVALID, ARM::parseArchProfile(ARMArch[i]));
962       break;
963     }
964   }
965 }
966 
967 TEST(TargetParserTest, ARMparseArchVersion) {
968   for (unsigned i = 0; i < std::size(ARMArch); i++)
969     if (((std::string)ARMArch[i]).substr(0, 4) == "armv")
970       EXPECT_EQ((ARMArch[i][4] - 48u), ARM::parseArchVersion(ARMArch[i]));
971     else
972       EXPECT_EQ(5u, ARM::parseArchVersion(ARMArch[i]));
973 }
974 
975 TEST(TargetParserTest, getARMCPUForArch) {
976   // Platform specific defaults.
977   {
978     llvm::Triple Triple("arm--nacl");
979     EXPECT_EQ("cortex-a8", ARM::getARMCPUForArch(Triple));
980   }
981   {
982     llvm::Triple Triple("arm--openbsd");
983     EXPECT_EQ("cortex-a8", ARM::getARMCPUForArch(Triple));
984   }
985   {
986     llvm::Triple Triple("armv6-unknown-freebsd");
987     EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple));
988   }
989   {
990     llvm::Triple Triple("thumbv6-unknown-freebsd");
991     EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple));
992   }
993   {
994     llvm::Triple Triple("armebv6-unknown-freebsd");
995     EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple));
996   }
997   {
998     llvm::Triple Triple("arm--win32");
999     EXPECT_EQ("cortex-a9", ARM::getARMCPUForArch(Triple));
1000     EXPECT_EQ("generic", ARM::getARMCPUForArch(Triple, "armv8-a"));
1001   }
1002   // Some alternative architectures
1003   {
1004     llvm::Triple Triple("armv7k-apple-ios9");
1005     EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple));
1006   }
1007   {
1008     llvm::Triple Triple("armv7k-apple-watchos3");
1009     EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple));
1010   }
1011   {
1012     llvm::Triple Triple("armv7k-apple-tvos9");
1013     EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple));
1014   }
1015   // armeb is permitted, but armebeb is not
1016   {
1017     llvm::Triple Triple("armeb-none-eabi");
1018     EXPECT_EQ("arm7tdmi", ARM::getARMCPUForArch(Triple));
1019   }
1020   {
1021     llvm::Triple Triple("armebeb-none-eabi");
1022     EXPECT_EQ("", ARM::getARMCPUForArch(Triple));
1023   }
1024   {
1025     llvm::Triple Triple("armebv6eb-none-eabi");
1026     EXPECT_EQ("", ARM::getARMCPUForArch(Triple));
1027   }
1028   // xscaleeb is permitted, but armebxscale is not
1029   {
1030     llvm::Triple Triple("xscaleeb-none-eabi");
1031     EXPECT_EQ("xscale", ARM::getARMCPUForArch(Triple));
1032   }
1033   {
1034     llvm::Triple Triple("armebxscale-none-eabi");
1035     EXPECT_EQ("", ARM::getARMCPUForArch(Triple));
1036   }
1037 }
1038 
1039 TEST(TargetParserTest, ARMPrintSupportedExtensions) {
1040   std::string expected =
1041       "All available -march extensions for ARM\n\n"
1042       "    Name                Description\n"
1043       "    crc                 This is a long dummy description\n"
1044       "    crypto\n"
1045       "    sha2\n";
1046 
1047   StringMap<StringRef> DummyMap;
1048   DummyMap["crc"] = "This is a long dummy description";
1049 
1050   outs().flush();
1051   testing::internal::CaptureStdout();
1052   ARM::PrintSupportedExtensions(DummyMap);
1053   outs().flush();
1054   std::string captured = testing::internal::GetCapturedStdout();
1055 
1056   // Check that the start of the output is as expected.
1057   EXPECT_EQ(0ULL, captured.find(expected));
1058 
1059   // Should not include "none" or "invalid".
1060   EXPECT_EQ(std::string::npos, captured.find("none"));
1061   EXPECT_EQ(std::string::npos, captured.find("invalid"));
1062   // Should not include anything that lacks a feature name. Checking a few here
1063   // but not all as if one is hidden correctly the rest should be.
1064   EXPECT_EQ(std::string::npos, captured.find("simd"));
1065   EXPECT_EQ(std::string::npos, captured.find("maverick"));
1066   EXPECT_EQ(std::string::npos, captured.find("xscale"));
1067 }
1068 
1069 struct AArch64CPUTestParams
1070     : public ARMCPUTestParams<AArch64::ExtensionBitset> {
1071   AArch64CPUTestParams(StringRef CPUName, StringRef ExpectedArch,
1072                        StringRef ExpectedFPU,
1073                        AArch64::ExtensionBitset ExpectedFlags)
1074       : ARMCPUTestParams<AArch64::ExtensionBitset>(CPUName, ExpectedArch,
1075                                                    ExpectedFPU, ExpectedFlags,
1076                                                    /*ignored*/ "") {}
1077   /// Print a gtest-compatible facsimile of the CPUName, to make the test's name
1078   /// human-readable.
1079   ///
1080   /// https://github.com/google/googletest/blob/main/docs/advanced.md#specifying-names-for-value-parameterized-test-parameters
1081   static std::string PrintToStringParamName(
1082       const testing::TestParamInfo<AArch64CPUTestParams> &Info) {
1083     std::string Name = Info.param.CPUName.str();
1084     for (char &C : Name)
1085       if (!std::isalnum(C))
1086         C = '_';
1087     return Name;
1088   }
1089 };
1090 
1091 class AArch64CPUTestFixture
1092     : public ::testing::TestWithParam<AArch64CPUTestParams> {};
1093 
1094 TEST_P(AArch64CPUTestFixture, testAArch64CPU) {
1095   auto params = GetParam();
1096 
1097   const std::optional<AArch64::CpuInfo> Cpu = AArch64::parseCpu(params.CPUName);
1098   EXPECT_TRUE(Cpu);
1099   EXPECT_EQ(params.ExpectedArch, Cpu->Arch.Name);
1100 
1101   EXPECT_PRED_FORMAT2(
1102       AssertSameExtensionFlags<ARM::ISAKind::AARCH64>(params.CPUName),
1103       params.ExpectedFlags, Cpu->getImpliedExtensions());
1104 }
1105 
1106 INSTANTIATE_TEST_SUITE_P(
1107     AArch64CPUTests, AArch64CPUTestFixture,
1108     ::testing::Values(
1109         AArch64CPUTestParams("cortex-a34", "armv8-a", "crypto-neon-fp-armv8",
1110                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1111                               AArch64::AEK_SHA2, AArch64::AEK_FP,
1112                               AArch64::AEK_SIMD, AArch64::AEK_PERFMON}),
1113         AArch64CPUTestParams("cortex-a35", "armv8-a", "crypto-neon-fp-armv8",
1114                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1115                               AArch64::AEK_SHA2, AArch64::AEK_FP,
1116                               AArch64::AEK_SIMD, AArch64::AEK_PERFMON}),
1117         AArch64CPUTestParams("cortex-a53", "armv8-a", "crypto-neon-fp-armv8",
1118                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1119                               AArch64::AEK_SHA2, AArch64::AEK_FP,
1120                               AArch64::AEK_SIMD, AArch64::AEK_PERFMON}),
1121         AArch64CPUTestParams(
1122             "cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",
1123             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1124              AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_RAS,
1125              AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_FP16,
1126              AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_PERFMON}),
1127         AArch64CPUTestParams("cortex-a510", "armv9-a", "neon-fp-armv8",
1128                              {AArch64::AEK_CRC,         AArch64::AEK_FP,
1129                               AArch64::AEK_SIMD,        AArch64::AEK_RAS,
1130                               AArch64::AEK_LSE,         AArch64::AEK_RDM,
1131                               AArch64::AEK_RCPC,        AArch64::AEK_DOTPROD,
1132                               AArch64::AEK_BF16,        AArch64::AEK_I8MM,
1133                               AArch64::AEK_SVE,         AArch64::AEK_SVE2,
1134                               AArch64::AEK_SVE2BITPERM, AArch64::AEK_PAUTH,
1135                               AArch64::AEK_MTE,         AArch64::AEK_SSBS,
1136                               AArch64::AEK_FP16,        AArch64::AEK_FP16FML,
1137                               AArch64::AEK_SB,          AArch64::AEK_JSCVT,
1138                               AArch64::AEK_FCMA,        AArch64::AEK_PERFMON,
1139                               AArch64::AEK_ETE,         AArch64::AEK_AM}),
1140         AArch64CPUTestParams("cortex-a520", "armv9.2-a", "crypto-neon-fp-armv8",
1141                              {AArch64::AEK_BF16,        AArch64::AEK_I8MM,
1142                               AArch64::AEK_SVE,         AArch64::AEK_SVE2,
1143                               AArch64::AEK_FP16,        AArch64::AEK_DOTPROD,
1144                               AArch64::AEK_LSE,         AArch64::AEK_RDM,
1145                               AArch64::AEK_SIMD,        AArch64::AEK_RCPC,
1146                               AArch64::AEK_RAS,         AArch64::AEK_CRC,
1147                               AArch64::AEK_FP,          AArch64::AEK_SB,
1148                               AArch64::AEK_SSBS,        AArch64::AEK_MTE,
1149                               AArch64::AEK_FP16FML,     AArch64::AEK_PAUTH,
1150                               AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
1151                               AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
1152                               AArch64::AEK_JSCVT,       AArch64::AEK_FCMA,
1153                               AArch64::AEK_PERFMON,     AArch64::AEK_AM,
1154                               AArch64::AEK_ETE}),
1155         AArch64CPUTestParams("cortex-a520ae", "armv9.2-a",
1156                              "crypto-neon-fp-armv8",
1157                              {AArch64::AEK_BF16,        AArch64::AEK_I8MM,
1158                               AArch64::AEK_SVE,         AArch64::AEK_SVE2,
1159                               AArch64::AEK_FP16,        AArch64::AEK_DOTPROD,
1160                               AArch64::AEK_LSE,         AArch64::AEK_RDM,
1161                               AArch64::AEK_SIMD,        AArch64::AEK_RCPC,
1162                               AArch64::AEK_RAS,         AArch64::AEK_CRC,
1163                               AArch64::AEK_FP,          AArch64::AEK_SB,
1164                               AArch64::AEK_SSBS,        AArch64::AEK_MTE,
1165                               AArch64::AEK_FP16FML,     AArch64::AEK_PAUTH,
1166                               AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
1167                               AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
1168                               AArch64::AEK_JSCVT,       AArch64::AEK_FCMA,
1169                               AArch64::AEK_PERFMON,     AArch64::AEK_AM,
1170                               AArch64::AEK_ETE}),
1171         AArch64CPUTestParams("cortex-a57", "armv8-a", "crypto-neon-fp-armv8",
1172                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1173                               AArch64::AEK_SHA2, AArch64::AEK_FP,
1174                               AArch64::AEK_SIMD, AArch64::AEK_PERFMON}),
1175         AArch64CPUTestParams(
1176             "cortex-a65", "armv8.2-a", "crypto-neon-fp-armv8",
1177             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1178              AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16,
1179              AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RCPC,
1180              AArch64::AEK_RDM, AArch64::AEK_SIMD, AArch64::AEK_SSBS,
1181              AArch64::AEK_PERFMON}),
1182         AArch64CPUTestParams(
1183             "cortex-a65ae", "armv8.2-a", "crypto-neon-fp-armv8",
1184             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1185              AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16,
1186              AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RCPC,
1187              AArch64::AEK_RDM, AArch64::AEK_SIMD, AArch64::AEK_SSBS,
1188              AArch64::AEK_PERFMON}),
1189         AArch64CPUTestParams("cortex-a72", "armv8-a", "crypto-neon-fp-armv8",
1190                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1191                               AArch64::AEK_SHA2, AArch64::AEK_FP,
1192                               AArch64::AEK_SIMD, AArch64::AEK_PERFMON}),
1193         AArch64CPUTestParams("cortex-a73", "armv8-a", "crypto-neon-fp-armv8",
1194                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1195                               AArch64::AEK_SHA2, AArch64::AEK_FP,
1196                               AArch64::AEK_SIMD, AArch64::AEK_PERFMON}),
1197         AArch64CPUTestParams(
1198             "cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",
1199             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1200              AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_RAS,
1201              AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_FP16,
1202              AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_PERFMON}),
1203         AArch64CPUTestParams(
1204             "cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8",
1205             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1206              AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD,
1207              AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16,
1208              AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS,
1209              AArch64::AEK_PERFMON}),
1210         AArch64CPUTestParams(
1211             "cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",
1212             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1213              AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD,
1214              AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16,
1215              AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS,
1216              AArch64::AEK_PERFMON}),
1217         AArch64CPUTestParams(
1218             "cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8",
1219             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1220              AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD,
1221              AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16,
1222              AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS,
1223              AArch64::AEK_PERFMON}),
1224         AArch64CPUTestParams(
1225             "cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8",
1226             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1227              AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD,
1228              AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16,
1229              AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS,
1230              AArch64::AEK_PROFILE, AArch64::AEK_PERFMON}),
1231         AArch64CPUTestParams(
1232             "cortex-a78ae", "armv8.2-a", "crypto-neon-fp-armv8",
1233             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1234              AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD,
1235              AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16,
1236              AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS,
1237              AArch64::AEK_PROFILE, AArch64::AEK_PERFMON}),
1238         AArch64CPUTestParams(
1239             "cortex-a78c", "armv8.2-a", "crypto-neon-fp-armv8",
1240             {AArch64::AEK_RAS, AArch64::AEK_CRC, AArch64::AEK_AES,
1241              AArch64::AEK_SHA2, AArch64::AEK_FP, AArch64::AEK_SIMD,
1242              AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_RDM,
1243              AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC,
1244              AArch64::AEK_SSBS, AArch64::AEK_PROFILE, AArch64::AEK_FLAGM,
1245              AArch64::AEK_PAUTH, AArch64::AEK_PERFMON}),
1246         AArch64CPUTestParams(
1247             "cortex-a710", "armv9-a", "neon-fp-armv8",
1248             {AArch64::AEK_CRC,     AArch64::AEK_FP,          AArch64::AEK_SIMD,
1249              AArch64::AEK_RAS,     AArch64::AEK_LSE,         AArch64::AEK_RDM,
1250              AArch64::AEK_RCPC,    AArch64::AEK_DOTPROD,     AArch64::AEK_MTE,
1251              AArch64::AEK_FP16,    AArch64::AEK_FP16FML,     AArch64::AEK_SVE,
1252              AArch64::AEK_SVE2,    AArch64::AEK_SVE2BITPERM, AArch64::AEK_PAUTH,
1253              AArch64::AEK_FLAGM,   AArch64::AEK_SB,          AArch64::AEK_I8MM,
1254              AArch64::AEK_BF16,    AArch64::AEK_JSCVT,       AArch64::AEK_FCMA,
1255              AArch64::AEK_PERFMON, AArch64::AEK_ETE}),
1256         AArch64CPUTestParams("cortex-a715", "armv9-a", "neon-fp-armv8",
1257                              {AArch64::AEK_CRC,     AArch64::AEK_FP,
1258                               AArch64::AEK_BF16,    AArch64::AEK_SIMD,
1259                               AArch64::AEK_RAS,     AArch64::AEK_LSE,
1260                               AArch64::AEK_RDM,     AArch64::AEK_RCPC,
1261                               AArch64::AEK_DOTPROD, AArch64::AEK_MTE,
1262                               AArch64::AEK_PAUTH,   AArch64::AEK_SVE,
1263                               AArch64::AEK_SVE2,    AArch64::AEK_SVE2BITPERM,
1264                               AArch64::AEK_SSBS,    AArch64::AEK_SB,
1265                               AArch64::AEK_I8MM,    AArch64::AEK_PERFMON,
1266                               AArch64::AEK_PREDRES, AArch64::AEK_PROFILE,
1267                               AArch64::AEK_FP16FML, AArch64::AEK_FP16,
1268                               AArch64::AEK_FLAGM,   AArch64::AEK_JSCVT,
1269                               AArch64::AEK_FCMA,    AArch64::AEK_PERFMON,
1270                               AArch64::AEK_ETE,     AArch64::AEK_TRBE}),
1271         AArch64CPUTestParams("cortex-a720", "armv9.2-a", "crypto-neon-fp-armv8",
1272                              {AArch64::AEK_BF16,        AArch64::AEK_I8MM,
1273                               AArch64::AEK_SVE,         AArch64::AEK_SVE2,
1274                               AArch64::AEK_FP16,        AArch64::AEK_DOTPROD,
1275                               AArch64::AEK_LSE,         AArch64::AEK_RDM,
1276                               AArch64::AEK_SIMD,        AArch64::AEK_RCPC,
1277                               AArch64::AEK_RAS,         AArch64::AEK_CRC,
1278                               AArch64::AEK_FP,          AArch64::AEK_SB,
1279                               AArch64::AEK_SSBS,        AArch64::AEK_MTE,
1280                               AArch64::AEK_FP16FML,     AArch64::AEK_PAUTH,
1281                               AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
1282                               AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
1283                               AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
1284                               AArch64::AEK_FCMA,        AArch64::AEK_PERFMON,
1285                               AArch64::AEK_ETE,         AArch64::AEK_SPE_EEF,
1286                               AArch64::AEK_TRBE}),
1287         AArch64CPUTestParams("cortex-a720ae", "armv9.2-a",
1288                              "crypto-neon-fp-armv8",
1289                              {AArch64::AEK_BF16,        AArch64::AEK_I8MM,
1290                               AArch64::AEK_SVE,         AArch64::AEK_SVE2,
1291                               AArch64::AEK_FP16,        AArch64::AEK_DOTPROD,
1292                               AArch64::AEK_LSE,         AArch64::AEK_RDM,
1293                               AArch64::AEK_SIMD,        AArch64::AEK_RCPC,
1294                               AArch64::AEK_RAS,         AArch64::AEK_CRC,
1295                               AArch64::AEK_FP,          AArch64::AEK_SB,
1296                               AArch64::AEK_SSBS,        AArch64::AEK_MTE,
1297                               AArch64::AEK_FP16FML,     AArch64::AEK_PAUTH,
1298                               AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
1299                               AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
1300                               AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
1301                               AArch64::AEK_FCMA,        AArch64::AEK_PERFMON,
1302                               AArch64::AEK_ETE,         AArch64::AEK_SPE_EEF,
1303                               AArch64::AEK_TRBE}),
1304         AArch64CPUTestParams("cortex-a725", "armv9.2-a", "crypto-neon-fp-armv8",
1305                              {AArch64::AEK_BF16,        AArch64::AEK_I8MM,
1306                               AArch64::AEK_SVE,         AArch64::AEK_SVE2,
1307                               AArch64::AEK_FP16,        AArch64::AEK_DOTPROD,
1308                               AArch64::AEK_LSE,         AArch64::AEK_RDM,
1309                               AArch64::AEK_SIMD,        AArch64::AEK_RCPC,
1310                               AArch64::AEK_RAS,         AArch64::AEK_CRC,
1311                               AArch64::AEK_FP,          AArch64::AEK_SB,
1312                               AArch64::AEK_SSBS,        AArch64::AEK_MTE,
1313                               AArch64::AEK_FP16FML,     AArch64::AEK_PAUTH,
1314                               AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
1315                               AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
1316                               AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
1317                               AArch64::AEK_FCMA,        AArch64::AEK_ETE,
1318                               AArch64::AEK_SPE_EEF,     AArch64::AEK_TRBE}),
1319         AArch64CPUTestParams(
1320             "neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8",
1321             {AArch64::AEK_RAS,     AArch64::AEK_SVE,     AArch64::AEK_SSBS,
1322              AArch64::AEK_RCPC,    AArch64::AEK_CRC,     AArch64::AEK_FP,
1323              AArch64::AEK_SIMD,    AArch64::AEK_RAS,     AArch64::AEK_LSE,
1324              AArch64::AEK_RDM,     AArch64::AEK_RCPC,    AArch64::AEK_DOTPROD,
1325              AArch64::AEK_AES,     AArch64::AEK_SHA2,    AArch64::AEK_SHA3,
1326              AArch64::AEK_SM4,     AArch64::AEK_FP16,    AArch64::AEK_BF16,
1327              AArch64::AEK_PROFILE, AArch64::AEK_RAND,    AArch64::AEK_FP16FML,
1328              AArch64::AEK_I8MM,    AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
1329              AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON, AArch64::AEK_CCDP}),
1330         AArch64CPUTestParams("neoverse-v2", "armv9-a", "neon-fp-armv8",
1331                              {AArch64::AEK_RAS,         AArch64::AEK_SVE,
1332                               AArch64::AEK_SSBS,        AArch64::AEK_RCPC,
1333                               AArch64::AEK_CRC,         AArch64::AEK_FP,
1334                               AArch64::AEK_SIMD,        AArch64::AEK_MTE,
1335                               AArch64::AEK_LSE,         AArch64::AEK_RDM,
1336                               AArch64::AEK_RCPC,        AArch64::AEK_DOTPROD,
1337                               AArch64::AEK_FP16,        AArch64::AEK_BF16,
1338                               AArch64::AEK_SVE2,        AArch64::AEK_PROFILE,
1339                               AArch64::AEK_FP16FML,     AArch64::AEK_I8MM,
1340                               AArch64::AEK_SVE2BITPERM, AArch64::AEK_RAND,
1341                               AArch64::AEK_JSCVT,       AArch64::AEK_FCMA,
1342                               AArch64::AEK_PAUTH,       AArch64::AEK_PERFMON,
1343                               AArch64::AEK_ETE}),
1344         AArch64CPUTestParams("neoverse-v3", "armv9.2-a", "neon-fp-armv8",
1345                              {AArch64::AEK_BF16,        AArch64::AEK_I8MM,
1346                               AArch64::AEK_SVE,         AArch64::AEK_SVE2,
1347                               AArch64::AEK_FP16,        AArch64::AEK_DOTPROD,
1348                               AArch64::AEK_LSE,         AArch64::AEK_RDM,
1349                               AArch64::AEK_SIMD,        AArch64::AEK_RCPC,
1350                               AArch64::AEK_RAS,         AArch64::AEK_CRC,
1351                               AArch64::AEK_FP,          AArch64::AEK_PROFILE,
1352                               AArch64::AEK_MTE,         AArch64::AEK_SSBS,
1353                               AArch64::AEK_SB,          AArch64::AEK_PREDRES,
1354                               AArch64::AEK_LS64,        AArch64::AEK_BRBE,
1355                               AArch64::AEK_PAUTH,       AArch64::AEK_FLAGM,
1356                               AArch64::AEK_PERFMON,     AArch64::AEK_RAND,
1357                               AArch64::AEK_SVE2BITPERM, AArch64::AEK_FP16FML,
1358                               AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
1359                               AArch64::AEK_FCMA,        AArch64::AEK_PERFMON,
1360                               AArch64::AEK_ETE,         AArch64::AEK_SPE_EEF}),
1361         AArch64CPUTestParams("neoverse-v3ae", "armv9.2-a", "neon-fp-armv8",
1362                              {AArch64::AEK_BF16,        AArch64::AEK_I8MM,
1363                               AArch64::AEK_SVE,         AArch64::AEK_SVE2,
1364                               AArch64::AEK_FP16,        AArch64::AEK_DOTPROD,
1365                               AArch64::AEK_LSE,         AArch64::AEK_RDM,
1366                               AArch64::AEK_SIMD,        AArch64::AEK_RCPC,
1367                               AArch64::AEK_RAS,         AArch64::AEK_CRC,
1368                               AArch64::AEK_FP,          AArch64::AEK_PROFILE,
1369                               AArch64::AEK_MTE,         AArch64::AEK_SSBS,
1370                               AArch64::AEK_SB,          AArch64::AEK_PREDRES,
1371                               AArch64::AEK_LS64,        AArch64::AEK_BRBE,
1372                               AArch64::AEK_PAUTH,       AArch64::AEK_FLAGM,
1373                               AArch64::AEK_PERFMON,     AArch64::AEK_RAND,
1374                               AArch64::AEK_SVE2BITPERM, AArch64::AEK_FP16FML,
1375                               AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
1376                               AArch64::AEK_FCMA,        AArch64::AEK_PERFMON,
1377                               AArch64::AEK_ETE,         AArch64::AEK_SPE_EEF}),
1378         AArch64CPUTestParams(
1379             "cortex-r82", "armv8-r", "crypto-neon-fp-armv8",
1380             {AArch64::AEK_CRC, AArch64::AEK_RDM, AArch64::AEK_SSBS,
1381              AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_SIMD,
1382              AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_RAS,
1383              AArch64::AEK_RCPC, AArch64::AEK_LSE, AArch64::AEK_SB,
1384              AArch64::AEK_JSCVT, AArch64::AEK_FCMA, AArch64::AEK_PAUTH,
1385              AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, AArch64::AEK_PREDRES,
1386              AArch64::AEK_CCDP}),
1387         AArch64CPUTestParams(
1388             "cortex-r82ae", "armv8-r", "crypto-neon-fp-armv8",
1389             {AArch64::AEK_CRC, AArch64::AEK_RDM, AArch64::AEK_SSBS,
1390              AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_SIMD,
1391              AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_RAS,
1392              AArch64::AEK_RCPC, AArch64::AEK_LSE, AArch64::AEK_SB,
1393              AArch64::AEK_JSCVT, AArch64::AEK_FCMA, AArch64::AEK_PAUTH,
1394              AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, AArch64::AEK_PREDRES,
1395              AArch64::AEK_CCDP}),
1396         AArch64CPUTestParams(
1397             "cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8",
1398             {AArch64::AEK_CRC, AArch64::AEK_AES,
1399              AArch64::AEK_SHA2, AArch64::AEK_FP, AArch64::AEK_RDM,
1400              AArch64::AEK_SIMD, AArch64::AEK_RAS, AArch64::AEK_LSE,
1401              AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC,
1402              AArch64::AEK_SSBS, AArch64::AEK_PROFILE, AArch64::AEK_PERFMON}),
1403         AArch64CPUTestParams(
1404             "cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8",
1405             {AArch64::AEK_CRC, AArch64::AEK_AES,
1406              AArch64::AEK_SHA2, AArch64::AEK_FP, AArch64::AEK_RDM,
1407              AArch64::AEK_SIMD, AArch64::AEK_RAS, AArch64::AEK_LSE,
1408              AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC,
1409              AArch64::AEK_SSBS, AArch64::AEK_PAUTH, AArch64::AEK_PROFILE,
1410              AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, AArch64::AEK_LSE2,
1411              AArch64::AEK_RCPC_IMMO}),
1412         AArch64CPUTestParams("cortex-x2", "armv9-a", "neon-fp-armv8",
1413                              {AArch64::AEK_CRC,         AArch64::AEK_FP,
1414                               AArch64::AEK_SIMD,        AArch64::AEK_RAS,
1415                               AArch64::AEK_LSE,         AArch64::AEK_RDM,
1416                               AArch64::AEK_RCPC,        AArch64::AEK_DOTPROD,
1417                               AArch64::AEK_MTE,         AArch64::AEK_PAUTH,
1418                               AArch64::AEK_I8MM,        AArch64::AEK_BF16,
1419                               AArch64::AEK_SVE,         AArch64::AEK_SVE2,
1420                               AArch64::AEK_SVE2BITPERM, AArch64::AEK_SSBS,
1421                               AArch64::AEK_SB,          AArch64::AEK_FP16,
1422                               AArch64::AEK_FP16FML,     AArch64::AEK_FLAGM,
1423                               AArch64::AEK_JSCVT,       AArch64::AEK_FCMA,
1424                               AArch64::AEK_PERFMON,     AArch64::AEK_AM,
1425                               AArch64::AEK_ETE}),
1426         AArch64CPUTestParams("cortex-x3", "armv9-a", "neon-fp-armv8",
1427                              {AArch64::AEK_CRC,     AArch64::AEK_FP,
1428                               AArch64::AEK_BF16,    AArch64::AEK_SIMD,
1429                               AArch64::AEK_RAS,     AArch64::AEK_LSE,
1430                               AArch64::AEK_RDM,     AArch64::AEK_RCPC,
1431                               AArch64::AEK_DOTPROD, AArch64::AEK_MTE,
1432                               AArch64::AEK_PAUTH,   AArch64::AEK_SVE,
1433                               AArch64::AEK_SVE2,    AArch64::AEK_SVE2BITPERM,
1434                               AArch64::AEK_SB,      AArch64::AEK_PROFILE,
1435                               AArch64::AEK_PERFMON, AArch64::AEK_I8MM,
1436                               AArch64::AEK_FP16,    AArch64::AEK_FP16FML,
1437                               AArch64::AEK_PREDRES, AArch64::AEK_FLAGM,
1438                               AArch64::AEK_SSBS,    AArch64::AEK_JSCVT,
1439                               AArch64::AEK_FCMA,    AArch64::AEK_PERFMON,
1440                               AArch64::AEK_ETE,     AArch64::AEK_TRBE}),
1441         AArch64CPUTestParams("cortex-x4", "armv9.2-a", "crypto-neon-fp-armv8",
1442                              {AArch64::AEK_BF16,        AArch64::AEK_I8MM,
1443                               AArch64::AEK_SVE,         AArch64::AEK_SVE2,
1444                               AArch64::AEK_FP16,        AArch64::AEK_DOTPROD,
1445                               AArch64::AEK_LSE,         AArch64::AEK_RDM,
1446                               AArch64::AEK_SIMD,        AArch64::AEK_RCPC,
1447                               AArch64::AEK_RAS,         AArch64::AEK_CRC,
1448                               AArch64::AEK_FP,          AArch64::AEK_SB,
1449                               AArch64::AEK_SSBS,        AArch64::AEK_MTE,
1450                               AArch64::AEK_FP16FML,     AArch64::AEK_PAUTH,
1451                               AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
1452                               AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
1453                               AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
1454                               AArch64::AEK_FCMA,        AArch64::AEK_PERFMON,
1455                               AArch64::AEK_ETE,         AArch64::AEK_SPE_EEF,
1456                               AArch64::AEK_TRBE}),
1457         AArch64CPUTestParams("cortex-x925", "armv9.2-a", "crypto-neon-fp-armv8",
1458                              {AArch64::AEK_BF16,        AArch64::AEK_I8MM,
1459                               AArch64::AEK_SVE,         AArch64::AEK_SVE2,
1460                               AArch64::AEK_FP16,        AArch64::AEK_DOTPROD,
1461                               AArch64::AEK_LSE,         AArch64::AEK_RDM,
1462                               AArch64::AEK_SIMD,        AArch64::AEK_RCPC,
1463                               AArch64::AEK_RAS,         AArch64::AEK_CRC,
1464                               AArch64::AEK_FP,          AArch64::AEK_SB,
1465                               AArch64::AEK_SSBS,        AArch64::AEK_MTE,
1466                               AArch64::AEK_FP16FML,     AArch64::AEK_PAUTH,
1467                               AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM,
1468                               AArch64::AEK_PERFMON,     AArch64::AEK_PREDRES,
1469                               AArch64::AEK_PROFILE,     AArch64::AEK_JSCVT,
1470                               AArch64::AEK_FCMA,        AArch64::AEK_ETE,
1471                               AArch64::AEK_SPE_EEF,     AArch64::AEK_TRBE}),
1472         AArch64CPUTestParams("cyclone", "armv8-a", "crypto-neon-fp-armv8",
1473                              {AArch64::AEK_AES, AArch64::AEK_SHA2,
1474                               AArch64::AEK_FP, AArch64::AEK_SIMD,
1475                               AArch64::AEK_PERFMON}),
1476         AArch64CPUTestParams("apple-a7", "armv8-a", "crypto-neon-fp-armv8",
1477                              {AArch64::AEK_AES, AArch64::AEK_SHA2,
1478                               AArch64::AEK_FP, AArch64::AEK_SIMD,
1479                               AArch64::AEK_PERFMON}),
1480         AArch64CPUTestParams("apple-a8", "armv8-a", "crypto-neon-fp-armv8",
1481                              {AArch64::AEK_AES, AArch64::AEK_SHA2,
1482                               AArch64::AEK_FP, AArch64::AEK_SIMD,
1483                               AArch64::AEK_PERFMON}),
1484         AArch64CPUTestParams("apple-a9", "armv8-a", "crypto-neon-fp-armv8",
1485                              {AArch64::AEK_AES, AArch64::AEK_SHA2,
1486                               AArch64::AEK_FP, AArch64::AEK_SIMD,
1487                               AArch64::AEK_PERFMON}),
1488         AArch64CPUTestParams("apple-a10", "armv8-a", "crypto-neon-fp-armv8",
1489                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1490                               AArch64::AEK_SHA2, AArch64::AEK_FP,
1491                               AArch64::AEK_RDM, AArch64::AEK_SIMD,
1492                               AArch64::AEK_PERFMON, AArch64::AEK_PAN,
1493                               AArch64::AEK_LOR, AArch64::AEK_VH}),
1494         AArch64CPUTestParams("apple-a11", "armv8.2-a", "crypto-neon-fp-armv8",
1495                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1496                               AArch64::AEK_SHA2, AArch64::AEK_FP,
1497                               AArch64::AEK_LSE, AArch64::AEK_RAS,
1498                               AArch64::AEK_RDM, AArch64::AEK_SIMD,
1499                               AArch64::AEK_FP16, AArch64::AEK_PERFMON}),
1500         AArch64CPUTestParams(
1501             "apple-a12", "armv8.3-a", "crypto-neon-fp-armv8",
1502             {AArch64::AEK_CRC, AArch64::AEK_AES,
1503              AArch64::AEK_SHA2, AArch64::AEK_FP, AArch64::AEK_SIMD,
1504              AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
1505              AArch64::AEK_RCPC, AArch64::AEK_FP16, AArch64::AEK_JSCVT,
1506              AArch64::AEK_FCMA, AArch64::AEK_PAUTH, AArch64::AEK_PERFMON}),
1507         AArch64CPUTestParams(
1508             "apple-s4", "armv8.3-a", "crypto-neon-fp-armv8",
1509             {AArch64::AEK_CRC, AArch64::AEK_AES,
1510              AArch64::AEK_SHA2, AArch64::AEK_FP, AArch64::AEK_SIMD,
1511              AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
1512              AArch64::AEK_RCPC, AArch64::AEK_FP16, AArch64::AEK_JSCVT,
1513              AArch64::AEK_FCMA, AArch64::AEK_PAUTH, AArch64::AEK_PERFMON}),
1514         AArch64CPUTestParams(
1515             "apple-s5", "armv8.3-a", "crypto-neon-fp-armv8",
1516             {AArch64::AEK_CRC, AArch64::AEK_AES,
1517              AArch64::AEK_SHA2, AArch64::AEK_FP, AArch64::AEK_SIMD,
1518              AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
1519              AArch64::AEK_RCPC, AArch64::AEK_FP16, AArch64::AEK_JSCVT,
1520              AArch64::AEK_FCMA, AArch64::AEK_PAUTH, AArch64::AEK_PERFMON}),
1521         AArch64CPUTestParams(
1522             "apple-a13", "armv8.4-a", "crypto-neon-fp-armv8",
1523             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1524              AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD,
1525              AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
1526              AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
1527              AArch64::AEK_FP16FML, AArch64::AEK_SHA3, AArch64::AEK_JSCVT,
1528              AArch64::AEK_FCMA, AArch64::AEK_PAUTH, AArch64::AEK_PERFMON}),
1529         AArch64CPUTestParams("apple-a14", "armv8.4-a", "crypto-neon-fp-armv8",
1530                              {AArch64::AEK_CRC,
1531                               AArch64::AEK_AES,
1532                               AArch64::AEK_SHA2,
1533                               AArch64::AEK_SHA3,
1534                               AArch64::AEK_FP,
1535                               AArch64::AEK_SIMD,
1536                               AArch64::AEK_LSE,
1537                               AArch64::AEK_RAS,
1538                               AArch64::AEK_RDM,
1539                               AArch64::AEK_RCPC,
1540                               AArch64::AEK_DOTPROD,
1541                               AArch64::AEK_FP16,
1542                               AArch64::AEK_FP16FML,
1543                               AArch64::AEK_SHA3,
1544                               AArch64::AEK_JSCVT,
1545                               AArch64::AEK_FCMA,
1546                               AArch64::AEK_PAUTH,
1547                               AArch64::AEK_PERFMON,
1548                               AArch64::AEK_PREDRES,
1549                               AArch64::AEK_SB,
1550                               AArch64::AEK_SSBS,
1551                               AArch64::AEK_CCDP,
1552                               AArch64::AEK_FRINT3264,
1553                               AArch64::AEK_SPECRESTRICT,
1554                               AArch64::AEK_ALTERNATIVENZCV}),
1555         AArch64CPUTestParams("apple-m1", "armv8.4-a", "crypto-neon-fp-armv8",
1556                              {AArch64::AEK_CRC,
1557                               AArch64::AEK_AES,
1558                               AArch64::AEK_SHA2,
1559                               AArch64::AEK_SHA3,
1560                               AArch64::AEK_FP,
1561                               AArch64::AEK_SIMD,
1562                               AArch64::AEK_LSE,
1563                               AArch64::AEK_RAS,
1564                               AArch64::AEK_RDM,
1565                               AArch64::AEK_RCPC,
1566                               AArch64::AEK_DOTPROD,
1567                               AArch64::AEK_FP16,
1568                               AArch64::AEK_FP16FML,
1569                               AArch64::AEK_SHA3,
1570                               AArch64::AEK_JSCVT,
1571                               AArch64::AEK_FCMA,
1572                               AArch64::AEK_PAUTH,
1573                               AArch64::AEK_PERFMON,
1574                               AArch64::AEK_PREDRES,
1575                               AArch64::AEK_SB,
1576                               AArch64::AEK_SSBS,
1577                               AArch64::AEK_CCDP,
1578                               AArch64::AEK_FRINT3264,
1579                               AArch64::AEK_SPECRESTRICT,
1580                               AArch64::AEK_ALTERNATIVENZCV}),
1581         AArch64CPUTestParams(
1582             "apple-a15", "armv8.6-a", "crypto-neon-fp-armv8",
1583             {AArch64::AEK_CRC,     AArch64::AEK_AES,     AArch64::AEK_SHA2,
1584              AArch64::AEK_SHA3,    AArch64::AEK_FP,      AArch64::AEK_SIMD,
1585              AArch64::AEK_LSE,     AArch64::AEK_RAS,     AArch64::AEK_RDM,
1586              AArch64::AEK_RCPC,    AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
1587              AArch64::AEK_FP16FML, AArch64::AEK_SHA3,    AArch64::AEK_BF16,
1588              AArch64::AEK_I8MM,    AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
1589              AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON}),
1590         AArch64CPUTestParams(
1591             "apple-m2", "armv8.6-a", "crypto-neon-fp-armv8",
1592             {AArch64::AEK_CRC,     AArch64::AEK_AES,     AArch64::AEK_SHA2,
1593              AArch64::AEK_SHA3,    AArch64::AEK_FP,      AArch64::AEK_SIMD,
1594              AArch64::AEK_LSE,     AArch64::AEK_RAS,     AArch64::AEK_RDM,
1595              AArch64::AEK_RCPC,    AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
1596              AArch64::AEK_FP16FML, AArch64::AEK_SHA3,    AArch64::AEK_BF16,
1597              AArch64::AEK_I8MM,    AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
1598              AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON}),
1599         AArch64CPUTestParams(
1600             "apple-a16", "armv8.6-a", "crypto-neon-fp-armv8",
1601             {AArch64::AEK_CRC,     AArch64::AEK_AES,     AArch64::AEK_SHA2,
1602              AArch64::AEK_SHA3,    AArch64::AEK_FP,      AArch64::AEK_SIMD,
1603              AArch64::AEK_LSE,     AArch64::AEK_RAS,     AArch64::AEK_RDM,
1604              AArch64::AEK_RCPC,    AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
1605              AArch64::AEK_FP16FML, AArch64::AEK_SHA3,    AArch64::AEK_BF16,
1606              AArch64::AEK_I8MM,    AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
1607              AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON, AArch64::AEK_HCX}),
1608         AArch64CPUTestParams(
1609             "apple-m3", "armv8.6-a", "crypto-neon-fp-armv8",
1610             {AArch64::AEK_CRC,     AArch64::AEK_AES,     AArch64::AEK_SHA2,
1611              AArch64::AEK_SHA3,    AArch64::AEK_FP,      AArch64::AEK_SIMD,
1612              AArch64::AEK_LSE,     AArch64::AEK_RAS,     AArch64::AEK_RDM,
1613              AArch64::AEK_RCPC,    AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
1614              AArch64::AEK_FP16FML, AArch64::AEK_SHA3,    AArch64::AEK_BF16,
1615              AArch64::AEK_I8MM,    AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
1616              AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON, AArch64::AEK_HCX}),
1617         AArch64CPUTestParams(
1618             "apple-a17", "armv8.6-a", "crypto-neon-fp-armv8",
1619             {AArch64::AEK_CRC,     AArch64::AEK_AES,     AArch64::AEK_SHA2,
1620              AArch64::AEK_SHA3,    AArch64::AEK_FP,      AArch64::AEK_SIMD,
1621              AArch64::AEK_LSE,     AArch64::AEK_RAS,     AArch64::AEK_RDM,
1622              AArch64::AEK_RCPC,    AArch64::AEK_DOTPROD, AArch64::AEK_FP16,
1623              AArch64::AEK_FP16FML, AArch64::AEK_SHA3,    AArch64::AEK_BF16,
1624              AArch64::AEK_I8MM,    AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
1625              AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON, AArch64::AEK_HCX}),
1626         AArch64CPUTestParams("apple-m4", "armv8.7-a", "crypto-neon-fp-armv8",
1627                              {AArch64::AEK_CRC,       AArch64::AEK_AES,
1628                               AArch64::AEK_SHA2,      AArch64::AEK_SHA3,
1629                               AArch64::AEK_FP,        AArch64::AEK_SIMD,
1630                               AArch64::AEK_LSE,       AArch64::AEK_RAS,
1631                               AArch64::AEK_RDM,       AArch64::AEK_RCPC,
1632                               AArch64::AEK_DOTPROD,   AArch64::AEK_FP16,
1633                               AArch64::AEK_FP16FML,   AArch64::AEK_BF16,
1634                               AArch64::AEK_I8MM,      AArch64::AEK_JSCVT,
1635                               AArch64::AEK_FCMA,      AArch64::AEK_PAUTH,
1636                               AArch64::AEK_SME,       AArch64::AEK_SME2,
1637                               AArch64::AEK_SMEF64F64, AArch64::AEK_SMEI16I64,
1638                               AArch64::AEK_PERFMON}),
1639         AArch64CPUTestParams("exynos-m3", "armv8-a", "crypto-neon-fp-armv8",
1640                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1641                               AArch64::AEK_SHA2, AArch64::AEK_FP,
1642                               AArch64::AEK_SIMD, AArch64::AEK_PERFMON}),
1643         AArch64CPUTestParams(
1644             "exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8",
1645             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1646              AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16,
1647              AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
1648              AArch64::AEK_SIMD, AArch64::AEK_PERFMON}),
1649         AArch64CPUTestParams(
1650             "exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
1651             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1652              AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16,
1653              AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM,
1654              AArch64::AEK_SIMD, AArch64::AEK_PERFMON}),
1655         AArch64CPUTestParams("falkor", "armv8-a", "crypto-neon-fp-armv8",
1656                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1657                               AArch64::AEK_SHA2, AArch64::AEK_FP,
1658                               AArch64::AEK_SIMD, AArch64::AEK_RDM,
1659                               AArch64::AEK_PERFMON}),
1660         AArch64CPUTestParams("kryo", "armv8-a", "crypto-neon-fp-armv8",
1661                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1662                               AArch64::AEK_SHA2, AArch64::AEK_FP,
1663                               AArch64::AEK_SIMD, AArch64::AEK_PERFMON}),
1664         AArch64CPUTestParams(
1665             "neoverse-e1", "armv8.2-a", "crypto-neon-fp-armv8",
1666             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1667              AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16,
1668              AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RCPC,
1669              AArch64::AEK_RDM, AArch64::AEK_SIMD, AArch64::AEK_SSBS,
1670              AArch64::AEK_PERFMON}),
1671         AArch64CPUTestParams(
1672             "neoverse-n1", "armv8.2-a", "crypto-neon-fp-armv8",
1673             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1674              AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16,
1675              AArch64::AEK_LSE, AArch64::AEK_PROFILE, AArch64::AEK_RAS,
1676              AArch64::AEK_RCPC, AArch64::AEK_RDM, AArch64::AEK_SIMD,
1677              AArch64::AEK_SSBS, AArch64::AEK_PERFMON}),
1678         AArch64CPUTestParams("neoverse-n2", "armv9-a", "crypto-neon-fp-armv8",
1679                              {AArch64::AEK_CRC,         AArch64::AEK_FP,
1680                               AArch64::AEK_SIMD,        AArch64::AEK_FP16,
1681                               AArch64::AEK_RAS,         AArch64::AEK_LSE,
1682                               AArch64::AEK_SVE,         AArch64::AEK_DOTPROD,
1683                               AArch64::AEK_RCPC,        AArch64::AEK_RDM,
1684                               AArch64::AEK_MTE,         AArch64::AEK_SSBS,
1685                               AArch64::AEK_SB,          AArch64::AEK_SVE2,
1686                               AArch64::AEK_SVE2BITPERM, AArch64::AEK_BF16,
1687                               AArch64::AEK_I8MM,        AArch64::AEK_JSCVT,
1688                               AArch64::AEK_FCMA,        AArch64::AEK_PAUTH,
1689                               AArch64::AEK_FP16FML,     AArch64::AEK_PERFMON,
1690                               AArch64::AEK_ETE,         AArch64::AEK_TRBE}),
1691         AArch64CPUTestParams("neoverse-n3", "armv9.2-a", "neon-fp-armv8",
1692                              {AArch64::AEK_BF16,    AArch64::AEK_I8MM,
1693                               AArch64::AEK_SVE,     AArch64::AEK_SVE2,
1694                               AArch64::AEK_FP16,    AArch64::AEK_DOTPROD,
1695                               AArch64::AEK_LSE,     AArch64::AEK_RDM,
1696                               AArch64::AEK_SIMD,    AArch64::AEK_RCPC,
1697                               AArch64::AEK_RAS,     AArch64::AEK_CRC,
1698                               AArch64::AEK_FP,      AArch64::AEK_PROFILE,
1699                               AArch64::AEK_MTE,     AArch64::AEK_SSBS,
1700                               AArch64::AEK_SB,      AArch64::AEK_PREDRES,
1701                               AArch64::AEK_FCMA,    AArch64::AEK_PAUTH,
1702                               AArch64::AEK_FLAGM,   AArch64::AEK_PERFMON,
1703                               AArch64::AEK_RAND,    AArch64::AEK_SVE2BITPERM,
1704                               AArch64::AEK_FP16FML, AArch64::AEK_PROFILE,
1705                               AArch64::AEK_JSCVT,   AArch64::AEK_PERFMON,
1706                               AArch64::AEK_ETE,     AArch64::AEK_SPE_EEF}),
1707         AArch64CPUTestParams(
1708             "ampere1", "armv8.6-a", "crypto-neon-fp-armv8",
1709             {AArch64::AEK_CRC,  AArch64::AEK_FP,    AArch64::AEK_FP16,
1710              AArch64::AEK_SIMD, AArch64::AEK_RAS,   AArch64::AEK_LSE,
1711              AArch64::AEK_RDM,  AArch64::AEK_RCPC,  AArch64::AEK_DOTPROD,
1712              AArch64::AEK_SHA3, AArch64::AEK_BF16,  AArch64::AEK_SHA2,
1713              AArch64::AEK_AES,  AArch64::AEK_I8MM,  AArch64::AEK_SSBS,
1714              AArch64::AEK_SB,   AArch64::AEK_RAND,  AArch64::AEK_JSCVT,
1715              AArch64::AEK_FCMA, AArch64::AEK_PAUTH, AArch64::AEK_PERFMON}),
1716         AArch64CPUTestParams(
1717             "ampere1a", "armv8.6-a", "crypto-neon-fp-armv8",
1718             {AArch64::AEK_CRC,   AArch64::AEK_FP,     AArch64::AEK_FP16,
1719              AArch64::AEK_SIMD,  AArch64::AEK_RAS,    AArch64::AEK_LSE,
1720              AArch64::AEK_RDM,   AArch64::AEK_RCPC,   AArch64::AEK_DOTPROD,
1721              AArch64::AEK_SM4,   AArch64::AEK_SHA3,   AArch64::AEK_BF16,
1722              AArch64::AEK_SHA2,  AArch64::AEK_AES,    AArch64::AEK_I8MM,
1723              AArch64::AEK_SSBS,  AArch64::AEK_SB,     AArch64::AEK_RAND,
1724              AArch64::AEK_MTE,   AArch64::AEK_JSCVT,  AArch64::AEK_FCMA,
1725              AArch64::AEK_PAUTH, AArch64::AEK_PERFMON}),
1726         AArch64CPUTestParams(
1727             "ampere1b", "armv8.7-a", "crypto-neon-fp-armv8",
1728             {AArch64::AEK_CRC,   AArch64::AEK_FP,    AArch64::AEK_FP16,
1729              AArch64::AEK_SIMD,  AArch64::AEK_RAS,   AArch64::AEK_LSE,
1730              AArch64::AEK_RDM,   AArch64::AEK_RCPC,  AArch64::AEK_DOTPROD,
1731              AArch64::AEK_SM4,   AArch64::AEK_SHA3,  AArch64::AEK_BF16,
1732              AArch64::AEK_SHA2,  AArch64::AEK_AES,   AArch64::AEK_I8MM,
1733              AArch64::AEK_SSBS,  AArch64::AEK_SB,    AArch64::AEK_RAND,
1734              AArch64::AEK_MTE,   AArch64::AEK_JSCVT, AArch64::AEK_FCMA,
1735              AArch64::AEK_PAUTH, AArch64::AEK_CSSC,  AArch64::AEK_PERFMON,
1736              AArch64::AEK_WFXT}),
1737         AArch64CPUTestParams(
1738             "neoverse-512tvb", "armv8.4-a", "crypto-neon-fp-armv8",
1739             {AArch64::AEK_RAS,     AArch64::AEK_SVE,     AArch64::AEK_SSBS,
1740              AArch64::AEK_RCPC,    AArch64::AEK_CRC,     AArch64::AEK_FP,
1741              AArch64::AEK_SIMD,    AArch64::AEK_RAS,     AArch64::AEK_LSE,
1742              AArch64::AEK_RDM,     AArch64::AEK_RCPC,    AArch64::AEK_DOTPROD,
1743              AArch64::AEK_AES,     AArch64::AEK_SHA2,    AArch64::AEK_SHA3,
1744              AArch64::AEK_SM4,     AArch64::AEK_FP16,    AArch64::AEK_BF16,
1745              AArch64::AEK_PROFILE, AArch64::AEK_RAND,    AArch64::AEK_FP16FML,
1746              AArch64::AEK_I8MM,    AArch64::AEK_JSCVT,   AArch64::AEK_FCMA,
1747              AArch64::AEK_PAUTH,   AArch64::AEK_PERFMON, AArch64::AEK_CCDP}),
1748         AArch64CPUTestParams("thunderx2t99", "armv8.1-a",
1749                              "crypto-neon-fp-armv8",
1750                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1751                               AArch64::AEK_SHA2, AArch64::AEK_LSE,
1752                               AArch64::AEK_RDM, AArch64::AEK_FP,
1753                               AArch64::AEK_SIMD}),
1754         AArch64CPUTestParams(
1755             "thunderx3t110",
1756             "armv8.3-a", "crypto-neon-fp-armv8",
1757             {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2,
1758              AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_FP,
1759              AArch64::AEK_SIMD, AArch64::AEK_RAS, AArch64::AEK_RCPC,
1760              AArch64::AEK_JSCVT, AArch64::AEK_FCMA, AArch64::AEK_PAUTH,
1761              AArch64::AEK_PERFMON}),
1762         AArch64CPUTestParams("thunderx", "armv8-a", "crypto-neon-fp-armv8",
1763                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1764                               AArch64::AEK_SHA2, AArch64::AEK_SIMD,
1765                               AArch64::AEK_FP, AArch64::AEK_PERFMON}),
1766         AArch64CPUTestParams("thunderxt81", "armv8-a", "crypto-neon-fp-armv8",
1767                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1768                               AArch64::AEK_SHA2, AArch64::AEK_SIMD,
1769                               AArch64::AEK_FP, AArch64::AEK_PERFMON}),
1770         AArch64CPUTestParams("thunderxt83", "armv8-a", "crypto-neon-fp-armv8",
1771                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1772                               AArch64::AEK_SHA2, AArch64::AEK_SIMD,
1773                               AArch64::AEK_FP, AArch64::AEK_PERFMON}),
1774         AArch64CPUTestParams("thunderxt88", "armv8-a", "crypto-neon-fp-armv8",
1775                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1776                               AArch64::AEK_SHA2, AArch64::AEK_SIMD,
1777                               AArch64::AEK_FP, AArch64::AEK_PERFMON}),
1778         AArch64CPUTestParams(
1779             "tsv110", "armv8.2-a", "crypto-neon-fp-armv8",
1780             {AArch64::AEK_CRC, AArch64::AEK_AES,
1781              AArch64::AEK_SHA2, AArch64::AEK_FP, AArch64::AEK_SIMD,
1782              AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_RDM,
1783              AArch64::AEK_PROFILE, AArch64::AEK_JSCVT, AArch64::AEK_FCMA,
1784              AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_DOTPROD,
1785              AArch64::AEK_PERFMON}),
1786         AArch64CPUTestParams("a64fx", "armv8.2-a", "crypto-neon-fp-armv8",
1787                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1788                               AArch64::AEK_SHA2, AArch64::AEK_FP,
1789                               AArch64::AEK_SIMD, AArch64::AEK_FP16,
1790                               AArch64::AEK_RAS, AArch64::AEK_LSE,
1791                               AArch64::AEK_SVE, AArch64::AEK_RDM,
1792                               AArch64::AEK_PERFMON, AArch64::AEK_FCMA}),
1793         AArch64CPUTestParams("carmel", "armv8.2-a", "crypto-neon-fp-armv8",
1794                              {AArch64::AEK_CRC, AArch64::AEK_AES,
1795                               AArch64::AEK_SHA2, AArch64::AEK_FP,
1796                               AArch64::AEK_SIMD, AArch64::AEK_FP16,
1797                               AArch64::AEK_RAS, AArch64::AEK_LSE,
1798                               AArch64::AEK_RDM}),
1799         AArch64CPUTestParams(
1800             "oryon-1", "armv8.6-a", "crypto-neon-fp-armv8",
1801             {AArch64::AEK_CRC,     AArch64::AEK_FP,      AArch64::AEK_PAUTH,
1802              AArch64::AEK_FCMA,    AArch64::AEK_JSCVT,   AArch64::AEK_SIMD,
1803              AArch64::AEK_RAS,     AArch64::AEK_LSE,     AArch64::AEK_RDM,
1804              AArch64::AEK_RCPC,    AArch64::AEK_DOTPROD, AArch64::AEK_SM4,
1805              AArch64::AEK_SHA3,    AArch64::AEK_BF16,    AArch64::AEK_SHA2,
1806              AArch64::AEK_AES,     AArch64::AEK_I8MM,    AArch64::AEK_RAND,
1807              AArch64::AEK_PROFILE, AArch64::AEK_PERFMON})),
1808 
1809     AArch64CPUTestParams::PrintToStringParamName);
1810 
1811 // Note: number of CPUs includes aliases.
1812 static constexpr unsigned NumAArch64CPUArchs = 81;
1813 
1814 TEST(TargetParserTest, testAArch64CPUArchList) {
1815   SmallVector<StringRef, NumAArch64CPUArchs> List;
1816   AArch64::fillValidCPUArchList(List);
1817 
1818   // No list exists for these in this test suite, so ensure all are
1819   // valid, and match the expected 'magic' count.
1820   EXPECT_EQ(List.size(), NumAArch64CPUArchs);
1821   for (StringRef CPU : List) {
1822     EXPECT_TRUE(AArch64::parseCpu(CPU));
1823   }
1824 }
1825 
1826 bool testAArch64Arch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch,
1827                      unsigned ArchAttr) {
1828   const AArch64::ArchInfo *AI = AArch64::parseArch(Arch);
1829   return AI != nullptr;
1830 }
1831 
1832 TEST(TargetParserTest, testAArch64Arch) {
1833   EXPECT_TRUE(testAArch64Arch("armv8-a", "cortex-a53", "v8a",
1834                               ARMBuildAttrs::CPUArch::v8_A));
1835   EXPECT_TRUE(testAArch64Arch("armv8.1-a", "generic", "v8.1a",
1836                               ARMBuildAttrs::CPUArch::v8_A));
1837   EXPECT_TRUE(testAArch64Arch("armv8.2-a", "generic", "v8.2a",
1838                               ARMBuildAttrs::CPUArch::v8_A));
1839   EXPECT_TRUE(testAArch64Arch("armv8.3-a", "generic", "v8.3a",
1840                               ARMBuildAttrs::CPUArch::v8_A));
1841   EXPECT_TRUE(testAArch64Arch("armv8.4-a", "generic", "v8.4a",
1842                               ARMBuildAttrs::CPUArch::v8_A));
1843   EXPECT_TRUE(testAArch64Arch("armv8.5-a", "generic", "v8.5a",
1844                               ARMBuildAttrs::CPUArch::v8_A));
1845   EXPECT_TRUE(testAArch64Arch("armv8.6-a", "generic", "v8.6a",
1846                               ARMBuildAttrs::CPUArch::v8_A));
1847   EXPECT_TRUE(testAArch64Arch("armv8.7-a", "generic", "v8.7a",
1848                               ARMBuildAttrs::CPUArch::v8_A));
1849   EXPECT_TRUE(testAArch64Arch("armv8.8-a", "generic", "v8.8a",
1850                               ARMBuildAttrs::CPUArch::v8_A));
1851   EXPECT_TRUE(testAArch64Arch("armv8.9-a", "generic", "v8.9a",
1852                               ARMBuildAttrs::CPUArch::v8_A));
1853   EXPECT_TRUE(testAArch64Arch("armv9-a", "generic", "v9a",
1854                               ARMBuildAttrs::CPUArch::v8_A));
1855   EXPECT_TRUE(testAArch64Arch("armv9.1-a", "generic", "v9.1a",
1856                               ARMBuildAttrs::CPUArch::v8_A));
1857   EXPECT_TRUE(testAArch64Arch("armv9.2-a", "generic", "v9.2a",
1858                               ARMBuildAttrs::CPUArch::v8_A));
1859   EXPECT_TRUE(testAArch64Arch("armv9.3-a", "generic", "v9.3a",
1860                               ARMBuildAttrs::CPUArch::v8_A));
1861   EXPECT_TRUE(testAArch64Arch("armv9.4-a", "generic", "v9.4a",
1862                               ARMBuildAttrs::CPUArch::v8_A));
1863   EXPECT_TRUE(testAArch64Arch("armv9.5-a", "generic", "v9.5a",
1864                               ARMBuildAttrs::CPUArch::v8_A));
1865 }
1866 
1867 bool testAArch64Extension(StringRef CPUName, StringRef ArchExt) {
1868   std::optional<AArch64::ExtensionInfo> Extension =
1869       AArch64::parseArchExtension(ArchExt);
1870   if (!Extension)
1871     return false;
1872   std::optional<AArch64::CpuInfo> CpuInfo = AArch64::parseCpu(CPUName);
1873   return CpuInfo->getImpliedExtensions().test(Extension->ID);
1874 }
1875 
1876 bool testAArch64Extension(const AArch64::ArchInfo &AI, StringRef ArchExt) {
1877   std::optional<AArch64::ExtensionInfo> Extension =
1878       AArch64::parseArchExtension(ArchExt);
1879   if (!Extension)
1880     return false;
1881   return AI.DefaultExts.test(Extension->ID);
1882 }
1883 
1884 TEST(TargetParserTest, testAArch64Extension) {
1885   EXPECT_FALSE(testAArch64Extension("cortex-a34", "ras"));
1886   EXPECT_FALSE(testAArch64Extension("cortex-a35", "ras"));
1887   EXPECT_FALSE(testAArch64Extension("cortex-a53", "ras"));
1888   EXPECT_TRUE(testAArch64Extension("cortex-a55", "ras"));
1889   EXPECT_TRUE(testAArch64Extension("cortex-a55", "fp16"));
1890   EXPECT_FALSE(testAArch64Extension("cortex-a55", "fp16fml"));
1891   EXPECT_TRUE(testAArch64Extension("cortex-a55", "dotprod"));
1892   EXPECT_FALSE(testAArch64Extension("cortex-a57", "ras"));
1893   EXPECT_FALSE(testAArch64Extension("cortex-a72", "ras"));
1894   EXPECT_FALSE(testAArch64Extension("cortex-a73", "ras"));
1895   EXPECT_TRUE(testAArch64Extension("cortex-a75", "ras"));
1896   EXPECT_TRUE(testAArch64Extension("cortex-a75", "fp16"));
1897   EXPECT_FALSE(testAArch64Extension("cortex-a75", "fp16fml"));
1898   EXPECT_TRUE(testAArch64Extension("cortex-a75", "dotprod"));
1899   EXPECT_TRUE(testAArch64Extension("cortex-r82", "ras"));
1900   EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16"));
1901   EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16fml"));
1902   EXPECT_TRUE(testAArch64Extension("cortex-r82", "dotprod"));
1903   EXPECT_TRUE(testAArch64Extension("cortex-r82", "lse"));
1904   EXPECT_FALSE(testAArch64Extension("cyclone", "ras"));
1905   EXPECT_FALSE(testAArch64Extension("exynos-m3", "ras"));
1906   EXPECT_TRUE(testAArch64Extension("exynos-m4", "dotprod"));
1907   EXPECT_TRUE(testAArch64Extension("exynos-m4", "fp16"));
1908   EXPECT_TRUE(testAArch64Extension("exynos-m4", "lse"));
1909   EXPECT_TRUE(testAArch64Extension("exynos-m4", "ras"));
1910   EXPECT_TRUE(testAArch64Extension("exynos-m4", "rdm"));
1911   EXPECT_TRUE(testAArch64Extension("exynos-m5", "dotprod"));
1912   EXPECT_TRUE(testAArch64Extension("exynos-m5", "fp16"));
1913   EXPECT_TRUE(testAArch64Extension("exynos-m5", "lse"));
1914   EXPECT_TRUE(testAArch64Extension("exynos-m5", "ras"));
1915   EXPECT_TRUE(testAArch64Extension("exynos-m5", "rdm"));
1916   EXPECT_TRUE(testAArch64Extension("falkor", "rdm"));
1917   EXPECT_FALSE(testAArch64Extension("kryo", "ras"));
1918   EXPECT_TRUE(testAArch64Extension("saphira", "crc"));
1919   EXPECT_TRUE(testAArch64Extension("saphira", "lse"));
1920   EXPECT_TRUE(testAArch64Extension("saphira", "rdm"));
1921   EXPECT_TRUE(testAArch64Extension("saphira", "ras"));
1922   EXPECT_TRUE(testAArch64Extension("saphira", "rcpc"));
1923   EXPECT_TRUE(testAArch64Extension("saphira", "profile"));
1924   EXPECT_FALSE(testAArch64Extension("saphira", "fp16"));
1925   EXPECT_FALSE(testAArch64Extension("thunderx2t99", "ras"));
1926   EXPECT_FALSE(testAArch64Extension("thunderx", "lse"));
1927   EXPECT_FALSE(testAArch64Extension("thunderxt81", "lse"));
1928   EXPECT_FALSE(testAArch64Extension("thunderxt83", "lse"));
1929   EXPECT_FALSE(testAArch64Extension("thunderxt88", "lse"));
1930   EXPECT_TRUE(testAArch64Extension("tsv110", "aes"));
1931   EXPECT_TRUE(testAArch64Extension("tsv110", "sha2"));
1932   EXPECT_FALSE(testAArch64Extension("tsv110", "sha3"));
1933   EXPECT_FALSE(testAArch64Extension("tsv110", "sm4"));
1934   EXPECT_TRUE(testAArch64Extension("tsv110", "ras"));
1935   EXPECT_TRUE(testAArch64Extension("tsv110", "profile"));
1936   EXPECT_TRUE(testAArch64Extension("tsv110", "fp16"));
1937   EXPECT_TRUE(testAArch64Extension("tsv110", "fp16fml"));
1938   EXPECT_TRUE(testAArch64Extension("tsv110", "dotprod"));
1939   EXPECT_TRUE(testAArch64Extension("tsv110", "jscvt"));
1940   EXPECT_TRUE(testAArch64Extension("tsv110", "fcma"));
1941   EXPECT_TRUE(testAArch64Extension("a64fx", "fp16"));
1942   EXPECT_TRUE(testAArch64Extension("a64fx", "sve"));
1943   EXPECT_FALSE(testAArch64Extension("a64fx", "sve2"));
1944   EXPECT_TRUE(testAArch64Extension("carmel", "aes"));
1945   EXPECT_TRUE(testAArch64Extension("carmel", "sha2"));
1946   EXPECT_TRUE(testAArch64Extension("carmel", "fp16"));
1947 
1948   EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8A, "ras"));
1949   EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_1A, "ras"));
1950   EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "profile"));
1951   EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "fp16"));
1952   EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "fp16fml"));
1953   EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A, "fp16"));
1954   EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A, "fp16fml"));
1955   EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A, "fp16"));
1956   EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A, "fp16fml"));
1957 }
1958 
1959 TEST(TargetParserTest, AArch64ExtensionFeatures) {
1960   std::vector<uint64_t> Extensions = {
1961       AArch64::AEK_CRC,          AArch64::AEK_LSE,
1962       AArch64::AEK_RDM,          AArch64::AEK_CRYPTO,
1963       AArch64::AEK_SM4,          AArch64::AEK_SHA3,
1964       AArch64::AEK_SHA2,         AArch64::AEK_AES,
1965       AArch64::AEK_DOTPROD,      AArch64::AEK_FP,
1966       AArch64::AEK_SIMD,         AArch64::AEK_FP16,
1967       AArch64::AEK_FP16FML,      AArch64::AEK_PROFILE,
1968       AArch64::AEK_RAS,          AArch64::AEK_SVE,
1969       AArch64::AEK_SVE2,         AArch64::AEK_SVE2AES,
1970       AArch64::AEK_SVE2SM4,      AArch64::AEK_SVE2SHA3,
1971       AArch64::AEK_SVE2BITPERM,  AArch64::AEK_RCPC,
1972       AArch64::AEK_RAND,         AArch64::AEK_MTE,
1973       AArch64::AEK_SSBS,         AArch64::AEK_SB,
1974       AArch64::AEK_PREDRES,      AArch64::AEK_BF16,
1975       AArch64::AEK_I8MM,         AArch64::AEK_F32MM,
1976       AArch64::AEK_F64MM,        AArch64::AEK_TME,
1977       AArch64::AEK_LS64,         AArch64::AEK_BRBE,
1978       AArch64::AEK_PAUTH,        AArch64::AEK_FLAGM,
1979       AArch64::AEK_SME,          AArch64::AEK_SMEF64F64,
1980       AArch64::AEK_SMEI16I64,    AArch64::AEK_SME2,
1981       AArch64::AEK_HBC,          AArch64::AEK_MOPS,
1982       AArch64::AEK_PERFMON,      AArch64::AEK_SVE2P1,
1983       AArch64::AEK_SME2P1,       AArch64::AEK_B16B16,
1984       AArch64::AEK_SMEF16F16,    AArch64::AEK_CSSC,
1985       AArch64::AEK_RCPC3,        AArch64::AEK_THE,
1986       AArch64::AEK_D128,         AArch64::AEK_LSE128,
1987       AArch64::AEK_SPECRES2,     AArch64::AEK_RASV2,
1988       AArch64::AEK_ITE,          AArch64::AEK_GCS,
1989       AArch64::AEK_FAMINMAX,     AArch64::AEK_FP8FMA,
1990       AArch64::AEK_SSVE_FP8FMA,  AArch64::AEK_FP8DOT2,
1991       AArch64::AEK_SSVE_FP8DOT2, AArch64::AEK_FP8DOT4,
1992       AArch64::AEK_SSVE_FP8DOT4, AArch64::AEK_LUT,
1993       AArch64::AEK_SME_LUTV2,    AArch64::AEK_SMEF8F16,
1994       AArch64::AEK_SMEF8F32,     AArch64::AEK_SMEFA64,
1995       AArch64::AEK_CPA,          AArch64::AEK_PAUTHLR,
1996       AArch64::AEK_TLBIW,        AArch64::AEK_JSCVT,
1997       AArch64::AEK_FCMA,         AArch64::AEK_FP8,
1998 
1999   };
2000 
2001   std::vector<StringRef> Features;
2002 
2003   AArch64::ExtensionBitset ExtVal;
2004   for (auto Ext : Extensions)
2005     ExtVal.set(Ext);
2006 
2007   // Test an empty set of features.
2008   EXPECT_TRUE(AArch64::getExtensionFeatures({}, Features));
2009   EXPECT_TRUE(Features.size() == 0);
2010 
2011   AArch64::getExtensionFeatures(ExtVal, Features);
2012   EXPECT_EQ(Extensions.size(), Features.size());
2013 
2014   EXPECT_TRUE(llvm::is_contained(Features, "+crc"));
2015   EXPECT_TRUE(llvm::is_contained(Features, "+lse"));
2016   EXPECT_TRUE(llvm::is_contained(Features, "+rdm"));
2017   EXPECT_TRUE(llvm::is_contained(Features, "+crypto"));
2018   EXPECT_TRUE(llvm::is_contained(Features, "+sm4"));
2019   EXPECT_TRUE(llvm::is_contained(Features, "+sha3"));
2020   EXPECT_TRUE(llvm::is_contained(Features, "+sha2"));
2021   EXPECT_TRUE(llvm::is_contained(Features, "+aes"));
2022   EXPECT_TRUE(llvm::is_contained(Features, "+dotprod"));
2023   EXPECT_TRUE(llvm::is_contained(Features, "+fp-armv8"));
2024   EXPECT_TRUE(llvm::is_contained(Features, "+neon"));
2025   EXPECT_TRUE(llvm::is_contained(Features, "+fullfp16"));
2026   EXPECT_TRUE(llvm::is_contained(Features, "+fp16fml"));
2027   EXPECT_TRUE(llvm::is_contained(Features, "+spe"));
2028   EXPECT_TRUE(llvm::is_contained(Features, "+ras"));
2029   EXPECT_TRUE(llvm::is_contained(Features, "+sve"));
2030   EXPECT_TRUE(llvm::is_contained(Features, "+sve2"));
2031   EXPECT_TRUE(llvm::is_contained(Features, "+sve2-aes"));
2032   EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sm4"));
2033   EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sha3"));
2034   EXPECT_TRUE(llvm::is_contained(Features, "+sve2-bitperm"));
2035   EXPECT_TRUE(llvm::is_contained(Features, "+sve2p1"));
2036   EXPECT_TRUE(llvm::is_contained(Features, "+b16b16"));
2037   EXPECT_TRUE(llvm::is_contained(Features, "+rcpc"));
2038   EXPECT_TRUE(llvm::is_contained(Features, "+rand"));
2039   EXPECT_TRUE(llvm::is_contained(Features, "+mte"));
2040   EXPECT_TRUE(llvm::is_contained(Features, "+ssbs"));
2041   EXPECT_TRUE(llvm::is_contained(Features, "+sb"));
2042   EXPECT_TRUE(llvm::is_contained(Features, "+predres"));
2043   EXPECT_TRUE(llvm::is_contained(Features, "+bf16"));
2044   EXPECT_TRUE(llvm::is_contained(Features, "+i8mm"));
2045   EXPECT_TRUE(llvm::is_contained(Features, "+f32mm"));
2046   EXPECT_TRUE(llvm::is_contained(Features, "+f64mm"));
2047   EXPECT_TRUE(llvm::is_contained(Features, "+tme"));
2048   EXPECT_TRUE(llvm::is_contained(Features, "+ls64"));
2049   EXPECT_TRUE(llvm::is_contained(Features, "+brbe"));
2050   EXPECT_TRUE(llvm::is_contained(Features, "+pauth"));
2051   EXPECT_TRUE(llvm::is_contained(Features, "+flagm"));
2052   EXPECT_TRUE(llvm::is_contained(Features, "+sme"));
2053   EXPECT_TRUE(llvm::is_contained(Features, "+sme-f64f64"));
2054   EXPECT_TRUE(llvm::is_contained(Features, "+sme-i16i64"));
2055   EXPECT_TRUE(llvm::is_contained(Features, "+sme-f16f16"));
2056   EXPECT_TRUE(llvm::is_contained(Features, "+sme2"));
2057   EXPECT_TRUE(llvm::is_contained(Features, "+sme2p1"));
2058   EXPECT_TRUE(llvm::is_contained(Features, "+hbc"));
2059   EXPECT_TRUE(llvm::is_contained(Features, "+mops"));
2060   EXPECT_TRUE(llvm::is_contained(Features, "+perfmon"));
2061   EXPECT_TRUE(llvm::is_contained(Features, "+cssc"));
2062   EXPECT_TRUE(llvm::is_contained(Features, "+rcpc3"));
2063   EXPECT_TRUE(llvm::is_contained(Features, "+the"));
2064   EXPECT_TRUE(llvm::is_contained(Features, "+d128"));
2065   EXPECT_TRUE(llvm::is_contained(Features, "+lse128"));
2066   EXPECT_TRUE(llvm::is_contained(Features, "+specres2"));
2067   EXPECT_TRUE(llvm::is_contained(Features, "+ite"));
2068   EXPECT_TRUE(llvm::is_contained(Features, "+gcs"));
2069   EXPECT_TRUE(llvm::is_contained(Features, "+fp8"));
2070   EXPECT_TRUE(llvm::is_contained(Features, "+faminmax"));
2071   EXPECT_TRUE(llvm::is_contained(Features, "+fp8fma"));
2072   EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8fma"));
2073   EXPECT_TRUE(llvm::is_contained(Features, "+fp8dot2"));
2074   EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8dot2"));
2075   EXPECT_TRUE(llvm::is_contained(Features, "+fp8dot4"));
2076   EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8dot4"));
2077   EXPECT_TRUE(llvm::is_contained(Features, "+lut"));
2078   EXPECT_TRUE(llvm::is_contained(Features, "+sme-lutv2"));
2079   EXPECT_TRUE(llvm::is_contained(Features, "+sme-f8f16"));
2080   EXPECT_TRUE(llvm::is_contained(Features, "+sme-f8f32"));
2081   EXPECT_TRUE(llvm::is_contained(Features, "+sme-fa64"));
2082   EXPECT_TRUE(llvm::is_contained(Features, "+cpa"));
2083   EXPECT_TRUE(llvm::is_contained(Features, "+pauth-lr"));
2084   EXPECT_TRUE(llvm::is_contained(Features, "+tlbiw"));
2085   EXPECT_TRUE(llvm::is_contained(Features, "+jsconv"));
2086   EXPECT_TRUE(llvm::is_contained(Features, "+complxnum"));
2087 
2088   // Assuming we listed every extension above, this should produce the same
2089   // result.
2090   std::vector<StringRef> AllFeatures;
2091   EXPECT_TRUE(AArch64::getExtensionFeatures(ExtVal, AllFeatures));
2092   EXPECT_THAT(Features, ::testing::ContainerEq(AllFeatures));
2093 }
2094 
2095 TEST(TargetParserTest, AArch64ArchFeatures) {
2096   EXPECT_EQ(AArch64::ARMV8A.ArchFeature, "+v8a");
2097   EXPECT_EQ(AArch64::ARMV8_1A.ArchFeature, "+v8.1a");
2098   EXPECT_EQ(AArch64::ARMV8_2A.ArchFeature, "+v8.2a");
2099   EXPECT_EQ(AArch64::ARMV8_3A.ArchFeature, "+v8.3a");
2100   EXPECT_EQ(AArch64::ARMV8_4A.ArchFeature, "+v8.4a");
2101   EXPECT_EQ(AArch64::ARMV8_5A.ArchFeature, "+v8.5a");
2102   EXPECT_EQ(AArch64::ARMV8_6A.ArchFeature, "+v8.6a");
2103   EXPECT_EQ(AArch64::ARMV8_7A.ArchFeature, "+v8.7a");
2104   EXPECT_EQ(AArch64::ARMV8_8A.ArchFeature, "+v8.8a");
2105   EXPECT_EQ(AArch64::ARMV8_9A.ArchFeature, "+v8.9a");
2106   EXPECT_EQ(AArch64::ARMV9A.ArchFeature, "+v9a");
2107   EXPECT_EQ(AArch64::ARMV9_1A.ArchFeature, "+v9.1a");
2108   EXPECT_EQ(AArch64::ARMV9_2A.ArchFeature, "+v9.2a");
2109   EXPECT_EQ(AArch64::ARMV9_3A.ArchFeature, "+v9.3a");
2110   EXPECT_EQ(AArch64::ARMV9_4A.ArchFeature, "+v9.4a");
2111   EXPECT_EQ(AArch64::ARMV9_5A.ArchFeature, "+v9.5a");
2112   EXPECT_EQ(AArch64::ARMV8R.ArchFeature, "+v8r");
2113 }
2114 
2115 TEST(TargetParserTest, AArch64ArchPartialOrder) {
2116   for (const auto *A : AArch64::ArchInfos) {
2117     EXPECT_EQ(*A, *A);
2118 
2119     // v8r has no relation to other valid architectures
2120     if (*A != AArch64::ARMV8R) {
2121       EXPECT_FALSE(A->implies(AArch64::ARMV8R));
2122       EXPECT_FALSE(AArch64::ARMV8R.implies(*A));
2123     }
2124   }
2125 
2126   for (const auto *A : {
2127            &AArch64::ARMV8_1A,
2128            &AArch64::ARMV8_2A,
2129            &AArch64::ARMV8_3A,
2130            &AArch64::ARMV8_4A,
2131            &AArch64::ARMV8_5A,
2132            &AArch64::ARMV8_6A,
2133            &AArch64::ARMV8_7A,
2134            &AArch64::ARMV8_8A,
2135            &AArch64::ARMV8_9A,
2136        })
2137     EXPECT_TRUE(A->implies(AArch64::ARMV8A));
2138 
2139   for (const auto *A :
2140        {&AArch64::ARMV9_1A, &AArch64::ARMV9_2A, &AArch64::ARMV9_3A,
2141         &AArch64::ARMV9_4A, &AArch64::ARMV9_5A})
2142     EXPECT_TRUE(A->implies(AArch64::ARMV9A));
2143 
2144   EXPECT_TRUE(AArch64::ARMV8_1A.implies(AArch64::ARMV8A));
2145   EXPECT_TRUE(AArch64::ARMV8_2A.implies(AArch64::ARMV8_1A));
2146   EXPECT_TRUE(AArch64::ARMV8_3A.implies(AArch64::ARMV8_2A));
2147   EXPECT_TRUE(AArch64::ARMV8_4A.implies(AArch64::ARMV8_3A));
2148   EXPECT_TRUE(AArch64::ARMV8_5A.implies(AArch64::ARMV8_4A));
2149   EXPECT_TRUE(AArch64::ARMV8_6A.implies(AArch64::ARMV8_5A));
2150   EXPECT_TRUE(AArch64::ARMV8_7A.implies(AArch64::ARMV8_6A));
2151   EXPECT_TRUE(AArch64::ARMV8_8A.implies(AArch64::ARMV8_7A));
2152   EXPECT_TRUE(AArch64::ARMV8_9A.implies(AArch64::ARMV8_8A));
2153 
2154   EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV9A));
2155   EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV9_1A));
2156   EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV9_2A));
2157   EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV9_3A));
2158   EXPECT_TRUE(AArch64::ARMV9_5A.implies(AArch64::ARMV9_4A));
2159 
2160   EXPECT_TRUE(AArch64::ARMV9A.implies(AArch64::ARMV8_5A));
2161   EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV8_6A));
2162   EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV8_7A));
2163   EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV8_8A));
2164   EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV8_9A));
2165 }
2166 
2167 TEST(TargetParserTest, AArch64ArchExtFeature) {
2168   const char *ArchExt[][4] = {
2169       {"crc", "nocrc", "+crc", "-crc"},
2170       {"crypto", "nocrypto", "+crypto", "-crypto"},
2171       {"flagm", "noflagm", "+flagm", "-flagm"},
2172       {"fp", "nofp", "+fp-armv8", "-fp-armv8"},
2173       {"simd", "nosimd", "+neon", "-neon"},
2174       {"fp16", "nofp16", "+fullfp16", "-fullfp16"},
2175       {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"},
2176       {"profile", "noprofile", "+spe", "-spe"},
2177       {"ras", "noras", "+ras", "-ras"},
2178       {"lse", "nolse", "+lse", "-lse"},
2179       {"rdm", "nordm", "+rdm", "-rdm"},
2180       {"sve", "nosve", "+sve", "-sve"},
2181       {"sve2", "nosve2", "+sve2", "-sve2"},
2182       {"sve2-aes", "nosve2-aes", "+sve2-aes", "-sve2-aes"},
2183       {"sve2-sm4", "nosve2-sm4", "+sve2-sm4", "-sve2-sm4"},
2184       {"sve2-sha3", "nosve2-sha3", "+sve2-sha3", "-sve2-sha3"},
2185       {"sve2p1", "nosve2p1", "+sve2p1", "-sve2p1"},
2186       {"b16b16", "nob16b16", "+b16b16", "-b16b16"},
2187       {"sve2-bitperm", "nosve2-bitperm", "+sve2-bitperm", "-sve2-bitperm"},
2188       {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
2189       {"rcpc", "norcpc", "+rcpc", "-rcpc"},
2190       {"rng", "norng", "+rand", "-rand"},
2191       {"memtag", "nomemtag", "+mte", "-mte"},
2192       {"tme", "notme", "+tme", "-tme"},
2193       {"pauth", "nopauth", "+pauth", "-pauth"},
2194       {"ssbs", "nossbs", "+ssbs", "-ssbs"},
2195       {"sb", "nosb", "+sb", "-sb"},
2196       {"predres", "nopredres", "+predres", "-predres"},
2197       {"i8mm", "noi8mm", "+i8mm", "-i8mm"},
2198       {"f32mm", "nof32mm", "+f32mm", "-f32mm"},
2199       {"f64mm", "nof64mm", "+f64mm", "-f64mm"},
2200       {"sme", "nosme", "+sme", "-sme"},
2201       {"sme-fa64", "nosme-fa64", "+sme-fa64", "-sme-fa64"},
2202       {"sme-f64f64", "nosme-f64f64", "+sme-f64f64", "-sme-f64f64"},
2203       {"sme-i16i64", "nosme-i16i64", "+sme-i16i64", "-sme-i16i64"},
2204       {"sme-f16f16", "nosme-f16f16", "+sme-f16f16", "-sme-f16f16"},
2205       {"sme2", "nosme2", "+sme2", "-sme2"},
2206       {"sme2p1", "nosme2p1", "+sme2p1", "-sme2p1"},
2207       {"hbc", "nohbc", "+hbc", "-hbc"},
2208       {"mops", "nomops", "+mops", "-mops"},
2209       {"pmuv3", "nopmuv3", "+perfmon", "-perfmon"},
2210       {"predres2", "nopredres2", "+specres2", "-specres2"},
2211       {"rasv2", "norasv2", "+rasv2", "-rasv2"},
2212       {"gcs", "nogcs", "+gcs", "-gcs"},
2213       {"fp8", "nofp8", "+fp8", "-fp8"},
2214       {"faminmax", "nofaminmax", "+faminmax", "-faminmax"},
2215       {"fp8fma", "nofp8fma", "+fp8fma", "-fp8fma"},
2216       {"ssve-fp8fma", "nossve-fp8fma", "+ssve-fp8fma", "-ssve-fp8fma"},
2217       {"fp8dot2", "nofp8dot2", "+fp8dot2", "-fp8dot2"},
2218       {"ssve-fp8dot2", "nossve-fp8dot2", "+ssve-fp8dot2", "-ssve-fp8dot2"},
2219       {"fp8dot4", "nofp8dot4", "+fp8dot4", "-fp8dot4"},
2220       {"ssve-fp8dot4", "nossve-fp8dot4", "+ssve-fp8dot4", "-ssve-fp8dot4"},
2221       {"lut", "nolut", "+lut", "-lut"},
2222       {"sme-lutv2", "nosme-lutv2", "+sme-lutv2", "-sme-lutv2"},
2223       {"sme-f8f16", "nosme-f8f16", "+sme-f8f16", "-sme-f8f16"},
2224       {"sme-f8f32", "nosme-f8f32", "+sme-f8f32", "-sme-f8f32"},
2225   };
2226 
2227   for (unsigned i = 0; i < std::size(ArchExt); i++) {
2228     EXPECT_EQ(StringRef(ArchExt[i][2]),
2229               AArch64::getArchExtFeature(ArchExt[i][0]));
2230     EXPECT_EQ(StringRef(ArchExt[i][3]),
2231               AArch64::getArchExtFeature(ArchExt[i][1]));
2232   }
2233 }
2234 
2235 TEST(TargetParserTest, AArch64PrintSupportedExtensions) {
2236   std::string expected =
2237       "All available -march extensions for AArch64\n\n"
2238       "    Name                Architecture Feature(s)                                Description\n";
2239 
2240   outs().flush();
2241   testing::internal::CaptureStdout();
2242   AArch64::PrintSupportedExtensions();
2243   outs().flush();
2244   std::string captured = testing::internal::GetCapturedStdout();
2245 
2246   // Check that the start of the output is as expected.
2247   EXPECT_EQ(0ULL, captured.find(expected));
2248 
2249   // Should not include "none".
2250   EXPECT_EQ(std::string::npos, captured.find("none"));
2251   // Should not include anything that lacks a feature name. Checking a few here
2252   // but not all as if one is hidden correctly the rest should be.
2253   EXPECT_EQ(std::string::npos, captured.find("memtag3"));
2254   EXPECT_EQ(std::string::npos, captured.find("sha1"));
2255   EXPECT_EQ(std::string::npos, captured.find("ssbs2"));
2256 }
2257 
2258 struct AArch64ExtensionDependenciesBaseArchTestParams {
2259   const llvm::AArch64::ArchInfo &Arch;
2260   std::vector<StringRef> Modifiers;
2261   std::vector<StringRef> ExpectedPos;
2262   std::vector<StringRef> ExpectedNeg;
2263 };
2264 
2265 class AArch64ExtensionDependenciesBaseArchTestFixture
2266     : public ::testing::TestWithParam<
2267           AArch64ExtensionDependenciesBaseArchTestParams> {};
2268 
2269 struct AArch64ExtensionDependenciesBaseCPUTestParams {
2270   StringRef CPUName;
2271   std::vector<StringRef> Modifiers;
2272   std::vector<StringRef> ExpectedPos;
2273   std::vector<StringRef> ExpectedNeg;
2274 };
2275 
2276 class AArch64ExtensionDependenciesBaseCPUTestFixture
2277     : public ::testing::TestWithParam<
2278           AArch64ExtensionDependenciesBaseCPUTestParams> {};
2279 
2280 TEST_P(AArch64ExtensionDependenciesBaseArchTestFixture,
2281        AArch64ExtensionDependenciesBaseArch) {
2282   auto Params = GetParam();
2283 
2284   llvm::AArch64::ExtensionSet Extensions;
2285   Extensions.addArchDefaults(Params.Arch);
2286   for (auto M : Params.Modifiers) {
2287     bool success = Extensions.parseModifier(M);
2288     EXPECT_TRUE(success);
2289   }
2290   std::vector<StringRef> Features;
2291   Extensions.toLLVMFeatureList(Features);
2292 
2293   for (auto E : Params.ExpectedPos) {
2294     std::string PosString = "+";
2295     PosString += E;
2296     std::string NegString = "-";
2297     NegString += E;
2298     ASSERT_THAT(Features, Contains(StrEq(PosString)));
2299     ASSERT_THAT(Features, Not(Contains(StrEq(NegString))));
2300   }
2301 
2302   for (auto E : Params.ExpectedNeg) {
2303     std::string PosString = "+";
2304     PosString += E;
2305     ASSERT_THAT(Features, Not(Contains(StrEq(PosString))));
2306     // Features default to off, so the negative string is not expected in many
2307     // cases.
2308   }
2309 }
2310 
2311 TEST_P(AArch64ExtensionDependenciesBaseCPUTestFixture,
2312        AArch64ExtensionDependenciesBaseCPU) {
2313   auto Params = GetParam();
2314 
2315   llvm::AArch64::ExtensionSet Extensions;
2316   const std::optional<llvm::AArch64::CpuInfo> CPU =
2317       llvm::AArch64::parseCpu(Params.CPUName);
2318   EXPECT_TRUE(CPU);
2319   Extensions.addCPUDefaults(*CPU);
2320   for (auto M : Params.Modifiers) {
2321     bool success = Extensions.parseModifier(M);
2322     EXPECT_TRUE(success);
2323   }
2324   std::vector<StringRef> Features;
2325   Extensions.toLLVMFeatureList(Features);
2326 
2327   for (auto E : Params.ExpectedPos) {
2328     std::string PosString = "+";
2329     PosString += E;
2330     std::string NegString = "-";
2331     NegString += E;
2332     ASSERT_THAT(Features, Contains(StrEq(PosString)));
2333     ASSERT_THAT(Features, Not(Contains(StrEq(NegString))));
2334   }
2335 
2336   for (auto E : Params.ExpectedNeg) {
2337     std::string PosString = "+";
2338     PosString += E;
2339     ASSERT_THAT(Features, Not(Contains(StrEq(PosString))));
2340     // Features default to off, so the negative string is not expected in many
2341     // cases.
2342   }
2343 }
2344 
2345 AArch64ExtensionDependenciesBaseArchTestParams
2346     AArch64ExtensionDependenciesArchData[] = {
2347         // Base architecture features
2348         {AArch64::ARMV8A, {}, {"v8a", "fp-armv8", "neon"}, {}},
2349         {AArch64::ARMV8_1A,
2350          {},
2351          {"v8.1a", "crc", "fp-armv8", "lse", "rdm", "neon"},
2352          {}},
2353         {AArch64::ARMV9_5A, {}, {"v9.5a", "mops", "cpa"}, {}},
2354 
2355         // Positive modifiers
2356         {AArch64::ARMV8A, {"fp16"}, {"fullfp16"}, {}},
2357         {AArch64::ARMV8A, {"dotprod"}, {"dotprod"}, {}},
2358 
2359         // Negative modifiers
2360         {AArch64::ARMV8A, {"nofp"}, {"v8a"}, {"fp-armv8", "neon"}},
2361 
2362         // Mixed modifiers
2363         {AArch64::ARMV8A,
2364          {"fp16", "nofp16"},
2365          {"v8a", "fp-armv8", "neon"},
2366          {"fullfp16"}},
2367         {AArch64::ARMV8A,
2368          {"fp16", "nofp"},
2369          {"v8a"},
2370          {"fp-armv8", "neon", "fullfp16"}},
2371 
2372         // Long dependency chains: sve2-bitperm -> sve2 -> sve -> fp16 -> fp
2373         {AArch64::ARMV8A,
2374          {"nofp", "sve2-bitperm"},
2375          {"fp-armv8", "fullfp16", "sve", "sve2", "sve2-bitperm"},
2376          {}},
2377         {AArch64::ARMV8A,
2378          {"sve2-bitperm", "nofp16"},
2379          {"fp-armv8"},
2380          {"full-fp16", "sve", "sve2", "sve2-bitperm"}},
2381 
2382         // Meaning of +crypto varies with base architecture.
2383         {AArch64::ARMV8A, {"crypto"}, {"aes", "sha2"}, {}},
2384         {AArch64::ARMV8_4A, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}},
2385         {AArch64::ARMV9A, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}},
2386 
2387         // -crypto always disables all crypto features, even if it wouldn't
2388         // enable them.
2389         {AArch64::ARMV8A,
2390          {"aes", "sha2", "sha3", "sm4", "nocrypto"},
2391          {},
2392          {"aes", "sha2", "sha3", "sm4"}},
2393         {AArch64::ARMV8_4A,
2394          {"aes", "sha2", "sha3", "sm4", "nocrypto"},
2395          {},
2396          {"aes", "sha2", "sha3", "sm4"}},
2397 
2398         // +fp16 implies +fp16fml for v8.4A+, but not v9.0-A+
2399         {AArch64::ARMV8_3A, {"fp16"}, {"fullfp16"}, {"fp16fml"}},
2400         {AArch64::ARMV9A, {"fp16"}, {"fullfp16"}, {"fp16fml"}},
2401         {AArch64::ARMV8_4A, {"fp16"}, {"fullfp16", "fp16fml"}, {}},
2402 
2403         // fp -> fp16
2404         {AArch64::ARMV8A, {"nofp", "fp16"}, {"fp-armv8", "fullfp16"}, {}},
2405         {AArch64::ARMV8A, {"fp16", "nofp"}, {}, {"fp-armv8", "fullfp16"}},
2406 
2407         // fp -> simd
2408         {AArch64::ARMV8A, {"nofp", "simd"}, {"fp-armv8", "neon"}, {}},
2409         {AArch64::ARMV8A, {"simd", "nofp"}, {}, {"fp-armv8", "neon"}},
2410 
2411         // fp -> jscvt
2412         {AArch64::ARMV8A, {"nofp", "jscvt"}, {"fp-armv8", "jsconv"}, {}},
2413         {AArch64::ARMV8A, {"jscvt", "nofp"}, {}, {"fp-armv8", "jsconv"}},
2414 
2415         // simd -> {aes, sha2, sha3, sm4}
2416         {AArch64::ARMV8A, {"nosimd", "aes"}, {"neon", "aes"}, {}},
2417         {AArch64::ARMV8A, {"aes", "nosimd"}, {}, {"neon", "aes"}},
2418         {AArch64::ARMV8A, {"nosimd", "sha2"}, {"neon", "sha2"}, {}},
2419         {AArch64::ARMV8A, {"sha2", "nosimd"}, {}, {"neon", "sha2"}},
2420         {AArch64::ARMV8A, {"nosimd", "sha3"}, {"neon", "sha3"}, {}},
2421         {AArch64::ARMV8A, {"sha3", "nosimd"}, {}, {"neon", "sha3"}},
2422         {AArch64::ARMV8A, {"nosimd", "sm4"}, {"neon", "sm4"}, {}},
2423         {AArch64::ARMV8A, {"sm4", "nosimd"}, {}, {"neon", "sm4"}},
2424 
2425         // simd -> {rdm, dotprod, fcma}
2426         {AArch64::ARMV8A, {"nosimd", "rdm"}, {"neon", "rdm"}, {}},
2427         {AArch64::ARMV8A, {"rdm", "nosimd"}, {}, {"neon", "rdm"}},
2428         {AArch64::ARMV8A, {"nosimd", "dotprod"}, {"neon", "dotprod"}, {}},
2429         {AArch64::ARMV8A, {"dotprod", "nosimd"}, {}, {"neon", "dotprod"}},
2430         {AArch64::ARMV8A, {"nosimd", "fcma"}, {"neon", "complxnum"}, {}},
2431         {AArch64::ARMV8A, {"fcma", "nosimd"}, {}, {"neon", "complxnum"}},
2432 
2433         // fp16 -> {fp16fml, sve}
2434         {AArch64::ARMV8A, {"nofp16", "fp16fml"}, {"fullfp16", "fp16fml"}, {}},
2435         {AArch64::ARMV8A, {"fp16fml", "nofp16"}, {}, {"fullfp16", "fp16fml"}},
2436         {AArch64::ARMV8A, {"nofp16", "sve"}, {"fullfp16", "sve"}, {}},
2437         {AArch64::ARMV8A, {"sve", "nofp16"}, {}, {"fullfp16", "sve"}},
2438 
2439         // bf16 -> {sme, b16b16}
2440         {AArch64::ARMV8A, {"nobf16", "sme"}, {"bf16", "sme"}, {}},
2441         {AArch64::ARMV8A, {"sme", "nobf16"}, {}, {"bf16", "sme"}},
2442         {AArch64::ARMV8A, {"nobf16", "b16b16"}, {"bf16", "b16b16"}, {}},
2443         {AArch64::ARMV8A, {"b16b16", "nobf16"}, {}, {"bf16", "b16b16"}},
2444 
2445         // sve -> {sve2, f32mm, f64mm}
2446         {AArch64::ARMV8A, {"nosve", "sve2"}, {"sve", "sve2"}, {}},
2447         {AArch64::ARMV8A, {"sve2", "nosve"}, {}, {"sve", "sve2"}},
2448         {AArch64::ARMV8A, {"nosve", "f32mm"}, {"sve", "f32mm"}, {}},
2449         {AArch64::ARMV8A, {"f32mm", "nosve"}, {}, {"sve", "f32mm"}},
2450         {AArch64::ARMV8A, {"nosve", "f64mm"}, {"sve", "f64mm"}, {}},
2451         {AArch64::ARMV8A, {"f64mm", "nosve"}, {}, {"sve", "f64mm"}},
2452 
2453         // sve2 -> {sve2p1, sve2-bitperm, sve2-aes, sve2-sha3, sve2-sm4}
2454         {AArch64::ARMV8A, {"nosve2", "sve2p1"}, {"sve2", "sve2p1"}, {}},
2455         {AArch64::ARMV8A, {"sve2p1", "nosve2"}, {}, {"sve2", "sve2p1"}},
2456         {AArch64::ARMV8A,
2457          {"nosve2", "sve2-bitperm"},
2458          {"sve2", "sve2-bitperm"},
2459          {}},
2460         {AArch64::ARMV8A,
2461          {"sve2-bitperm", "nosve2"},
2462          {},
2463          {"sve2", "sve2-bitperm"}},
2464         {AArch64::ARMV8A, {"nosve2", "sve2-aes"}, {"sve2", "sve2-aes"}, {}},
2465         {AArch64::ARMV8A, {"sve2-aes", "nosve2"}, {}, {"sve2", "sve2-aes"}},
2466         {AArch64::ARMV8A, {"nosve2", "sve2-sha3"}, {"sve2", "sve2-sha3"}, {}},
2467         {AArch64::ARMV8A, {"sve2-sha3", "nosve2"}, {}, {"sve2", "sve2-sha3"}},
2468         {AArch64::ARMV8A, {"nosve2", "sve2-sm4"}, {"sve2", "sve2-sm4"}, {}},
2469         {AArch64::ARMV8A, {"sve2-sm4", "nosve2"}, {}, {"sve2", "sve2-sm4"}},
2470 
2471         // sme -> {sme2, sme-f16f16, sme-f64f64, sme-i16i64, sme-fa64}
2472         {AArch64::ARMV8A, {"nosme", "sme2"}, {"sme", "sme2"}, {}},
2473         {AArch64::ARMV8A, {"sme2", "nosme"}, {}, {"sme", "sme2"}},
2474         {AArch64::ARMV8A, {"nosme", "sme-f16f16"}, {"sme", "sme-f16f16"}, {}},
2475         {AArch64::ARMV8A, {"sme-f16f16", "nosme"}, {}, {"sme", "sme-f16f16"}},
2476         {AArch64::ARMV8A, {"nosme", "sme-f64f64"}, {"sme", "sme-f64f64"}, {}},
2477         {AArch64::ARMV8A, {"sme-f64f64", "nosme"}, {}, {"sme", "sme-f64f64"}},
2478         {AArch64::ARMV8A, {"nosme", "sme-i16i64"}, {"sme", "sme-i16i64"}, {}},
2479         {AArch64::ARMV8A, {"sme-i16i64", "nosme"}, {}, {"sme", "sme-i16i64"}},
2480         {AArch64::ARMV8A, {"nosme", "sme-fa64"}, {"sme", "sme-fa64"}, {}},
2481         {AArch64::ARMV8A, {"sme-fa64", "nosme"}, {}, {"sme", "sme-fa64"}},
2482 
2483         // sme2 -> {sme2p1, ssve-fp8fma, ssve-fp8dot2, ssve-fp8dot4, sme-f8f16,
2484         // sme-f8f32}
2485         {AArch64::ARMV8A, {"nosme2", "sme2p1"}, {"sme2", "sme2p1"}, {}},
2486         {AArch64::ARMV8A, {"sme2p1", "nosme2"}, {}, {"sme2", "sme2p1"}},
2487         {AArch64::ARMV8A,
2488          {"nosme2", "ssve-fp8fma"},
2489          {"sme2", "ssve-fp8fma"},
2490          {}},
2491         {AArch64::ARMV8A,
2492          {"ssve-fp8fma", "nosme2"},
2493          {},
2494          {"sme2", "ssve-fp8fma"}},
2495         {AArch64::ARMV8A,
2496          {"nosme2", "ssve-fp8dot2"},
2497          {"sme2", "ssve-fp8dot2"},
2498          {}},
2499         {AArch64::ARMV8A,
2500          {"ssve-fp8dot2", "nosme2"},
2501          {},
2502          {"sme2", "ssve-fp8dot2"}},
2503         {AArch64::ARMV8A,
2504          {"nosme2", "ssve-fp8dot4"},
2505          {"sme2", "ssve-fp8dot4"},
2506          {}},
2507         {AArch64::ARMV8A,
2508          {"ssve-fp8dot4", "nosme2"},
2509          {},
2510          {"sme2", "ssve-fp8dot4"}},
2511         {AArch64::ARMV8A, {"nosme2", "sme-f8f16"}, {"sme2", "sme-f8f16"}, {}},
2512         {AArch64::ARMV8A, {"sme-f8f16", "nosme2"}, {}, {"sme2", "sme-f8f16"}},
2513         {AArch64::ARMV8A, {"nosme2", "sme-f8f32"}, {"sme2", "sme-f8f32"}, {}},
2514         {AArch64::ARMV8A, {"sme-f8f32", "nosme2"}, {}, {"sme2", "sme-f8f32"}},
2515 
2516         // fp8 -> {sme-f8f16, sme-f8f32}
2517         {AArch64::ARMV8A, {"nofp8", "sme-f8f16"}, {"fp8", "sme-f8f16"}, {}},
2518         {AArch64::ARMV8A, {"sme-f8f16", "nofp8"}, {}, {"fp8", "sme-f8f16"}},
2519         {AArch64::ARMV8A, {"nofp8", "sme-f8f32"}, {"fp8", "sme-f8f32"}, {}},
2520         {AArch64::ARMV8A, {"sme-f8f32", "nofp8"}, {}, {"fp8", "sme-f8f32"}},
2521 
2522         // lse -> lse128
2523         {AArch64::ARMV8A, {"nolse", "lse128"}, {"lse", "lse128"}, {}},
2524         {AArch64::ARMV8A, {"lse128", "nolse"}, {}, {"lse", "lse128"}},
2525 
2526         // predres -> predres2
2527         {AArch64::ARMV8A,
2528          {"nopredres", "predres2"},
2529          {"predres", "specres2"},
2530          {}},
2531         {AArch64::ARMV8A,
2532          {"predres2", "nopredres"},
2533          {},
2534          {"predres", "specres2"}},
2535 
2536         // ras -> ras2
2537         {AArch64::ARMV8A, {"noras", "rasv2"}, {"ras", "rasv2"}, {}},
2538         {AArch64::ARMV8A, {"rasv2", "noras"}, {}, {"ras", "rasv2"}},
2539 
2540         // rcpc -> rcpc3
2541         {AArch64::ARMV8A, {"norcpc", "rcpc3"}, {"rcpc", "rcpc3"}, {}},
2542         {AArch64::ARMV8A, {"rcpc3", "norcpc"}, {}, {"rcpc", "rcpc3"}},
2543 };
2544 
2545 INSTANTIATE_TEST_SUITE_P(
2546     AArch64ExtensionDependenciesBaseArch,
2547     AArch64ExtensionDependenciesBaseArchTestFixture,
2548     ::testing::ValuesIn(AArch64ExtensionDependenciesArchData));
2549 
2550 AArch64ExtensionDependenciesBaseCPUTestParams
2551     AArch64ExtensionDependenciesCPUData[] = {
2552         // Base CPU features
2553         {"cortex-a57",
2554          {},
2555          {"v8a", "aes", "crc", "fp-armv8", "sha2", "neon"},
2556          {}},
2557         {"cortex-r82",
2558          {},
2559          {"v8r", "crc", "dotprod", "fp-armv8", "fullfp16", "fp16fml", "lse",
2560           "ras", "rcpc", "rdm", "sb", "neon", "ssbs"},
2561          {}},
2562         {"cortex-a520",
2563          {},
2564          {"v9.2a",    "bf16",    "crc",  "dotprod",      "flagm", "fp-armv8",
2565           "fullfp16", "fp16fml", "i8mm", "lse",          "mte",   "pauth",
2566           "perfmon",  "predres", "ras",  "rcpc",         "rdm",   "sb",
2567           "neon",     "ssbs",    "sve",  "sve2-bitperm", "sve2"},
2568          {}},
2569 
2570         // Negative modifiers
2571         {"cortex-r82",
2572          {"nofp"},
2573          {"v8r", "crc", "lse", "ras", "rcpc", "sb", "ssbs"},
2574          {"fp-armv8", "neon", "fullfp16", "fp16fml", "dotprod", "rdm"}},
2575 };
2576 
2577 INSTANTIATE_TEST_SUITE_P(
2578     AArch64ExtensionDependenciesBaseCPU,
2579     AArch64ExtensionDependenciesBaseCPUTestFixture,
2580     ::testing::ValuesIn(AArch64ExtensionDependenciesCPUData));
2581 
2582 } // namespace
2583