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

source code of llvm/unittests/TargetParser/TargetParserTest.cpp