1 //===----------- TargetParser.cpp - Target Parser -------------------------===//
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
7 //===----------------------------------------------------------------------===//
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"
28 using ::testing::Contains
;
29 using ::testing::StrEq
;
32 const char *ARMArch
[] = {
33 "armv4", "armv4t", "armv5", "armv5t", "armv5e",
34 "armv5te", "armv5tej", "armv6", "armv6j", "armv6k",
35 "armv6hl", "armv6t2", "armv6kz", "armv6z", "armv6zk",
36 "armv6-m", "armv6m", "armv6sm", "armv6s-m", "armv7-a",
37 "armv7", "armv7a", "armv7ve", "armv7hl", "armv7l",
38 "armv7-r", "armv7r", "armv7-m", "armv7m", "armv7k",
39 "armv7s", "armv7e-m", "armv7em", "armv8-a", "armv8",
40 "armv8a", "armv8l", "armv8.1-a", "armv8.1a", "armv8.2-a",
41 "armv8.2a", "armv8.3-a", "armv8.3a", "armv8.4-a", "armv8.4a",
42 "armv8.5-a", "armv8.5a", "armv8.6-a", "armv8.6a", "armv8.7-a",
43 "armv8.7a", "armv8.8-a", "armv8.8a", "armv8.9-a", "armv8.9a",
44 "armv8-r", "armv8r", "armv8-m.base", "armv8m.base", "armv8-m.main",
45 "armv8m.main", "iwmmxt", "iwmmxt2", "xscale", "armv8.1-m.main",
46 "armv9-a", "armv9", "armv9a", "armv9.1-a", "armv9.1a",
47 "armv9.2-a", "armv9.2a", "armv9.3-a", "armv9.3a", "armv9.4-a",
48 "armv9.4a", "armv9.5-a", "armv9.5a", "armv9.6a", "armv9.6-a",
51 std::string
FormatExtensionFlags(int64_t Flags
) {
52 std::vector
<StringRef
> Features
;
54 if (Flags
& ARM::AEK_NONE
)
55 Features
.push_back("none");
56 ARM::getExtensionFeatures(Flags
, Features
);
58 // The target parser also includes every extension you don't have.
59 // E.g. if AEK_CRC is not set then it adds "-crc". Not useful here.
60 Features
.erase(std::remove_if(Features
.begin(), Features
.end(),
61 [](StringRef extension
) {
62 return extension
.starts_with("-");
66 return llvm::join(Features
, ", ");
69 std::string
SerializeExtensionFlags(AArch64::ExtensionBitset Flags
) {
70 std::string SerializedFlags
;
71 std::ostringstream ss
;
73 for (unsigned int i
= 0; i
< AArch64::AEK_NUM_EXTENSIONS
; i
++) {
75 HexValue
|= (int)Flags
[i
];
76 if ((i
+ 1) % 4 == 0) {
77 ss
<< std::hex
<< HexValue
;
81 // check if there are remainig unhandled bits
82 if ((AArch64::AEK_NUM_EXTENSIONS
% 4) != 0)
83 ss
<< std::hex
<< HexValue
;
85 SerializedFlags
= ss
.str();
86 return SerializedFlags
;
89 template <ARM::ISAKind ISAKind
> struct AssertSameExtensionFlags
{
90 AssertSameExtensionFlags(StringRef CPUName
) : CPUName(CPUName
) {}
92 testing::AssertionResult
operator()(const char *m_expr
, const char *n_expr
,
93 uint64_t ExpectedFlags
,
95 if (ExpectedFlags
== GotFlags
)
96 return testing::AssertionSuccess();
98 return testing::AssertionFailure()
99 << llvm::formatv("CPU: {4}\n"
100 "Expected extension flags: {0} ({1:x})\n"
101 " Got extension flags: {2} ({3:x})\n"
102 " Diff: {5} ({6:x})\n",
103 FormatExtensionFlags(ExpectedFlags
), ExpectedFlags
,
104 FormatExtensionFlags(GotFlags
), GotFlags
, CPUName
,
105 FormatExtensionFlags(ExpectedFlags
^ GotFlags
));
111 template <typename T
> struct ARMCPUTestParams
{
112 ARMCPUTestParams(StringRef CPUName
, StringRef ExpectedArch
,
113 StringRef ExpectedFPU
, T ExpectedFlags
, StringRef CPUAttr
)
114 : CPUName(CPUName
), ExpectedArch(ExpectedArch
), ExpectedFPU(ExpectedFPU
),
115 ExpectedFlags(ExpectedFlags
), CPUAttr(CPUAttr
) {}
117 friend std::ostream
&operator<<(std::ostream
&os
,
118 const ARMCPUTestParams
<T
> ¶ms
) {
119 os
<< "\"" << params
.CPUName
.str() << "\", \"" << params
.ExpectedArch
.str()
120 << "\", \"" << params
.ExpectedFPU
.str() << "\", 0x";
121 if constexpr (std::is_same
<T
, uint64_t>::value
)
122 os
<< std::hex
<< params
.ExpectedFlags
;
124 os
<< SerializeExtensionFlags(params
.ExpectedFlags
);
125 os
<< ", \"" << params
.CPUAttr
.str() << "\"";
129 /// Print a gtest-compatible facsimile of the CPUName, to make the test's name
132 /// https://github.com/google/googletest/blob/main/docs/advanced.md#specifying-names-for-value-parameterized-test-parameters
133 static std::string
PrintToStringParamName(
134 const testing::TestParamInfo
<ARMCPUTestParams
<T
>> &Info
) {
135 std::string Name
= Info
.param
.CPUName
.str();
137 if (!std::isalnum(C
))
143 StringRef ExpectedArch
;
144 StringRef ExpectedFPU
;
149 class ARMCPUTestFixture
150 : public ::testing::TestWithParam
<ARMCPUTestParams
<uint64_t>> {};
152 TEST_P(ARMCPUTestFixture
, ARMCPUTests
) {
153 auto params
= GetParam();
155 ARM::ArchKind AK
= ARM::parseCPUArch(params
.CPUName
);
156 EXPECT_EQ(params
.ExpectedArch
, ARM::getArchName(AK
));
158 ARM::FPUKind FPUKind
= ARM::getDefaultFPU(params
.CPUName
, AK
);
159 EXPECT_EQ(params
.ExpectedFPU
, ARM::getFPUName(FPUKind
));
161 uint64_t default_extensions
= ARM::getDefaultExtensions(params
.CPUName
, AK
);
163 AssertSameExtensionFlags
<ARM::ISAKind::ARM
>(params
.CPUName
),
164 params
.ExpectedFlags
, default_extensions
);
166 EXPECT_EQ(params
.CPUAttr
, ARM::getCPUAttr(AK
));
169 // Note that we include ARM::AEK_NONE even when there are other extensions
170 // we expect. This is because the default extensions for a CPU are the sum
171 // of the default extensions for its architecture and for the CPU.
172 // So if a CPU has no extra extensions, it adds AEK_NONE.
173 INSTANTIATE_TEST_SUITE_P(
174 ARMCPUTestsPart1
, ARMCPUTestFixture
,
176 ARMCPUTestParams
<uint64_t>("invalid", "invalid", "invalid",
178 ARMCPUTestParams
<uint64_t>("generic", "invalid", "none", ARM::AEK_NONE
,
181 ARMCPUTestParams
<uint64_t>("arm8", "armv4", "none", ARM::AEK_NONE
, "4"),
182 ARMCPUTestParams
<uint64_t>("arm810", "armv4", "none", ARM::AEK_NONE
,
184 ARMCPUTestParams
<uint64_t>("strongarm", "armv4", "none", ARM::AEK_NONE
,
186 ARMCPUTestParams
<uint64_t>("strongarm110", "armv4", "none",
188 ARMCPUTestParams
<uint64_t>("strongarm1100", "armv4", "none",
190 ARMCPUTestParams
<uint64_t>("strongarm1110", "armv4", "none",
192 ARMCPUTestParams
<uint64_t>("arm7tdmi", "armv4t", "none", ARM::AEK_NONE
,
194 ARMCPUTestParams
<uint64_t>("arm7tdmi-s", "armv4t", "none",
195 ARM::AEK_NONE
, "4T"),
196 ARMCPUTestParams
<uint64_t>("arm710t", "armv4t", "none", ARM::AEK_NONE
,
198 ARMCPUTestParams
<uint64_t>("arm720t", "armv4t", "none", ARM::AEK_NONE
,
200 ARMCPUTestParams
<uint64_t>("arm9", "armv4t", "none", ARM::AEK_NONE
,
202 ARMCPUTestParams
<uint64_t>("arm9tdmi", "armv4t", "none", ARM::AEK_NONE
,
204 ARMCPUTestParams
<uint64_t>("arm920", "armv4t", "none", ARM::AEK_NONE
,
206 ARMCPUTestParams
<uint64_t>("arm920t", "armv4t", "none", ARM::AEK_NONE
,
208 ARMCPUTestParams
<uint64_t>("arm922t", "armv4t", "none", ARM::AEK_NONE
,
210 ARMCPUTestParams
<uint64_t>("arm940t", "armv4t", "none", ARM::AEK_NONE
,
212 ARMCPUTestParams
<uint64_t>("ep9312", "armv4t", "none", ARM::AEK_NONE
,
214 ARMCPUTestParams
<uint64_t>("arm10tdmi", "armv5t", "none", ARM::AEK_NONE
,
216 ARMCPUTestParams
<uint64_t>("arm1020t", "armv5t", "none", ARM::AEK_NONE
,
218 ARMCPUTestParams
<uint64_t>("arm9e", "armv5te", "none",
219 ARM::AEK_NONE
| ARM::AEK_DSP
, "5TE"),
220 ARMCPUTestParams
<uint64_t>("arm946e-s", "armv5te", "none",
221 ARM::AEK_NONE
| ARM::AEK_DSP
, "5TE"),
222 ARMCPUTestParams
<uint64_t>("arm966e-s", "armv5te", "none",
223 ARM::AEK_NONE
| ARM::AEK_DSP
, "5TE"),
224 ARMCPUTestParams
<uint64_t>("arm968e-s", "armv5te", "none",
225 ARM::AEK_NONE
| ARM::AEK_DSP
, "5TE"),
226 ARMCPUTestParams
<uint64_t>("arm10e", "armv5te", "none",
227 ARM::AEK_NONE
| ARM::AEK_DSP
, "5TE"),
228 ARMCPUTestParams
<uint64_t>("arm1020e", "armv5te", "none",
229 ARM::AEK_NONE
| ARM::AEK_DSP
, "5TE"),
230 ARMCPUTestParams
<uint64_t>("arm1022e", "armv5te", "none",
231 ARM::AEK_NONE
| ARM::AEK_DSP
, "5TE"),
232 ARMCPUTestParams
<uint64_t>("arm926ej-s", "armv5tej", "none",
233 ARM::AEK_NONE
| ARM::AEK_DSP
, "5TEJ"),
234 ARMCPUTestParams
<uint64_t>("arm1136j-s", "armv6", "none",
235 ARM::AEK_NONE
| ARM::AEK_DSP
, "6"),
236 ARMCPUTestParams
<uint64_t>("arm1136jf-s", "armv6", "vfpv2",
237 ARM::AEK_NONE
| ARM::AEK_DSP
, "6"),
238 ARMCPUTestParams
<uint64_t>("arm1176jz-s", "armv6kz", "none",
239 ARM::AEK_NONE
| ARM::AEK_SEC
| ARM::AEK_DSP
,
241 ARMCPUTestParams
<uint64_t>("mpcore", "armv6k", "vfpv2",
242 ARM::AEK_NONE
| ARM::AEK_DSP
, "6K"),
243 ARMCPUTestParams
<uint64_t>("mpcorenovfp", "armv6k", "none",
244 ARM::AEK_NONE
| ARM::AEK_DSP
, "6K"),
245 ARMCPUTestParams
<uint64_t>("arm1176jzf-s", "armv6kz", "vfpv2",
246 ARM::AEK_NONE
| ARM::AEK_SEC
| ARM::AEK_DSP
,
248 ARMCPUTestParams
<uint64_t>("arm1156t2-s", "armv6t2", "none",
249 ARM::AEK_NONE
| ARM::AEK_DSP
, "6T2"),
250 ARMCPUTestParams
<uint64_t>("arm1156t2f-s", "armv6t2", "vfpv2",
251 ARM::AEK_NONE
| ARM::AEK_DSP
, "6T2"),
252 ARMCPUTestParams
<uint64_t>("cortex-m0", "armv6-m", "none",
253 ARM::AEK_NONE
, "6-M"),
254 ARMCPUTestParams
<uint64_t>("cortex-m0plus", "armv6-m", "none",
255 ARM::AEK_NONE
, "6-M"),
256 ARMCPUTestParams
<uint64_t>("cortex-m1", "armv6-m", "none",
257 ARM::AEK_NONE
, "6-M"),
258 ARMCPUTestParams
<uint64_t>("sc000", "armv6-m", "none", ARM::AEK_NONE
,
260 ARMCPUTestParams
<uint64_t>("cortex-a5", "armv7-a", "neon-vfpv4",
261 ARM::AEK_MP
| ARM::AEK_SEC
| ARM::AEK_DSP
,
263 ARMCPUTestParams
<uint64_t>("cortex-a7", "armv7-a", "neon-vfpv4",
264 ARM::AEK_HWDIVTHUMB
| ARM::AEK_HWDIVARM
|
265 ARM::AEK_MP
| ARM::AEK_SEC
|
266 ARM::AEK_VIRT
| ARM::AEK_DSP
,
268 ARMCPUTestParams
<uint64_t>("cortex-a8", "armv7-a", "neon",
269 ARM::AEK_SEC
| ARM::AEK_DSP
, "7-A")),
270 ARMCPUTestParams
<uint64_t>::PrintToStringParamName
);
272 // gtest in llvm has a limit of 50 test cases when using ::Values so we split
273 // them into 2 blocks
274 INSTANTIATE_TEST_SUITE_P(
275 ARMCPUTestsPart2
, ARMCPUTestFixture
,
277 ARMCPUTestParams
<uint64_t>("cortex-a9", "armv7-a", "neon-fp16",
278 ARM::AEK_MP
| ARM::AEK_SEC
| ARM::AEK_DSP
,
280 ARMCPUTestParams
<uint64_t>("cortex-a12", "armv7-a", "neon-vfpv4",
281 ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
282 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
|
285 ARMCPUTestParams
<uint64_t>("cortex-a15", "armv7-a", "neon-vfpv4",
286 ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
287 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
|
290 ARMCPUTestParams
<uint64_t>("cortex-a17", "armv7-a", "neon-vfpv4",
291 ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
292 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
|
295 ARMCPUTestParams
<uint64_t>("krait", "armv7-a", "neon-vfpv4",
296 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
|
299 ARMCPUTestParams
<uint64_t>("cortex-r4", "armv7-r", "none",
300 ARM::AEK_NONE
| ARM::AEK_HWDIVTHUMB
|
303 ARMCPUTestParams
<uint64_t>("cortex-r4f", "armv7-r", "vfpv3-d16",
304 ARM::AEK_NONE
| ARM::AEK_HWDIVTHUMB
|
307 ARMCPUTestParams
<uint64_t>("cortex-r5", "armv7-r", "vfpv3-d16",
308 ARM::AEK_MP
| ARM::AEK_HWDIVARM
|
309 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
311 ARMCPUTestParams
<uint64_t>("cortex-r7", "armv7-r", "vfpv3-d16-fp16",
312 ARM::AEK_MP
| ARM::AEK_HWDIVARM
|
313 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
315 ARMCPUTestParams
<uint64_t>("cortex-r8", "armv7-r", "vfpv3-d16-fp16",
316 ARM::AEK_MP
| ARM::AEK_HWDIVARM
|
317 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
319 ARMCPUTestParams
<uint64_t>("cortex-r52", "armv8-r", "neon-fp-armv8",
320 ARM::AEK_NONE
| ARM::AEK_CRC
| ARM::AEK_MP
|
321 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
322 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
324 ARMCPUTestParams
<uint64_t>("cortex-r52plus", "armv8-r", "neon-fp-armv8",
325 ARM::AEK_NONE
| ARM::AEK_CRC
| ARM::AEK_MP
|
326 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
327 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
329 ARMCPUTestParams
<uint64_t>("sc300", "armv7-m", "none",
330 ARM::AEK_NONE
| ARM::AEK_HWDIVTHUMB
, "7-M"),
331 ARMCPUTestParams
<uint64_t>("cortex-m3", "armv7-m", "none",
332 ARM::AEK_NONE
| ARM::AEK_HWDIVTHUMB
, "7-M"),
333 ARMCPUTestParams
<uint64_t>("cortex-m4", "armv7e-m", "fpv4-sp-d16",
334 ARM::AEK_NONE
| ARM::AEK_HWDIVTHUMB
|
337 ARMCPUTestParams
<uint64_t>("cortex-m7", "armv7e-m", "fpv5-d16",
338 ARM::AEK_NONE
| ARM::AEK_HWDIVTHUMB
|
341 ARMCPUTestParams
<uint64_t>("cortex-a32", "armv8-a",
342 "crypto-neon-fp-armv8",
343 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
|
344 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
345 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
347 ARMCPUTestParams
<uint64_t>("cortex-a35", "armv8-a",
348 "crypto-neon-fp-armv8",
349 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
|
350 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
351 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
353 ARMCPUTestParams
<uint64_t>("cortex-a53", "armv8-a",
354 "crypto-neon-fp-armv8",
355 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
|
356 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
357 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
359 ARMCPUTestParams
<uint64_t>(
360 "cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",
361 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
362 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
|
363 ARM::AEK_FP16
| ARM::AEK_RAS
| ARM::AEK_DOTPROD
,
365 ARMCPUTestParams
<uint64_t>("cortex-a57", "armv8-a",
366 "crypto-neon-fp-armv8",
367 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
|
368 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
369 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
371 ARMCPUTestParams
<uint64_t>("cortex-a72", "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
,
377 ARMCPUTestParams
<uint64_t>("cortex-a73", "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
,
383 ARMCPUTestParams
<uint64_t>(
384 "cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",
385 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
386 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
|
387 ARM::AEK_FP16
| ARM::AEK_RAS
| ARM::AEK_DOTPROD
,
389 ARMCPUTestParams
<uint64_t>(
390 "cortex-a76", "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
,
395 ARMCPUTestParams
<uint64_t>(
396 "cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",
397 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
398 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
|
399 ARM::AEK_FP16
| ARM::AEK_RAS
| ARM::AEK_DOTPROD
,
401 ARMCPUTestParams
<uint64_t>(
402 "cortex-a78c", "armv8.2-a", "crypto-neon-fp-armv8",
403 ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
404 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
| ARM::AEK_CRC
|
405 ARM::AEK_RAS
| ARM::AEK_FP16
| ARM::AEK_DOTPROD
,
407 ARMCPUTestParams
<uint64_t>("cortex-a710", "armv9-a", "neon-fp-armv8",
408 ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
409 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
|
410 ARM::AEK_DSP
| ARM::AEK_CRC
|
411 ARM::AEK_RAS
| ARM::AEK_DOTPROD
|
412 ARM::AEK_FP16FML
| ARM::AEK_BF16
|
413 ARM::AEK_I8MM
| ARM::AEK_SB
,
415 ARMCPUTestParams
<uint64_t>(
416 "cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8",
417 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
418 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
|
419 ARM::AEK_FP16
| ARM::AEK_RAS
| ARM::AEK_DOTPROD
,
421 ARMCPUTestParams
<uint64_t>(
422 "cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8",
423 ARM::AEK_DOTPROD
| ARM::AEK_FP16
| ARM::AEK_SEC
| ARM::AEK_MP
|
424 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
|
425 ARM::AEK_DSP
| ARM::AEK_CRC
| ARM::AEK_RAS
,
427 ARMCPUTestParams
<uint64_t>(
428 "cortex-a78ae", "armv8.2-a", "crypto-neon-fp-armv8",
429 ARM::AEK_RAS
| ARM::AEK_DOTPROD
| ARM::AEK_SEC
| ARM::AEK_MP
|
430 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
|
431 ARM::AEK_DSP
| ARM::AEK_CRC
| ARM::AEK_RAS
,
433 ARMCPUTestParams
<uint64_t>(
434 "cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8",
435 ARM::AEK_RAS
| ARM::AEK_FP16
| ARM::AEK_DOTPROD
| ARM::AEK_SEC
|
436 ARM::AEK_MP
| ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
437 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
| ARM::AEK_CRC
,
439 ARMCPUTestParams
<uint64_t>(
440 "cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8",
441 ARM::AEK_RAS
| ARM::AEK_FP16
| ARM::AEK_DOTPROD
| ARM::AEK_SEC
|
442 ARM::AEK_MP
| ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
443 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
| ARM::AEK_CRC
,
445 ARMCPUTestParams
<uint64_t>(
446 "neoverse-n1", "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
,
451 ARMCPUTestParams
<uint64_t>(
452 "neoverse-n2", "armv9-a", "neon-fp-armv8",
453 ARM::AEK_CRC
| ARM::AEK_HWDIVTHUMB
| ARM::AEK_HWDIVARM
|
454 ARM::AEK_MP
| ARM::AEK_SEC
| ARM::AEK_VIRT
| ARM::AEK_DSP
|
455 ARM::AEK_BF16
| ARM::AEK_DOTPROD
| ARM::AEK_RAS
|
456 ARM::AEK_I8MM
| ARM::AEK_FP16FML
| ARM::AEK_SB
,
458 ARMCPUTestParams
<uint64_t>(
459 "neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8",
460 ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
461 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
| ARM::AEK_CRC
|
462 ARM::AEK_RAS
| ARM::AEK_FP16
| ARM::AEK_BF16
| ARM::AEK_DOTPROD
,
464 ARMCPUTestParams
<uint64_t>("cyclone", "armv8-a", "crypto-neon-fp-armv8",
465 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
|
466 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
467 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
469 ARMCPUTestParams
<uint64_t>("exynos-m3", "armv8-a",
470 "crypto-neon-fp-armv8",
471 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
|
472 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
473 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
475 ARMCPUTestParams
<uint64_t>(
476 "exynos-m4", "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_DOTPROD
| ARM::AEK_FP16
| ARM::AEK_RAS
,
481 ARMCPUTestParams
<uint64_t>(
482 "exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
483 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
484 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
|
485 ARM::AEK_DOTPROD
| ARM::AEK_FP16
| ARM::AEK_RAS
,
487 ARMCPUTestParams
<uint64_t>("cortex-m23", "armv8-m.base", "none",
488 ARM::AEK_NONE
| ARM::AEK_HWDIVTHUMB
,
490 ARMCPUTestParams
<uint64_t>("cortex-m33", "armv8-m.main", "fpv5-sp-d16",
491 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
493 ARMCPUTestParams
<uint64_t>("star-mc1", "armv8-m.main", "fpv5-sp-d16",
494 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
496 ARMCPUTestParams
<uint64_t>("cortex-m35p", "armv8-m.main", "fpv5-sp-d16",
497 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
499 ARMCPUTestParams
<uint64_t>(
500 "cortex-m55", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
501 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
| ARM::AEK_SIMD
| ARM::AEK_FP
|
502 ARM::AEK_RAS
| ARM::AEK_LOB
| ARM::AEK_FP16
,
504 ARMCPUTestParams
<uint64_t>(
505 "cortex-m85", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
506 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
| ARM::AEK_SIMD
| ARM::AEK_FP
|
507 ARM::AEK_RAS
| ARM::AEK_LOB
| ARM::AEK_FP16
| ARM::AEK_PACBTI
,
509 ARMCPUTestParams
<uint64_t>(
510 "cortex-m52", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
511 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
| ARM::AEK_SIMD
| ARM::AEK_FP
|
512 ARM::AEK_RAS
| ARM::AEK_LOB
| ARM::AEK_FP16
| ARM::AEK_PACBTI
,
514 ARMCPUTestParams
<uint64_t>("iwmmxt", "iwmmxt", "none", ARM::AEK_NONE
,
516 ARMCPUTestParams
<uint64_t>("xscale", "xscale", "none", ARM::AEK_NONE
,
518 ARMCPUTestParams
<uint64_t>("swift", "armv7s", "neon-vfpv4",
519 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
|
522 ARMCPUTestParams
<uint64_t>::PrintToStringParamName
);
524 static constexpr unsigned NumARMCPUArchs
= 93;
526 TEST(TargetParserTest
, testARMCPUArchList
) {
527 SmallVector
<StringRef
, NumARMCPUArchs
> List
;
528 ARM::fillValidCPUArchList(List
);
530 // No list exists for these in this test suite, so ensure all are
531 // valid, and match the expected 'magic' count.
532 EXPECT_EQ(List
.size(), NumARMCPUArchs
);
533 for (StringRef CPU
: List
) {
534 EXPECT_NE(ARM::parseCPUArch(CPU
), ARM::ArchKind::INVALID
);
538 TEST(TargetParserTest
, testInvalidARMArch
) {
539 auto InvalidArchStrings
= {"armv", "armv99", "noarm"};
540 for (const char *InvalidArch
: InvalidArchStrings
)
541 EXPECT_EQ(ARM::parseArch(InvalidArch
), ARM::ArchKind::INVALID
);
544 bool testARMArch(StringRef Arch
, StringRef DefaultCPU
, StringRef SubArch
,
546 ARM::ArchKind AK
= ARM::parseArch(Arch
);
547 bool Result
= (AK
!= ARM::ArchKind::INVALID
);
548 Result
&= ARM::getDefaultCPU(Arch
) == DefaultCPU
;
549 Result
&= ARM::getSubArch(AK
) == SubArch
;
550 Result
&= (ARM::getArchAttr(AK
) == ArchAttr
);
554 TEST(TargetParserTest
, testARMArch
) {
556 testARMArch("armv4", "strongarm", "v4", ARMBuildAttrs::CPUArch::v4
));
558 testARMArch("armv4t", "arm7tdmi", "v4t", ARMBuildAttrs::CPUArch::v4T
));
560 testARMArch("armv5t", "arm10tdmi", "v5", ARMBuildAttrs::CPUArch::v5T
));
562 testARMArch("armv5te", "arm1022e", "v5e", ARMBuildAttrs::CPUArch::v5TE
));
563 EXPECT_TRUE(testARMArch("armv5tej", "arm926ej-s", "v5e",
564 ARMBuildAttrs::CPUArch::v5TEJ
));
566 testARMArch("armv6", "arm1136jf-s", "v6", ARMBuildAttrs::CPUArch::v6
));
568 testARMArch("armv6k", "mpcore", "v6k", ARMBuildAttrs::CPUArch::v6K
));
569 EXPECT_TRUE(testARMArch("armv6t2", "arm1156t2-s", "v6t2",
570 ARMBuildAttrs::CPUArch::v6T2
));
571 EXPECT_TRUE(testARMArch("armv6kz", "arm1176jzf-s", "v6kz",
572 ARMBuildAttrs::CPUArch::v6KZ
));
574 testARMArch("armv6-m", "cortex-m0", "v6m", ARMBuildAttrs::CPUArch::v6_M
));
576 testARMArch("armv7-a", "generic", "v7", ARMBuildAttrs::CPUArch::v7
));
578 testARMArch("armv7ve", "generic", "v7ve", ARMBuildAttrs::CPUArch::v7
));
580 testARMArch("armv7-r", "cortex-r4", "v7r", ARMBuildAttrs::CPUArch::v7
));
582 testARMArch("armv7-m", "cortex-m3", "v7m", ARMBuildAttrs::CPUArch::v7
));
583 EXPECT_TRUE(testARMArch("armv7e-m", "cortex-m4", "v7em",
584 ARMBuildAttrs::CPUArch::v7E_M
));
586 testARMArch("armv8-a", "generic", "v8a", ARMBuildAttrs::CPUArch::v8_A
));
587 EXPECT_TRUE(testARMArch("armv8.1-a", "generic", "v8.1a",
588 ARMBuildAttrs::CPUArch::v8_A
));
589 EXPECT_TRUE(testARMArch("armv8.2-a", "generic", "v8.2a",
590 ARMBuildAttrs::CPUArch::v8_A
));
591 EXPECT_TRUE(testARMArch("armv8.3-a", "generic", "v8.3a",
592 ARMBuildAttrs::CPUArch::v8_A
));
593 EXPECT_TRUE(testARMArch("armv8.4-a", "generic", "v8.4a",
594 ARMBuildAttrs::CPUArch::v8_A
));
595 EXPECT_TRUE(testARMArch("armv8.5-a", "generic", "v8.5a",
596 ARMBuildAttrs::CPUArch::v8_A
));
597 EXPECT_TRUE(testARMArch("armv8.6-a", "generic", "v8.6a",
598 ARMBuildAttrs::CPUArch::v8_A
));
599 EXPECT_TRUE(testARMArch("armv8.7-a", "generic", "v8.7a",
600 ARMBuildAttrs::CPUArch::v8_A
));
601 EXPECT_TRUE(testARMArch("armv8.8-a", "generic", "v8.8a",
602 ARMBuildAttrs::CPUArch::v8_A
));
603 EXPECT_TRUE(testARMArch("armv8.9-a", "generic", "v8.9a",
604 ARMBuildAttrs::CPUArch::v8_A
));
606 testARMArch("armv9-a", "generic", "v9a", ARMBuildAttrs::CPUArch::v9_A
));
607 EXPECT_TRUE(testARMArch("armv9.1-a", "generic", "v9.1a",
608 ARMBuildAttrs::CPUArch::v9_A
));
609 EXPECT_TRUE(testARMArch("armv9.2-a", "generic", "v9.2a",
610 ARMBuildAttrs::CPUArch::v9_A
));
611 EXPECT_TRUE(testARMArch("armv9.3-a", "generic", "v9.3a",
612 ARMBuildAttrs::CPUArch::v9_A
));
613 EXPECT_TRUE(testARMArch("armv9.4-a", "generic", "v9.4a",
614 ARMBuildAttrs::CPUArch::v9_A
));
615 EXPECT_TRUE(testARMArch("armv9.5-a", "generic", "v9.5a",
616 ARMBuildAttrs::CPUArch::v9_A
));
617 EXPECT_TRUE(testARMArch("armv9.6-a", "generic", "v9.6a",
618 ARMBuildAttrs::CPUArch::v9_A
));
620 testARMArch("armv8-r", "generic", "v8r", ARMBuildAttrs::CPUArch::v8_R
));
621 EXPECT_TRUE(testARMArch("armv8-m.base", "generic", "v8m.base",
622 ARMBuildAttrs::CPUArch::v8_M_Base
));
623 EXPECT_TRUE(testARMArch("armv8-m.main", "generic", "v8m.main",
624 ARMBuildAttrs::CPUArch::v8_M_Main
));
625 EXPECT_TRUE(testARMArch("armv8.1-m.main", "generic", "v8.1m.main",
626 ARMBuildAttrs::CPUArch::v8_1_M_Main
));
628 testARMArch("iwmmxt", "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE
));
630 testARMArch("iwmmxt2", "generic", "", ARMBuildAttrs::CPUArch::v5TE
));
632 testARMArch("xscale", "xscale", "v5e", ARMBuildAttrs::CPUArch::v5TE
));
634 testARMArch("armv7s", "swift", "v7s", ARMBuildAttrs::CPUArch::v7
));
636 testARMArch("armv7k", "generic", "v7k", ARMBuildAttrs::CPUArch::v7
));
639 bool testARMExtension(StringRef CPUName
, ARM::ArchKind ArchKind
,
641 return ARM::getDefaultExtensions(CPUName
, ArchKind
) &
642 ARM::parseArchExt(ArchExt
);
645 TEST(TargetParserTest
, testARMExtension
) {
646 EXPECT_FALSE(testARMExtension("strongarm", ARM::ArchKind::INVALID
, "dsp"));
647 EXPECT_FALSE(testARMExtension("arm7tdmi", ARM::ArchKind::INVALID
, "dsp"));
648 EXPECT_FALSE(testARMExtension("arm10tdmi", ARM::ArchKind::INVALID
, "simd"));
649 EXPECT_FALSE(testARMExtension("arm1022e", ARM::ArchKind::INVALID
, "simd"));
650 EXPECT_FALSE(testARMExtension("arm926ej-s", ARM::ArchKind::INVALID
, "simd"));
652 testARMExtension("arm1136jf-s", ARM::ArchKind::INVALID
, "crypto"));
654 testARMExtension("arm1156t2-s", ARM::ArchKind::INVALID
, "crypto"));
656 testARMExtension("arm1176jzf-s", ARM::ArchKind::INVALID
, "crypto"));
657 EXPECT_FALSE(testARMExtension("cortex-m0", ARM::ArchKind::INVALID
, "crypto"));
658 EXPECT_FALSE(testARMExtension("cortex-a8", ARM::ArchKind::INVALID
, "crypto"));
659 EXPECT_FALSE(testARMExtension("cortex-r4", ARM::ArchKind::INVALID
, "crypto"));
660 EXPECT_FALSE(testARMExtension("cortex-m3", ARM::ArchKind::INVALID
, "crypto"));
661 EXPECT_FALSE(testARMExtension("cortex-a53", ARM::ArchKind::INVALID
, "ras"));
662 EXPECT_FALSE(testARMExtension("cortex-a53", ARM::ArchKind::INVALID
, "fp16"));
663 EXPECT_TRUE(testARMExtension("cortex-a55", ARM::ArchKind::INVALID
, "fp16"));
665 testARMExtension("cortex-a55", ARM::ArchKind::INVALID
, "fp16fml"));
666 EXPECT_TRUE(testARMExtension("cortex-a75", ARM::ArchKind::INVALID
, "fp16"));
668 testARMExtension("cortex-a75", ARM::ArchKind::INVALID
, "fp16fml"));
669 EXPECT_FALSE(testARMExtension("cortex-r52", ARM::ArchKind::INVALID
, "ras"));
671 testARMExtension("cortex-r52plus", ARM::ArchKind::INVALID
, "ras"));
672 EXPECT_FALSE(testARMExtension("iwmmxt", ARM::ArchKind::INVALID
, "crc"));
673 EXPECT_FALSE(testARMExtension("xscale", ARM::ArchKind::INVALID
, "crc"));
674 EXPECT_FALSE(testARMExtension("swift", ARM::ArchKind::INVALID
, "crc"));
676 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4
, "dsp"));
677 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4T
, "dsp"));
678 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5T
, "simd"));
679 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TE
, "simd"));
680 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TEJ
, "simd"));
681 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6
, "crypto"));
682 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6K
, "crypto"));
683 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6T2
, "crypto"));
684 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6KZ
, "crypto"));
685 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6M
, "crypto"));
686 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7A
, "crypto"));
687 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7R
, "crypto"));
688 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7M
, "crypto"));
689 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7EM
, "crypto"));
690 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8A
, "ras"));
691 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_1A
, "ras"));
692 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A
, "profile"));
693 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A
, "fp16"));
694 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A
, "fp16fml"));
695 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A
, "fp16"));
696 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A
, "fp16fml"));
697 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A
, "fp16"));
698 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A
, "fp16fml"));
699 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8R
, "ras"));
701 testARMExtension("generic", ARM::ArchKind::ARMV8MBaseline
, "crc"));
703 testARMExtension("generic", ARM::ArchKind::ARMV8MMainline
, "crc"));
704 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT
, "crc"));
705 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT2
, "crc"));
706 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::XSCALE
, "crc"));
707 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7S
, "crypto"));
708 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7K
, "crypto"));
711 TEST(TargetParserTest
, ARMFPUVersion
) {
712 for (ARM::FPUKind FK
= static_cast<ARM::FPUKind
>(0);
713 FK
<= ARM::FPUKind::FK_LAST
;
714 FK
= static_cast<ARM::FPUKind
>(static_cast<unsigned>(FK
) + 1))
715 if (FK
== ARM::FK_LAST
|| ARM::getFPUName(FK
) == "invalid" ||
716 ARM::getFPUName(FK
) == "none" || ARM::getFPUName(FK
) == "softvfp")
717 EXPECT_EQ(ARM::FPUVersion::NONE
, ARM::getFPUVersion(FK
));
719 EXPECT_NE(ARM::FPUVersion::NONE
, ARM::getFPUVersion(FK
));
722 TEST(TargetParserTest
, ARMFPUNeonSupportLevel
) {
723 for (ARM::FPUKind FK
= static_cast<ARM::FPUKind
>(0);
724 FK
<= ARM::FPUKind::FK_LAST
;
725 FK
= static_cast<ARM::FPUKind
>(static_cast<unsigned>(FK
) + 1))
726 if (FK
== ARM::FK_LAST
||
727 ARM::getFPUName(FK
).find("neon") == std::string::npos
)
728 EXPECT_EQ(ARM::NeonSupportLevel::None
, ARM::getFPUNeonSupportLevel(FK
));
730 EXPECT_NE(ARM::NeonSupportLevel::None
, ARM::getFPUNeonSupportLevel(FK
));
733 TEST(TargetParserTest
, ARMFPURestriction
) {
734 for (ARM::FPUKind FK
= static_cast<ARM::FPUKind
>(0);
735 FK
<= ARM::FPUKind::FK_LAST
;
736 FK
= static_cast<ARM::FPUKind
>(static_cast<unsigned>(FK
) + 1)) {
737 if (FK
== ARM::FK_LAST
||
738 (ARM::getFPUName(FK
).find("d16") == std::string::npos
&&
739 ARM::getFPUName(FK
).find("vfpv3xd") == std::string::npos
))
740 EXPECT_EQ(ARM::FPURestriction::None
, ARM::getFPURestriction(FK
));
742 EXPECT_NE(ARM::FPURestriction::None
, ARM::getFPURestriction(FK
));
746 TEST(TargetParserTest
, ARMExtensionFeatures
) {
747 std::map
<uint64_t, std::vector
<StringRef
>> Extensions
;
749 for (auto &Ext
: ARM::ARCHExtNames
) {
750 if (!Ext
.Feature
.empty() && !Ext
.NegFeature
.empty())
751 Extensions
[Ext
.ID
] = {Ext
.Feature
, Ext
.NegFeature
};
754 Extensions
[ARM::AEK_HWDIVARM
] = {"+hwdiv-arm", "-hwdiv-arm"};
755 Extensions
[ARM::AEK_HWDIVTHUMB
] = {"+hwdiv", "-hwdiv"};
757 std::vector
<StringRef
> Features
;
759 EXPECT_FALSE(ARM::getExtensionFeatures(ARM::AEK_INVALID
, Features
));
761 for (auto &E
: Extensions
) {
764 ARM::getExtensionFeatures(E
.first
, Features
);
765 EXPECT_TRUE(llvm::is_contained(Features
, E
.second
.at(0)));
766 EXPECT_EQ(Extensions
.size(), Features
.size());
770 ARM::getExtensionFeatures(~E
.first
, Features
);
771 EXPECT_TRUE(llvm::is_contained(Features
, E
.second
.at(1)));
772 EXPECT_EQ(Extensions
.size(), Features
.size());
776 TEST(TargetParserTest
, ARMFPUFeatures
) {
777 std::vector
<StringRef
> Features
;
778 for (ARM::FPUKind FK
= static_cast<ARM::FPUKind
>(0);
779 FK
<= ARM::FPUKind::FK_LAST
;
780 FK
= static_cast<ARM::FPUKind
>(static_cast<unsigned>(FK
) + 1)) {
781 if (FK
== ARM::FK_INVALID
|| FK
>= ARM::FK_LAST
)
782 EXPECT_FALSE(ARM::getFPUFeatures(FK
, Features
));
784 EXPECT_TRUE(ARM::getFPUFeatures(FK
, Features
));
788 TEST(TargetParserTest
, ARMArchExtFeature
) {
789 const char *ArchExt
[][4] = {{"crc", "nocrc", "+crc", "-crc"},
790 {"crypto", "nocrypto", "+crypto", "-crypto"},
791 {"dsp", "nodsp", "+dsp", "-dsp"},
792 {"fp", "nofp", nullptr, nullptr},
793 {"idiv", "noidiv", nullptr, nullptr},
794 {"mp", "nomp", nullptr, nullptr},
795 {"simd", "nosimd", nullptr, nullptr},
796 {"sec", "nosec", nullptr, nullptr},
797 {"virt", "novirt", nullptr, nullptr},
798 {"fp16", "nofp16", "+fullfp16", "-fullfp16"},
799 {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"},
800 {"ras", "noras", "+ras", "-ras"},
801 {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
802 {"os", "noos", nullptr, nullptr},
803 {"iwmmxt", "noiwmmxt", nullptr, nullptr},
804 {"iwmmxt2", "noiwmmxt2", nullptr, nullptr},
805 {"maverick", "maverick", nullptr, nullptr},
806 {"xscale", "noxscale", nullptr, nullptr},
807 {"sb", "nosb", "+sb", "-sb"},
808 {"i8mm", "noi8mm", "+i8mm", "-i8mm"},
809 {"mve", "nomve", "+mve", "-mve"},
810 {"mve.fp", "nomve.fp", "+mve.fp", "-mve.fp"}};
812 for (unsigned i
= 0; i
< std::size(ArchExt
); i
++) {
813 EXPECT_EQ(StringRef(ArchExt
[i
][2]), ARM::getArchExtFeature(ArchExt
[i
][0]));
814 EXPECT_EQ(StringRef(ArchExt
[i
][3]), ARM::getArchExtFeature(ArchExt
[i
][1]));
819 testArchExtDependency(const char *ArchExt
,
820 const std::initializer_list
<const char *> &Expected
) {
821 std::vector
<StringRef
> Features
;
822 ARM::FPUKind FPUKind
;
824 if (!ARM::appendArchExtFeatures("", ARM::ArchKind::ARMV8_1MMainline
, ArchExt
,
828 return llvm::all_of(Expected
, [&](StringRef Ext
) {
829 return llvm::is_contained(Features
, Ext
);
833 TEST(TargetParserTest
, ARMArchExtDependencies
) {
834 EXPECT_TRUE(testArchExtDependency("mve", {"+mve", "+dsp"}));
835 EXPECT_TRUE(testArchExtDependency("mve.fp", {"+mve.fp", "+mve", "+dsp"}));
836 EXPECT_TRUE(testArchExtDependency("nodsp", {"-dsp", "-mve", "-mve.fp"}));
837 EXPECT_TRUE(testArchExtDependency("nomve", {"-mve", "-mve.fp"}));
840 TEST(TargetParserTest
, ARMparseHWDiv
) {
841 const char *hwdiv
[] = {"thumb", "arm", "arm,thumb", "thumb,arm"};
843 for (unsigned i
= 0; i
< std::size(hwdiv
); i
++)
844 EXPECT_NE(ARM::AEK_INVALID
, ARM::parseHWDiv((StringRef
)hwdiv
[i
]));
847 TEST(TargetParserTest
, ARMparseArchEndianAndISA
) {
848 const char *Arch
[] = {
849 "v2", "v2a", "v3", "v3m", "v4", "v4t",
850 "v5", "v5t", "v5e", "v5te", "v5tej", "v6",
851 "v6j", "v6k", "v6hl", "v6t2", "v6kz", "v6z",
852 "v6zk", "v6-m", "v6m", "v6sm", "v6s-m", "v7-a",
853 "v7", "v7a", "v7ve", "v7hl", "v7l", "v7-r",
854 "v7r", "v7-m", "v7m", "v7k", "v7s", "v7e-m",
855 "v7em", "v8-a", "v8", "v8a", "v8l", "v8.1-a",
856 "v8.1a", "v8.2-a", "v8.2a", "v8.3-a", "v8.3a", "v8.4-a",
857 "v8.4a", "v8.5-a", "v8.5a", "v8.6-a", "v8.6a", "v8.7-a",
858 "v8.7a", "v8.8-a", "v8.8a", "v8-r", "v8m.base", "v8m.main",
861 for (unsigned i
= 0; i
< std::size(Arch
); i
++) {
862 std::string arm_1
= "armeb" + (std::string
)(Arch
[i
]);
863 std::string arm_2
= "arm" + (std::string
)(Arch
[i
]) + "eb";
864 std::string arm_3
= "arm" + (std::string
)(Arch
[i
]);
865 std::string thumb_1
= "thumbeb" + (std::string
)(Arch
[i
]);
866 std::string thumb_2
= "thumb" + (std::string
)(Arch
[i
]) + "eb";
867 std::string thumb_3
= "thumb" + (std::string
)(Arch
[i
]);
869 EXPECT_EQ(ARM::EndianKind::BIG
, ARM::parseArchEndian(arm_1
));
870 EXPECT_EQ(ARM::EndianKind::BIG
, ARM::parseArchEndian(arm_2
));
871 EXPECT_EQ(ARM::EndianKind::LITTLE
, ARM::parseArchEndian(arm_3
));
873 EXPECT_EQ(ARM::ISAKind::ARM
, ARM::parseArchISA(arm_1
));
874 EXPECT_EQ(ARM::ISAKind::ARM
, ARM::parseArchISA(arm_2
));
875 EXPECT_EQ(ARM::ISAKind::ARM
, ARM::parseArchISA(arm_3
));
877 EXPECT_EQ(ARM::EndianKind::BIG
, ARM::parseArchEndian(thumb_1
));
878 EXPECT_EQ(ARM::EndianKind::BIG
, ARM::parseArchEndian(thumb_2
));
879 EXPECT_EQ(ARM::EndianKind::LITTLE
, ARM::parseArchEndian(thumb_3
));
881 EXPECT_EQ(ARM::ISAKind::THUMB
, ARM::parseArchISA(thumb_1
));
882 EXPECT_EQ(ARM::ISAKind::THUMB
, ARM::parseArchISA(thumb_2
));
883 EXPECT_EQ(ARM::ISAKind::THUMB
, ARM::parseArchISA(thumb_3
));
887 EXPECT_EQ(ARM::EndianKind::LITTLE
, ARM::parseArchEndian("aarch64"));
888 EXPECT_EQ(ARM::EndianKind::LITTLE
, ARM::parseArchEndian("arm64_32"));
889 EXPECT_EQ(ARM::EndianKind::BIG
, ARM::parseArchEndian("aarch64_be"));
891 EXPECT_EQ(ARM::ISAKind::AARCH64
, ARM::parseArchISA("aarch64"));
892 EXPECT_EQ(ARM::ISAKind::AARCH64
, ARM::parseArchISA("aarch64_be"));
893 EXPECT_EQ(ARM::ISAKind::AARCH64
, ARM::parseArchISA("arm64"));
894 EXPECT_EQ(ARM::ISAKind::AARCH64
, ARM::parseArchISA("arm64_be"));
895 EXPECT_EQ(ARM::ISAKind::AARCH64
, ARM::parseArchISA("arm64_32"));
896 EXPECT_EQ(ARM::ISAKind::AARCH64
, ARM::parseArchISA("aarch64_32"));
899 TEST(TargetParserTest
, ARMparseArchProfile
) {
900 for (unsigned i
= 0; i
< std::size(ARMArch
); i
++) {
901 switch (ARM::parseArch(ARMArch
[i
])) {
902 case ARM::ArchKind::ARMV6M
:
903 case ARM::ArchKind::ARMV7M
:
904 case ARM::ArchKind::ARMV7EM
:
905 case ARM::ArchKind::ARMV8MMainline
:
906 case ARM::ArchKind::ARMV8MBaseline
:
907 case ARM::ArchKind::ARMV8_1MMainline
:
908 EXPECT_EQ(ARM::ProfileKind::M
, ARM::parseArchProfile(ARMArch
[i
]));
910 case ARM::ArchKind::ARMV7R
:
911 case ARM::ArchKind::ARMV8R
:
912 EXPECT_EQ(ARM::ProfileKind::R
, ARM::parseArchProfile(ARMArch
[i
]));
914 case ARM::ArchKind::ARMV7A
:
915 case ARM::ArchKind::ARMV7VE
:
916 case ARM::ArchKind::ARMV7K
:
917 case ARM::ArchKind::ARMV8A
:
918 case ARM::ArchKind::ARMV8_1A
:
919 case ARM::ArchKind::ARMV8_2A
:
920 case ARM::ArchKind::ARMV8_3A
:
921 case ARM::ArchKind::ARMV8_4A
:
922 case ARM::ArchKind::ARMV8_5A
:
923 case ARM::ArchKind::ARMV8_6A
:
924 case ARM::ArchKind::ARMV8_7A
:
925 case ARM::ArchKind::ARMV8_8A
:
926 case ARM::ArchKind::ARMV8_9A
:
927 case ARM::ArchKind::ARMV9A
:
928 case ARM::ArchKind::ARMV9_1A
:
929 case ARM::ArchKind::ARMV9_2A
:
930 case ARM::ArchKind::ARMV9_3A
:
931 case ARM::ArchKind::ARMV9_4A
:
932 case ARM::ArchKind::ARMV9_5A
:
933 case ARM::ArchKind::ARMV9_6A
:
934 EXPECT_EQ(ARM::ProfileKind::A
, ARM::parseArchProfile(ARMArch
[i
]));
937 EXPECT_EQ(ARM::ProfileKind::INVALID
, ARM::parseArchProfile(ARMArch
[i
]));
943 TEST(TargetParserTest
, ARMparseArchVersion
) {
944 for (unsigned i
= 0; i
< std::size(ARMArch
); i
++)
945 if (((std::string
)ARMArch
[i
]).substr(0, 4) == "armv")
946 EXPECT_EQ((ARMArch
[i
][4] - 48u), ARM::parseArchVersion(ARMArch
[i
]));
948 EXPECT_EQ(5u, ARM::parseArchVersion(ARMArch
[i
]));
951 TEST(TargetParserTest
, getARMCPUForArch
) {
952 // Platform specific defaults.
954 llvm::Triple
Triple("arm--nacl");
955 EXPECT_EQ("cortex-a8", ARM::getARMCPUForArch(Triple
));
958 llvm::Triple
Triple("arm--openbsd");
959 EXPECT_EQ("cortex-a8", ARM::getARMCPUForArch(Triple
));
962 llvm::Triple
Triple("armv6-unknown-freebsd");
963 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple
));
966 llvm::Triple
Triple("thumbv6-unknown-freebsd");
967 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple
));
970 llvm::Triple
Triple("armebv6-unknown-freebsd");
971 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple
));
974 llvm::Triple
Triple("arm--win32");
975 EXPECT_EQ("cortex-a9", ARM::getARMCPUForArch(Triple
));
976 EXPECT_EQ("generic", ARM::getARMCPUForArch(Triple
, "armv8-a"));
978 // Some alternative architectures
980 llvm::Triple
Triple("armv7k-apple-ios9");
981 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple
));
984 llvm::Triple
Triple("armv7k-apple-watchos3");
985 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple
));
988 llvm::Triple
Triple("armv7k-apple-tvos9");
989 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple
));
991 // armeb is permitted, but armebeb is not
993 llvm::Triple
Triple("armeb-none-eabi");
994 EXPECT_EQ("arm7tdmi", ARM::getARMCPUForArch(Triple
));
997 llvm::Triple
Triple("armebeb-none-eabi");
998 EXPECT_EQ("", ARM::getARMCPUForArch(Triple
));
1001 llvm::Triple
Triple("armebv6eb-none-eabi");
1002 EXPECT_EQ("", ARM::getARMCPUForArch(Triple
));
1004 // xscaleeb is permitted, but armebxscale is not
1006 llvm::Triple
Triple("xscaleeb-none-eabi");
1007 EXPECT_EQ("xscale", ARM::getARMCPUForArch(Triple
));
1010 llvm::Triple
Triple("armebxscale-none-eabi");
1011 EXPECT_EQ("", ARM::getARMCPUForArch(Triple
));
1015 TEST(TargetParserTest
, ARMPrintSupportedExtensions
) {
1016 std::string expected
=
1017 "All available -march extensions for ARM\n\n"
1018 " Name Description\n"
1019 " crc This is a long dummy description\n"
1023 StringMap
<StringRef
> DummyMap
;
1024 DummyMap
["crc"] = "This is a long dummy description";
1027 testing::internal::CaptureStdout();
1028 ARM::PrintSupportedExtensions(DummyMap
);
1030 std::string captured
= testing::internal::GetCapturedStdout();
1032 // Check that the start of the output is as expected.
1033 EXPECT_EQ(0ULL, captured
.find(expected
));
1035 // Should not include "none" or "invalid".
1036 EXPECT_EQ(std::string::npos
, captured
.find("none"));
1037 EXPECT_EQ(std::string::npos
, captured
.find("invalid"));
1038 // Should not include anything that lacks a feature name. Checking a few here
1039 // but not all as if one is hidden correctly the rest should be.
1040 EXPECT_EQ(std::string::npos
, captured
.find("simd"));
1041 EXPECT_EQ(std::string::npos
, captured
.find("maverick"));
1042 EXPECT_EQ(std::string::npos
, captured
.find("xscale"));
1045 struct AArch64CPUTestParams
1046 : public ARMCPUTestParams
<AArch64::ExtensionBitset
> {
1047 AArch64CPUTestParams(StringRef CPUName
, StringRef ExpectedArch
)
1048 : ARMCPUTestParams
<AArch64::ExtensionBitset
>(CPUName
, ExpectedArch
,
1051 /// Print a gtest-compatible facsimile of the CPUName, to make the test's name
1054 /// https://github.com/google/googletest/blob/main/docs/advanced.md#specifying-names-for-value-parameterized-test-parameters
1055 static std::string
PrintToStringParamName(
1056 const testing::TestParamInfo
<AArch64CPUTestParams
> &Info
) {
1057 std::string Name
= Info
.param
.CPUName
.str();
1058 for (char &C
: Name
)
1059 if (!std::isalnum(C
))
1065 class AArch64CPUTestFixture
1066 : public ::testing::TestWithParam
<AArch64CPUTestParams
> {};
1068 TEST_P(AArch64CPUTestFixture
, testAArch64CPU
) {
1069 auto params
= GetParam();
1071 const std::optional
<AArch64::CpuInfo
> Cpu
= AArch64::parseCpu(params
.CPUName
);
1073 EXPECT_EQ(params
.ExpectedArch
, Cpu
->Arch
.Name
);
1076 INSTANTIATE_TEST_SUITE_P(
1077 AArch64CPUTests
, AArch64CPUTestFixture
,
1078 ::testing::Values(AArch64CPUTestParams("cortex-a34", "armv8-a"),
1079 AArch64CPUTestParams("cortex-a35", "armv8-a"),
1080 AArch64CPUTestParams("cortex-a53", "armv8-a"),
1081 AArch64CPUTestParams("cortex-a55", "armv8.2-a"),
1082 AArch64CPUTestParams("cortex-a510", "armv9-a"),
1083 AArch64CPUTestParams("cortex-a520", "armv9.2-a"),
1084 AArch64CPUTestParams("cortex-a520ae", "armv9.2-a"),
1085 AArch64CPUTestParams("cortex-a57", "armv8-a"),
1086 AArch64CPUTestParams("cortex-a65", "armv8.2-a"),
1087 AArch64CPUTestParams("cortex-a65ae", "armv8.2-a"),
1088 AArch64CPUTestParams("cortex-a72", "armv8-a"),
1089 AArch64CPUTestParams("cortex-a73", "armv8-a"),
1090 AArch64CPUTestParams("cortex-a75", "armv8.2-a"),
1091 AArch64CPUTestParams("cortex-a76", "armv8.2-a"),
1092 AArch64CPUTestParams("cortex-a76ae", "armv8.2-a"),
1093 AArch64CPUTestParams("cortex-a77", "armv8.2-a"),
1094 AArch64CPUTestParams("cortex-a78", "armv8.2-a"),
1095 AArch64CPUTestParams("cortex-a78ae", "armv8.2-a"),
1096 AArch64CPUTestParams("cortex-a78c", "armv8.2-a"),
1097 AArch64CPUTestParams("cortex-a710", "armv9-a"),
1098 AArch64CPUTestParams("cortex-a715", "armv9-a"),
1099 AArch64CPUTestParams("cortex-a720", "armv9.2-a"),
1100 AArch64CPUTestParams("cortex-a720ae", "armv9.2-a"),
1101 AArch64CPUTestParams("cortex-a725", "armv9.2-a"),
1102 AArch64CPUTestParams("neoverse-v1", "armv8.4-a"),
1103 AArch64CPUTestParams("neoverse-v2", "armv9-a"),
1104 AArch64CPUTestParams("neoverse-v3", "armv9.2-a"),
1105 AArch64CPUTestParams("neoverse-v3ae", "armv9.2-a"),
1106 AArch64CPUTestParams("cortex-r82", "armv8-r"),
1107 AArch64CPUTestParams("cortex-r82ae", "armv8-r"),
1108 AArch64CPUTestParams("cortex-x1", "armv8.2-a"),
1109 AArch64CPUTestParams("cortex-x1c", "armv8.2-a"),
1110 AArch64CPUTestParams("cortex-x2", "armv9-a"),
1111 AArch64CPUTestParams("cortex-x3", "armv9-a"),
1112 AArch64CPUTestParams("cortex-x4", "armv9.2-a"),
1113 AArch64CPUTestParams("cortex-x925", "armv9.2-a"),
1114 AArch64CPUTestParams("cyclone", "armv8-a"),
1115 AArch64CPUTestParams("apple-a7", "armv8-a"),
1116 AArch64CPUTestParams("apple-a8", "armv8-a"),
1117 AArch64CPUTestParams("apple-a9", "armv8-a"),
1118 AArch64CPUTestParams("apple-a10", "armv8-a"),
1119 AArch64CPUTestParams("apple-a11", "armv8.2-a"),
1120 AArch64CPUTestParams("apple-a12", "armv8.3-a"),
1121 AArch64CPUTestParams("apple-s4", "armv8.3-a"),
1122 AArch64CPUTestParams("apple-s5", "armv8.3-a"),
1123 AArch64CPUTestParams("apple-a13", "armv8.4-a"),
1124 AArch64CPUTestParams("apple-a14", "armv8.4-a"),
1125 AArch64CPUTestParams("apple-m1", "armv8.4-a"),
1126 AArch64CPUTestParams("apple-a15", "armv8.6-a"),
1127 AArch64CPUTestParams("apple-m2", "armv8.6-a"),
1128 AArch64CPUTestParams("apple-a16", "armv8.6-a"),
1129 AArch64CPUTestParams("apple-m3", "armv8.6-a"),
1130 AArch64CPUTestParams("apple-a17", "armv8.6-a"),
1131 AArch64CPUTestParams("apple-m4", "armv8.7-a"),
1132 AArch64CPUTestParams("exynos-m3", "armv8-a"),
1133 AArch64CPUTestParams("exynos-m4", "armv8.2-a"),
1134 AArch64CPUTestParams("exynos-m5", "armv8.2-a"),
1135 AArch64CPUTestParams("falkor", "armv8-a"),
1136 AArch64CPUTestParams("kryo", "armv8-a"),
1137 AArch64CPUTestParams("neoverse-e1", "armv8.2-a"),
1138 AArch64CPUTestParams("neoverse-n1", "armv8.2-a"),
1139 AArch64CPUTestParams("neoverse-n2", "armv9-a"),
1140 AArch64CPUTestParams("neoverse-n3", "armv9.2-a"),
1141 AArch64CPUTestParams("ampere1", "armv8.6-a"),
1142 AArch64CPUTestParams("ampere1a", "armv8.6-a"),
1143 AArch64CPUTestParams("ampere1b", "armv8.7-a"),
1144 AArch64CPUTestParams("neoverse-512tvb", "armv8.4-a"),
1145 AArch64CPUTestParams("thunderx2t99", "armv8.1-a"),
1146 AArch64CPUTestParams("thunderx3t110", "armv8.3-a"),
1147 AArch64CPUTestParams("thunderx", "armv8-a"),
1148 AArch64CPUTestParams("thunderxt81", "armv8-a"),
1149 AArch64CPUTestParams("thunderxt83", "armv8-a"),
1150 AArch64CPUTestParams("thunderxt88", "armv8-a"),
1151 AArch64CPUTestParams("tsv110", "armv8.2-a"),
1152 AArch64CPUTestParams("a64fx", "armv8.2-a"),
1153 AArch64CPUTestParams("carmel", "armv8.2-a"),
1154 AArch64CPUTestParams("saphira", "armv8.4-a"),
1155 AArch64CPUTestParams("oryon-1", "armv8.6-a")),
1156 AArch64CPUTestParams::PrintToStringParamName
);
1158 // Note: number of CPUs includes aliases.
1159 static constexpr unsigned NumAArch64CPUArchs
= 81;
1161 TEST(TargetParserTest
, testAArch64CPUArchList
) {
1162 SmallVector
<StringRef
, NumAArch64CPUArchs
> List
;
1163 AArch64::fillValidCPUArchList(List
);
1165 // No list exists for these in this test suite, so ensure all are
1166 // valid, and match the expected 'magic' count.
1167 EXPECT_EQ(List
.size(), NumAArch64CPUArchs
);
1168 for (StringRef CPU
: List
) {
1169 EXPECT_TRUE(AArch64::parseCpu(CPU
));
1173 bool testAArch64Arch(StringRef Arch
) {
1174 const AArch64::ArchInfo
*AI
= AArch64::parseArch(Arch
);
1175 return AI
!= nullptr;
1178 TEST(TargetParserTest
, testAArch64Arch
) {
1179 EXPECT_TRUE(testAArch64Arch("armv8-a"));
1180 EXPECT_TRUE(testAArch64Arch("armv8.1-a"));
1181 EXPECT_TRUE(testAArch64Arch("armv8.2-a"));
1182 EXPECT_TRUE(testAArch64Arch("armv8.3-a"));
1183 EXPECT_TRUE(testAArch64Arch("armv8.4-a"));
1184 EXPECT_TRUE(testAArch64Arch("armv8.5-a"));
1185 EXPECT_TRUE(testAArch64Arch("armv8.6-a"));
1186 EXPECT_TRUE(testAArch64Arch("armv8.7-a"));
1187 EXPECT_TRUE(testAArch64Arch("armv8.8-a"));
1188 EXPECT_TRUE(testAArch64Arch("armv8.9-a"));
1189 EXPECT_TRUE(testAArch64Arch("armv9-a"));
1190 EXPECT_TRUE(testAArch64Arch("armv9.1-a"));
1191 EXPECT_TRUE(testAArch64Arch("armv9.2-a"));
1192 EXPECT_TRUE(testAArch64Arch("armv9.3-a"));
1193 EXPECT_TRUE(testAArch64Arch("armv9.4-a"));
1194 EXPECT_TRUE(testAArch64Arch("armv9.5-a"));
1195 EXPECT_TRUE(testAArch64Arch("armv9.6-a"));
1198 bool testAArch64Extension(StringRef CPUName
, StringRef ArchExt
) {
1199 std::optional
<AArch64::ExtensionInfo
> Extension
=
1200 AArch64::parseArchExtension(ArchExt
);
1203 std::optional
<AArch64::CpuInfo
> CpuInfo
= AArch64::parseCpu(CPUName
);
1204 return CpuInfo
->getImpliedExtensions().test(Extension
->ID
);
1207 bool testAArch64Extension(const AArch64::ArchInfo
&AI
, StringRef ArchExt
) {
1208 std::optional
<AArch64::ExtensionInfo
> Extension
=
1209 AArch64::parseArchExtension(ArchExt
);
1212 return AI
.DefaultExts
.test(Extension
->ID
);
1215 TEST(TargetParserTest
, testAArch64Extension
) {
1216 EXPECT_FALSE(testAArch64Extension("cortex-a34", "ras"));
1217 EXPECT_FALSE(testAArch64Extension("cortex-a35", "ras"));
1218 EXPECT_FALSE(testAArch64Extension("cortex-a53", "ras"));
1219 EXPECT_TRUE(testAArch64Extension("cortex-a55", "ras"));
1220 EXPECT_TRUE(testAArch64Extension("cortex-a55", "fp16"));
1221 EXPECT_FALSE(testAArch64Extension("cortex-a55", "fp16fml"));
1222 EXPECT_TRUE(testAArch64Extension("cortex-a55", "dotprod"));
1223 EXPECT_FALSE(testAArch64Extension("cortex-a57", "ras"));
1224 EXPECT_FALSE(testAArch64Extension("cortex-a72", "ras"));
1225 EXPECT_FALSE(testAArch64Extension("cortex-a73", "ras"));
1226 EXPECT_TRUE(testAArch64Extension("cortex-a75", "ras"));
1227 EXPECT_TRUE(testAArch64Extension("cortex-a75", "fp16"));
1228 EXPECT_FALSE(testAArch64Extension("cortex-a75", "fp16fml"));
1229 EXPECT_TRUE(testAArch64Extension("cortex-a75", "dotprod"));
1230 EXPECT_TRUE(testAArch64Extension("cortex-r82", "ras"));
1231 EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16"));
1232 EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16fml"));
1233 EXPECT_TRUE(testAArch64Extension("cortex-r82", "dotprod"));
1234 EXPECT_TRUE(testAArch64Extension("cortex-r82", "lse"));
1235 EXPECT_FALSE(testAArch64Extension("cyclone", "ras"));
1236 EXPECT_FALSE(testAArch64Extension("exynos-m3", "ras"));
1237 EXPECT_TRUE(testAArch64Extension("exynos-m4", "dotprod"));
1238 EXPECT_TRUE(testAArch64Extension("exynos-m4", "fp16"));
1239 EXPECT_TRUE(testAArch64Extension("exynos-m4", "lse"));
1240 EXPECT_TRUE(testAArch64Extension("exynos-m4", "ras"));
1241 EXPECT_TRUE(testAArch64Extension("exynos-m4", "rdm"));
1242 EXPECT_TRUE(testAArch64Extension("exynos-m5", "dotprod"));
1243 EXPECT_TRUE(testAArch64Extension("exynos-m5", "fp16"));
1244 EXPECT_TRUE(testAArch64Extension("exynos-m5", "lse"));
1245 EXPECT_TRUE(testAArch64Extension("exynos-m5", "ras"));
1246 EXPECT_TRUE(testAArch64Extension("exynos-m5", "rdm"));
1247 EXPECT_TRUE(testAArch64Extension("falkor", "rdm"));
1248 EXPECT_FALSE(testAArch64Extension("kryo", "ras"));
1249 EXPECT_TRUE(testAArch64Extension("saphira", "crc"));
1250 EXPECT_TRUE(testAArch64Extension("saphira", "lse"));
1251 EXPECT_TRUE(testAArch64Extension("saphira", "rdm"));
1252 EXPECT_TRUE(testAArch64Extension("saphira", "ras"));
1253 EXPECT_TRUE(testAArch64Extension("saphira", "rcpc"));
1254 EXPECT_TRUE(testAArch64Extension("saphira", "profile"));
1255 EXPECT_FALSE(testAArch64Extension("saphira", "fp16"));
1256 EXPECT_FALSE(testAArch64Extension("thunderx2t99", "ras"));
1257 EXPECT_FALSE(testAArch64Extension("thunderx", "lse"));
1258 EXPECT_FALSE(testAArch64Extension("thunderxt81", "lse"));
1259 EXPECT_FALSE(testAArch64Extension("thunderxt83", "lse"));
1260 EXPECT_FALSE(testAArch64Extension("thunderxt88", "lse"));
1261 EXPECT_TRUE(testAArch64Extension("tsv110", "aes"));
1262 EXPECT_TRUE(testAArch64Extension("tsv110", "sha2"));
1263 EXPECT_FALSE(testAArch64Extension("tsv110", "sha3"));
1264 EXPECT_FALSE(testAArch64Extension("tsv110", "sm4"));
1265 EXPECT_TRUE(testAArch64Extension("tsv110", "ras"));
1266 EXPECT_TRUE(testAArch64Extension("tsv110", "profile"));
1267 EXPECT_TRUE(testAArch64Extension("tsv110", "fp16"));
1268 EXPECT_TRUE(testAArch64Extension("tsv110", "fp16fml"));
1269 EXPECT_TRUE(testAArch64Extension("tsv110", "dotprod"));
1270 EXPECT_TRUE(testAArch64Extension("tsv110", "jscvt"));
1271 EXPECT_TRUE(testAArch64Extension("tsv110", "fcma"));
1272 EXPECT_TRUE(testAArch64Extension("a64fx", "fp16"));
1273 EXPECT_TRUE(testAArch64Extension("a64fx", "sve"));
1274 EXPECT_FALSE(testAArch64Extension("a64fx", "sve2"));
1275 EXPECT_TRUE(testAArch64Extension("carmel", "aes"));
1276 EXPECT_TRUE(testAArch64Extension("carmel", "sha2"));
1277 EXPECT_TRUE(testAArch64Extension("carmel", "fp16"));
1279 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8A
, "ras"));
1280 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_1A
, "ras"));
1281 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A
, "profile"));
1282 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A
, "fp16"));
1283 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A
, "fp16fml"));
1284 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A
, "fp16"));
1285 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A
, "fp16fml"));
1286 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A
, "fp16"));
1287 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A
, "fp16fml"));
1290 TEST(TargetParserTest
, AArch64ExtensionFeatures
) {
1291 std::vector
<uint64_t> Extensions
= {
1292 AArch64::AEK_CRC
, AArch64::AEK_LSE
,
1293 AArch64::AEK_RDM
, AArch64::AEK_CRYPTO
,
1294 AArch64::AEK_SM4
, AArch64::AEK_SHA3
,
1295 AArch64::AEK_SHA2
, AArch64::AEK_AES
,
1296 AArch64::AEK_DOTPROD
, AArch64::AEK_FP
,
1297 AArch64::AEK_SIMD
, AArch64::AEK_FP16
,
1298 AArch64::AEK_FP16FML
, AArch64::AEK_PROFILE
,
1299 AArch64::AEK_RAS
, AArch64::AEK_SVE
,
1300 AArch64::AEK_SVE2
, AArch64::AEK_SVE2AES
,
1301 AArch64::AEK_SVE2SM4
, AArch64::AEK_SVE2SHA3
,
1302 AArch64::AEK_SVE2BITPERM
, AArch64::AEK_RCPC
,
1303 AArch64::AEK_RAND
, AArch64::AEK_MTE
,
1304 AArch64::AEK_SSBS
, AArch64::AEK_SB
,
1305 AArch64::AEK_PREDRES
, AArch64::AEK_BF16
,
1306 AArch64::AEK_I8MM
, AArch64::AEK_F32MM
,
1307 AArch64::AEK_F64MM
, AArch64::AEK_TME
,
1308 AArch64::AEK_LS64
, AArch64::AEK_BRBE
,
1309 AArch64::AEK_PAUTH
, AArch64::AEK_FLAGM
,
1310 AArch64::AEK_SME
, AArch64::AEK_SMEF64F64
,
1311 AArch64::AEK_SMEI16I64
, AArch64::AEK_SME2
,
1312 AArch64::AEK_HBC
, AArch64::AEK_MOPS
,
1313 AArch64::AEK_PERFMON
, AArch64::AEK_SVE2P1
,
1314 AArch64::AEK_SME2P1
, AArch64::AEK_SMEB16B16
,
1315 AArch64::AEK_SMEF16F16
, AArch64::AEK_CSSC
,
1316 AArch64::AEK_RCPC3
, AArch64::AEK_THE
,
1317 AArch64::AEK_D128
, AArch64::AEK_LSE128
,
1318 AArch64::AEK_SPECRES2
, AArch64::AEK_RASV2
,
1319 AArch64::AEK_ITE
, AArch64::AEK_GCS
,
1320 AArch64::AEK_FAMINMAX
, AArch64::AEK_FP8FMA
,
1321 AArch64::AEK_SSVE_FP8FMA
, AArch64::AEK_FP8DOT2
,
1322 AArch64::AEK_SSVE_FP8DOT2
, AArch64::AEK_FP8DOT4
,
1323 AArch64::AEK_SSVE_FP8DOT4
, AArch64::AEK_LUT
,
1324 AArch64::AEK_SME_LUTV2
, AArch64::AEK_SMEF8F16
,
1325 AArch64::AEK_SMEF8F32
, AArch64::AEK_SMEFA64
,
1326 AArch64::AEK_CPA
, AArch64::AEK_PAUTHLR
,
1327 AArch64::AEK_TLBIW
, AArch64::AEK_JSCVT
,
1328 AArch64::AEK_FCMA
, AArch64::AEK_FP8
,
1329 AArch64::AEK_SVEB16B16
, AArch64::AEK_SVE2P2
,
1330 AArch64::AEK_SME2P2
, AArch64::AEK_SVE_BFSCALE
,
1331 AArch64::AEK_SVE_F16F32MM
, AArch64::AEK_SVE_AES2
,
1332 AArch64::AEK_SSVE_AES
, AArch64::AEK_F8F32MM
,
1333 AArch64::AEK_F8F16MM
, AArch64::AEK_LSFE
,
1334 AArch64::AEK_FPRCVT
, AArch64::AEK_CMPBR
,
1335 AArch64::AEK_LSUI
, AArch64::AEK_OCCMO
,
1336 AArch64::AEK_PCDPHINT
, AArch64::AEK_POPS
,
1337 AArch64::AEK_SVEAES
};
1339 std::vector
<StringRef
> Features
;
1341 AArch64::ExtensionBitset ExtVal
;
1342 for (auto Ext
: Extensions
)
1345 // Test an empty set of features.
1346 EXPECT_TRUE(AArch64::getExtensionFeatures({}, Features
));
1347 EXPECT_TRUE(Features
.size() == 0);
1349 AArch64::getExtensionFeatures(ExtVal
, Features
);
1350 EXPECT_EQ(Extensions
.size(), Features
.size());
1352 EXPECT_TRUE(llvm::is_contained(Features
, "+crc"));
1353 EXPECT_TRUE(llvm::is_contained(Features
, "+lse"));
1354 EXPECT_TRUE(llvm::is_contained(Features
, "+rdm"));
1355 EXPECT_TRUE(llvm::is_contained(Features
, "+crypto"));
1356 EXPECT_TRUE(llvm::is_contained(Features
, "+sm4"));
1357 EXPECT_TRUE(llvm::is_contained(Features
, "+sha3"));
1358 EXPECT_TRUE(llvm::is_contained(Features
, "+sha2"));
1359 EXPECT_TRUE(llvm::is_contained(Features
, "+aes"));
1360 EXPECT_TRUE(llvm::is_contained(Features
, "+dotprod"));
1361 EXPECT_TRUE(llvm::is_contained(Features
, "+fp-armv8"));
1362 EXPECT_TRUE(llvm::is_contained(Features
, "+neon"));
1363 EXPECT_TRUE(llvm::is_contained(Features
, "+fullfp16"));
1364 EXPECT_TRUE(llvm::is_contained(Features
, "+fp16fml"));
1365 EXPECT_TRUE(llvm::is_contained(Features
, "+spe"));
1366 EXPECT_TRUE(llvm::is_contained(Features
, "+ras"));
1367 EXPECT_TRUE(llvm::is_contained(Features
, "+sve"));
1368 EXPECT_TRUE(llvm::is_contained(Features
, "+sve-b16b16"));
1369 EXPECT_TRUE(llvm::is_contained(Features
, "+sve-bfscale"));
1370 EXPECT_TRUE(llvm::is_contained(Features
, "+sve-f16f32mm"));
1371 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2"));
1372 EXPECT_TRUE(llvm::is_contained(Features
, "+sve-aes"));
1373 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2-aes"));
1374 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2-sm4"));
1375 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2-sha3"));
1376 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2-bitperm"));
1377 EXPECT_TRUE(llvm::is_contained(Features
, "+sve-aes2"));
1378 EXPECT_TRUE(llvm::is_contained(Features
, "+ssve-aes"));
1379 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2p1"));
1380 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2p2"));
1381 EXPECT_TRUE(llvm::is_contained(Features
, "+rcpc"));
1382 EXPECT_TRUE(llvm::is_contained(Features
, "+rand"));
1383 EXPECT_TRUE(llvm::is_contained(Features
, "+mte"));
1384 EXPECT_TRUE(llvm::is_contained(Features
, "+ssbs"));
1385 EXPECT_TRUE(llvm::is_contained(Features
, "+sb"));
1386 EXPECT_TRUE(llvm::is_contained(Features
, "+predres"));
1387 EXPECT_TRUE(llvm::is_contained(Features
, "+bf16"));
1388 EXPECT_TRUE(llvm::is_contained(Features
, "+i8mm"));
1389 EXPECT_TRUE(llvm::is_contained(Features
, "+f32mm"));
1390 EXPECT_TRUE(llvm::is_contained(Features
, "+f64mm"));
1391 EXPECT_TRUE(llvm::is_contained(Features
, "+tme"));
1392 EXPECT_TRUE(llvm::is_contained(Features
, "+ls64"));
1393 EXPECT_TRUE(llvm::is_contained(Features
, "+brbe"));
1394 EXPECT_TRUE(llvm::is_contained(Features
, "+pauth"));
1395 EXPECT_TRUE(llvm::is_contained(Features
, "+flagm"));
1396 EXPECT_TRUE(llvm::is_contained(Features
, "+sme"));
1397 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-f64f64"));
1398 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-i16i64"));
1399 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-f16f16"));
1400 EXPECT_TRUE(llvm::is_contained(Features
, "+sme2"));
1401 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-b16b16"));
1402 EXPECT_TRUE(llvm::is_contained(Features
, "+sme2p1"));
1403 EXPECT_TRUE(llvm::is_contained(Features
, "+sme2p2"));
1404 EXPECT_TRUE(llvm::is_contained(Features
, "+hbc"));
1405 EXPECT_TRUE(llvm::is_contained(Features
, "+mops"));
1406 EXPECT_TRUE(llvm::is_contained(Features
, "+perfmon"));
1407 EXPECT_TRUE(llvm::is_contained(Features
, "+cssc"));
1408 EXPECT_TRUE(llvm::is_contained(Features
, "+rcpc3"));
1409 EXPECT_TRUE(llvm::is_contained(Features
, "+the"));
1410 EXPECT_TRUE(llvm::is_contained(Features
, "+d128"));
1411 EXPECT_TRUE(llvm::is_contained(Features
, "+lse128"));
1412 EXPECT_TRUE(llvm::is_contained(Features
, "+specres2"));
1413 EXPECT_TRUE(llvm::is_contained(Features
, "+ite"));
1414 EXPECT_TRUE(llvm::is_contained(Features
, "+gcs"));
1415 EXPECT_TRUE(llvm::is_contained(Features
, "+fp8"));
1416 EXPECT_TRUE(llvm::is_contained(Features
, "+faminmax"));
1417 EXPECT_TRUE(llvm::is_contained(Features
, "+fp8fma"));
1418 EXPECT_TRUE(llvm::is_contained(Features
, "+ssve-fp8fma"));
1419 EXPECT_TRUE(llvm::is_contained(Features
, "+fp8dot2"));
1420 EXPECT_TRUE(llvm::is_contained(Features
, "+ssve-fp8dot2"));
1421 EXPECT_TRUE(llvm::is_contained(Features
, "+fp8dot4"));
1422 EXPECT_TRUE(llvm::is_contained(Features
, "+ssve-fp8dot4"));
1423 EXPECT_TRUE(llvm::is_contained(Features
, "+f8f32mm"));
1424 EXPECT_TRUE(llvm::is_contained(Features
, "+f8f16mm"));
1425 EXPECT_TRUE(llvm::is_contained(Features
, "+lut"));
1426 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-lutv2"));
1427 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-f8f16"));
1428 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-f8f32"));
1429 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-fa64"));
1430 EXPECT_TRUE(llvm::is_contained(Features
, "+cpa"));
1431 EXPECT_TRUE(llvm::is_contained(Features
, "+pauth-lr"));
1432 EXPECT_TRUE(llvm::is_contained(Features
, "+tlbiw"));
1433 EXPECT_TRUE(llvm::is_contained(Features
, "+jsconv"));
1434 EXPECT_TRUE(llvm::is_contained(Features
, "+complxnum"));
1435 EXPECT_TRUE(llvm::is_contained(Features
, "+lsfe"));
1436 EXPECT_TRUE(llvm::is_contained(Features
, "+fprcvt"));
1437 EXPECT_TRUE(llvm::is_contained(Features
, "+cmpbr"));
1438 EXPECT_TRUE(llvm::is_contained(Features
, "+lsui"));
1439 EXPECT_TRUE(llvm::is_contained(Features
, "+occmo"));
1440 EXPECT_TRUE(llvm::is_contained(Features
, "+pcdphint"));
1441 EXPECT_TRUE(llvm::is_contained(Features
, "+pops"));
1443 // Assuming we listed every extension above, this should produce the same
1445 std::vector
<StringRef
> AllFeatures
;
1446 EXPECT_TRUE(AArch64::getExtensionFeatures(ExtVal
, AllFeatures
));
1447 EXPECT_THAT(Features
, ::testing::ContainerEq(AllFeatures
));
1450 TEST(TargetParserTest
, AArch64ArchFeatures
) {
1451 EXPECT_EQ(AArch64::ARMV8A
.ArchFeature
, "+v8a");
1452 EXPECT_EQ(AArch64::ARMV8_1A
.ArchFeature
, "+v8.1a");
1453 EXPECT_EQ(AArch64::ARMV8_2A
.ArchFeature
, "+v8.2a");
1454 EXPECT_EQ(AArch64::ARMV8_3A
.ArchFeature
, "+v8.3a");
1455 EXPECT_EQ(AArch64::ARMV8_4A
.ArchFeature
, "+v8.4a");
1456 EXPECT_EQ(AArch64::ARMV8_5A
.ArchFeature
, "+v8.5a");
1457 EXPECT_EQ(AArch64::ARMV8_6A
.ArchFeature
, "+v8.6a");
1458 EXPECT_EQ(AArch64::ARMV8_7A
.ArchFeature
, "+v8.7a");
1459 EXPECT_EQ(AArch64::ARMV8_8A
.ArchFeature
, "+v8.8a");
1460 EXPECT_EQ(AArch64::ARMV8_9A
.ArchFeature
, "+v8.9a");
1461 EXPECT_EQ(AArch64::ARMV9A
.ArchFeature
, "+v9a");
1462 EXPECT_EQ(AArch64::ARMV9_1A
.ArchFeature
, "+v9.1a");
1463 EXPECT_EQ(AArch64::ARMV9_2A
.ArchFeature
, "+v9.2a");
1464 EXPECT_EQ(AArch64::ARMV9_3A
.ArchFeature
, "+v9.3a");
1465 EXPECT_EQ(AArch64::ARMV9_4A
.ArchFeature
, "+v9.4a");
1466 EXPECT_EQ(AArch64::ARMV9_5A
.ArchFeature
, "+v9.5a");
1467 EXPECT_EQ(AArch64::ARMV9_6A
.ArchFeature
, "+v9.6a");
1468 EXPECT_EQ(AArch64::ARMV8R
.ArchFeature
, "+v8r");
1471 TEST(TargetParserTest
, AArch64ArchPartialOrder
) {
1472 for (const auto *A
: AArch64::ArchInfos
) {
1475 // v8r has no relation to other valid architectures
1476 if (*A
!= AArch64::ARMV8R
) {
1477 EXPECT_FALSE(A
->implies(AArch64::ARMV8R
));
1478 EXPECT_FALSE(AArch64::ARMV8R
.implies(*A
));
1482 for (const auto *A
: {
1493 EXPECT_TRUE(A
->implies(AArch64::ARMV8A
));
1495 for (const auto *A
:
1496 {&AArch64::ARMV9_1A
, &AArch64::ARMV9_2A
, &AArch64::ARMV9_3A
,
1497 &AArch64::ARMV9_4A
, &AArch64::ARMV9_5A
, &AArch64::ARMV9_6A
})
1498 EXPECT_TRUE(A
->implies(AArch64::ARMV9A
));
1500 EXPECT_TRUE(AArch64::ARMV8_1A
.implies(AArch64::ARMV8A
));
1501 EXPECT_TRUE(AArch64::ARMV8_2A
.implies(AArch64::ARMV8_1A
));
1502 EXPECT_TRUE(AArch64::ARMV8_3A
.implies(AArch64::ARMV8_2A
));
1503 EXPECT_TRUE(AArch64::ARMV8_4A
.implies(AArch64::ARMV8_3A
));
1504 EXPECT_TRUE(AArch64::ARMV8_5A
.implies(AArch64::ARMV8_4A
));
1505 EXPECT_TRUE(AArch64::ARMV8_6A
.implies(AArch64::ARMV8_5A
));
1506 EXPECT_TRUE(AArch64::ARMV8_7A
.implies(AArch64::ARMV8_6A
));
1507 EXPECT_TRUE(AArch64::ARMV8_8A
.implies(AArch64::ARMV8_7A
));
1508 EXPECT_TRUE(AArch64::ARMV8_9A
.implies(AArch64::ARMV8_8A
));
1510 EXPECT_TRUE(AArch64::ARMV9_1A
.implies(AArch64::ARMV9A
));
1511 EXPECT_TRUE(AArch64::ARMV9_2A
.implies(AArch64::ARMV9_1A
));
1512 EXPECT_TRUE(AArch64::ARMV9_3A
.implies(AArch64::ARMV9_2A
));
1513 EXPECT_TRUE(AArch64::ARMV9_4A
.implies(AArch64::ARMV9_3A
));
1514 EXPECT_TRUE(AArch64::ARMV9_5A
.implies(AArch64::ARMV9_4A
));
1515 EXPECT_TRUE(AArch64::ARMV9_6A
.implies(AArch64::ARMV9_5A
));
1517 EXPECT_TRUE(AArch64::ARMV9A
.implies(AArch64::ARMV8_5A
));
1518 EXPECT_TRUE(AArch64::ARMV9_1A
.implies(AArch64::ARMV8_6A
));
1519 EXPECT_TRUE(AArch64::ARMV9_2A
.implies(AArch64::ARMV8_7A
));
1520 EXPECT_TRUE(AArch64::ARMV9_3A
.implies(AArch64::ARMV8_8A
));
1521 EXPECT_TRUE(AArch64::ARMV9_4A
.implies(AArch64::ARMV8_9A
));
1524 TEST(TargetParserTest
, AArch64ArchExtFeature
) {
1525 const char *ArchExt
[][4] = {
1526 {"crc", "nocrc", "+crc", "-crc"},
1527 {"crypto", "nocrypto", "+crypto", "-crypto"},
1528 {"flagm", "noflagm", "+flagm", "-flagm"},
1529 {"fp", "nofp", "+fp-armv8", "-fp-armv8"},
1530 {"simd", "nosimd", "+neon", "-neon"},
1531 {"fp16", "nofp16", "+fullfp16", "-fullfp16"},
1532 {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"},
1533 {"profile", "noprofile", "+spe", "-spe"},
1534 {"ras", "noras", "+ras", "-ras"},
1535 {"lse", "nolse", "+lse", "-lse"},
1536 {"rdm", "nordm", "+rdm", "-rdm"},
1537 {"sve", "nosve", "+sve", "-sve"},
1538 {"sve-b16b16", "nosve-b16b16", "+sve-b16b16", "-sve-b16b16"},
1539 {"sve-bfscale", "nosve-bfscale", "+sve-bfscale", "-sve-bfscale"},
1540 {"sve-f16f32mm", "nosve-f16f32mm", "+sve-f16f32mm", "-sve-f16f32mm"},
1541 {"sve2", "nosve2", "+sve2", "-sve2"},
1542 {"sve-aes", "nosve-aes", "+sve-aes", "-sve-aes"},
1543 {"sve2-aes", "nosve2-aes", "+sve2-aes", "-sve2-aes"},
1544 {"sve2-sm4", "nosve2-sm4", "+sve2-sm4", "-sve2-sm4"},
1545 {"sve2-sha3", "nosve2-sha3", "+sve2-sha3", "-sve2-sha3"},
1546 {"sve2p1", "nosve2p1", "+sve2p1", "-sve2p1"},
1547 {"sve2p2", "nosve2p2", "+sve2p2", "-sve2p2"},
1548 {"sve2-bitperm", "nosve2-bitperm", "+sve2-bitperm", "-sve2-bitperm"},
1549 {"sve-aes2", "nosve-aes2", "+sve-aes2", "-sve-aes2"},
1550 {"ssve-aes", "nossve-aes", "+ssve-aes", "-ssve-aes"},
1551 {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
1552 {"rcpc", "norcpc", "+rcpc", "-rcpc"},
1553 {"rng", "norng", "+rand", "-rand"},
1554 {"memtag", "nomemtag", "+mte", "-mte"},
1555 {"tme", "notme", "+tme", "-tme"},
1556 {"pauth", "nopauth", "+pauth", "-pauth"},
1557 {"ssbs", "nossbs", "+ssbs", "-ssbs"},
1558 {"sb", "nosb", "+sb", "-sb"},
1559 {"predres", "nopredres", "+predres", "-predres"},
1560 {"i8mm", "noi8mm", "+i8mm", "-i8mm"},
1561 {"f32mm", "nof32mm", "+f32mm", "-f32mm"},
1562 {"f64mm", "nof64mm", "+f64mm", "-f64mm"},
1563 {"f8f32mm", "nof8f32mm", "+f8f32mm", "-f8f32mm"},
1564 {"f8f16mm", "nof8f16mm", "+f8f16mm", "-f8f16mm"},
1565 {"sme", "nosme", "+sme", "-sme"},
1566 {"sme-fa64", "nosme-fa64", "+sme-fa64", "-sme-fa64"},
1567 {"sme-f64f64", "nosme-f64f64", "+sme-f64f64", "-sme-f64f64"},
1568 {"sme-i16i64", "nosme-i16i64", "+sme-i16i64", "-sme-i16i64"},
1569 {"sme-f16f16", "nosme-f16f16", "+sme-f16f16", "-sme-f16f16"},
1570 {"sme2", "nosme2", "+sme2", "-sme2"},
1571 {"sme-b16b16", "nosme-b16b16", "+sme-b16b16", "-sme-b16b16"},
1572 {"sme2p1", "nosme2p1", "+sme2p1", "-sme2p1"},
1573 {"sme2p2", "nosme2p2", "+sme2p2", "-sme2p2"},
1574 {"hbc", "nohbc", "+hbc", "-hbc"},
1575 {"mops", "nomops", "+mops", "-mops"},
1576 {"pmuv3", "nopmuv3", "+perfmon", "-perfmon"},
1577 {"predres2", "nopredres2", "+specres2", "-specres2"},
1578 {"rasv2", "norasv2", "+rasv2", "-rasv2"},
1579 {"gcs", "nogcs", "+gcs", "-gcs"},
1580 {"fp8", "nofp8", "+fp8", "-fp8"},
1581 {"faminmax", "nofaminmax", "+faminmax", "-faminmax"},
1582 {"fp8fma", "nofp8fma", "+fp8fma", "-fp8fma"},
1583 {"ssve-fp8fma", "nossve-fp8fma", "+ssve-fp8fma", "-ssve-fp8fma"},
1584 {"fp8dot2", "nofp8dot2", "+fp8dot2", "-fp8dot2"},
1585 {"ssve-fp8dot2", "nossve-fp8dot2", "+ssve-fp8dot2", "-ssve-fp8dot2"},
1586 {"fp8dot4", "nofp8dot4", "+fp8dot4", "-fp8dot4"},
1587 {"ssve-fp8dot4", "nossve-fp8dot4", "+ssve-fp8dot4", "-ssve-fp8dot4"},
1588 {"lut", "nolut", "+lut", "-lut"},
1589 {"sme-lutv2", "nosme-lutv2", "+sme-lutv2", "-sme-lutv2"},
1590 {"sme-f8f16", "nosme-f8f16", "+sme-f8f16", "-sme-f8f16"},
1591 {"sme-f8f32", "nosme-f8f32", "+sme-f8f32", "-sme-f8f32"},
1592 {"lsfe", "nolsfe", "+lsfe", "-lsfe"},
1593 {"fprcvt", "nofprcvt", "+fprcvt", "-fprcvt"},
1594 {"cmpbr", "nocmpbr", "+cmpbr", "-cmpbr"},
1595 {"lsui", "nolsui", "+lsui", "-lsui"},
1596 {"occmo", "nooccmo", "+occmo", "-occmo"},
1597 {"pcdphint", "nopcdphint", "+pcdphint", "-pcdphint"},
1598 {"pops", "nopops", "+pops", "-pops"},
1601 for (unsigned i
= 0; i
< std::size(ArchExt
); i
++) {
1602 EXPECT_EQ(StringRef(ArchExt
[i
][2]),
1603 AArch64::getArchExtFeature(ArchExt
[i
][0]));
1604 EXPECT_EQ(StringRef(ArchExt
[i
][3]),
1605 AArch64::getArchExtFeature(ArchExt
[i
][1]));
1609 TEST(TargetParserTest
, AArch64PrintSupportedExtensions
) {
1610 std::string expected
= "All available -march extensions for AArch64\n\n"
1611 " Name Architecture Feature(s) "
1615 testing::internal::CaptureStdout();
1616 AArch64::PrintSupportedExtensions();
1618 std::string captured
= testing::internal::GetCapturedStdout();
1620 // Check that the start of the output is as expected.
1621 EXPECT_EQ(0ULL, captured
.find(expected
));
1623 // Should not include "none".
1624 EXPECT_EQ(std::string::npos
, captured
.find("none"));
1625 // Should not include anything that lacks a feature name. Checking a few here
1626 // but not all as if one is hidden correctly the rest should be.
1627 EXPECT_EQ(std::string::npos
, captured
.find("memtag3"));
1628 EXPECT_EQ(std::string::npos
, captured
.find("sha1"));
1629 EXPECT_EQ(std::string::npos
, captured
.find("ssbs2"));
1632 struct AArch64ExtensionDependenciesBaseArchTestParams
{
1633 const llvm::AArch64::ArchInfo
&Arch
;
1634 std::vector
<StringRef
> Modifiers
;
1635 std::vector
<StringRef
> ExpectedPos
;
1636 std::vector
<StringRef
> ExpectedNeg
;
1639 class AArch64ExtensionDependenciesBaseArchTestFixture
1640 : public ::testing::TestWithParam
<
1641 AArch64ExtensionDependenciesBaseArchTestParams
> {};
1643 struct AArch64ExtensionDependenciesBaseCPUTestParams
{
1645 std::vector
<StringRef
> Modifiers
;
1646 std::vector
<StringRef
> ExpectedPos
;
1647 std::vector
<StringRef
> ExpectedNeg
;
1650 class AArch64ExtensionDependenciesBaseCPUTestFixture
1651 : public ::testing::TestWithParam
<
1652 AArch64ExtensionDependenciesBaseCPUTestParams
> {};
1654 TEST_P(AArch64ExtensionDependenciesBaseArchTestFixture
,
1655 AArch64ExtensionDependenciesBaseArch
) {
1656 auto Params
= GetParam();
1658 llvm::AArch64::ExtensionSet Extensions
;
1659 Extensions
.addArchDefaults(Params
.Arch
);
1660 for (auto M
: Params
.Modifiers
) {
1661 bool success
= Extensions
.parseModifier(M
);
1662 EXPECT_TRUE(success
);
1664 std::vector
<StringRef
> Features
;
1665 Extensions
.toLLVMFeatureList(Features
);
1667 for (auto E
: Params
.ExpectedPos
) {
1668 std::string PosString
= "+";
1670 std::string NegString
= "-";
1672 ASSERT_THAT(Features
, Contains(StrEq(PosString
)));
1673 ASSERT_THAT(Features
, Not(Contains(StrEq(NegString
))));
1676 for (auto E
: Params
.ExpectedNeg
) {
1677 std::string PosString
= "+";
1679 ASSERT_THAT(Features
, Not(Contains(StrEq(PosString
))));
1680 // Features default to off, so the negative string is not expected in many
1685 TEST_P(AArch64ExtensionDependenciesBaseCPUTestFixture
,
1686 AArch64ExtensionDependenciesBaseCPU
) {
1687 auto Params
= GetParam();
1689 llvm::AArch64::ExtensionSet Extensions
;
1690 const std::optional
<llvm::AArch64::CpuInfo
> CPU
=
1691 llvm::AArch64::parseCpu(Params
.CPUName
);
1693 Extensions
.addCPUDefaults(*CPU
);
1694 for (auto M
: Params
.Modifiers
) {
1695 bool success
= Extensions
.parseModifier(M
);
1696 EXPECT_TRUE(success
);
1698 std::vector
<StringRef
> Features
;
1699 Extensions
.toLLVMFeatureList(Features
);
1701 for (auto E
: Params
.ExpectedPos
) {
1702 std::string PosString
= "+";
1704 std::string NegString
= "-";
1706 ASSERT_THAT(Features
, Contains(StrEq(PosString
)));
1707 ASSERT_THAT(Features
, Not(Contains(StrEq(NegString
))));
1710 for (auto E
: Params
.ExpectedNeg
) {
1711 std::string PosString
= "+";
1713 ASSERT_THAT(Features
, Not(Contains(StrEq(PosString
))));
1714 // Features default to off, so the negative string is not expected in many
1719 AArch64ExtensionDependenciesBaseArchTestParams
1720 AArch64ExtensionDependenciesArchData
[] = {
1721 // Base architecture features
1722 {AArch64::ARMV8A
, {}, {"v8a", "fp-armv8", "neon"}, {}},
1725 {"v8.1a", "crc", "fp-armv8", "lse", "rdm", "neon"},
1727 {AArch64::ARMV9_5A
, {}, {"v9.5a", "mops", "cpa"}, {}},
1729 // Positive modifiers
1730 {AArch64::ARMV8A
, {"fp16"}, {"fullfp16"}, {}},
1731 {AArch64::ARMV8A
, {"dotprod"}, {"dotprod"}, {}},
1733 // Negative modifiers
1734 {AArch64::ARMV8A
, {"nofp"}, {"v8a"}, {"fp-armv8", "neon"}},
1739 {"v8a", "fp-armv8", "neon"},
1744 {"fp-armv8", "neon", "fullfp16"}},
1746 // Long dependency chains: sve2-bitperm -> sve2 -> sve -> fp16 -> fp
1748 {"nofp", "sve2-bitperm"},
1749 {"fp-armv8", "fullfp16", "sve", "sve2", "sve2-bitperm"},
1752 {"sve2-bitperm", "nofp16"},
1754 {"full-fp16", "sve", "sve2", "sve2-bitperm"}},
1756 // Meaning of +crypto varies with base architecture.
1757 {AArch64::ARMV8A
, {"crypto"}, {"aes", "sha2"}, {}},
1758 {AArch64::ARMV8_4A
, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}},
1759 {AArch64::ARMV9A
, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}},
1761 // -crypto always disables all crypto features, even if it wouldn't
1764 {"aes", "sha2", "sha3", "sm4", "nocrypto"},
1766 {"aes", "sha2", "sha3", "sm4"}},
1768 {"aes", "sha2", "sha3", "sm4", "nocrypto"},
1770 {"aes", "sha2", "sha3", "sm4"}},
1772 // +fp16 implies +fp16fml for v8.4A+, but not v9.0-A+
1773 {AArch64::ARMV8_3A
, {"fp16"}, {"fullfp16"}, {"fp16fml"}},
1774 {AArch64::ARMV9A
, {"fp16"}, {"fullfp16"}, {"fp16fml"}},
1775 {AArch64::ARMV8_4A
, {"fp16"}, {"fullfp16", "fp16fml"}, {}},
1778 {AArch64::ARMV8A
, {"nofp", "fp16"}, {"fp-armv8", "fullfp16"}, {}},
1779 {AArch64::ARMV8A
, {"fp16", "nofp"}, {}, {"fp-armv8", "fullfp16"}},
1782 {AArch64::ARMV8A
, {"nofp", "simd"}, {"fp-armv8", "neon"}, {}},
1783 {AArch64::ARMV8A
, {"simd", "nofp"}, {}, {"fp-armv8", "neon"}},
1786 {AArch64::ARMV8A
, {"nofp", "jscvt"}, {"fp-armv8", "jsconv"}, {}},
1787 {AArch64::ARMV8A
, {"jscvt", "nofp"}, {}, {"fp-armv8", "jsconv"}},
1790 {AArch64::ARMV9_6A
, {"nofp", "lsfe"}, {"fp-armv8", "lsfe"}, {}},
1791 {AArch64::ARMV9_6A
, {"lsfe", "nofp"}, {}, {"fp-armv8", "lsfe"}},
1794 {AArch64::ARMV9_6A
, {"nofp", "fprcvt"}, {"fp-armv8", "fprcvt"}, {}},
1795 {AArch64::ARMV9_6A
, {"fprcvt", "nofp"}, {}, {"fp-armv8", "fprcvt"}},
1797 // simd -> {aes, sha2, sha3, sm4, f8f16mm, f8f32mm}
1798 {AArch64::ARMV8A
, {"nosimd", "aes"}, {"neon", "aes"}, {}},
1799 {AArch64::ARMV8A
, {"aes", "nosimd"}, {}, {"neon", "aes"}},
1800 {AArch64::ARMV8A
, {"nosimd", "sha2"}, {"neon", "sha2"}, {}},
1801 {AArch64::ARMV8A
, {"sha2", "nosimd"}, {}, {"neon", "sha2"}},
1802 {AArch64::ARMV8A
, {"nosimd", "sha3"}, {"neon", "sha3"}, {}},
1803 {AArch64::ARMV8A
, {"sha3", "nosimd"}, {}, {"neon", "sha3"}},
1804 {AArch64::ARMV8A
, {"nosimd", "sm4"}, {"neon", "sm4"}, {}},
1805 {AArch64::ARMV8A
, {"sm4", "nosimd"}, {}, {"neon", "sm4"}},
1806 {AArch64::ARMV9_6A
, {"nosimd", "f8f16mm"}, {"neon", "f8f16mm"}, {}},
1807 {AArch64::ARMV9_6A
, {"f8f16mm", "nosimd"}, {}, {"neon", "f8f16mm"}},
1808 {AArch64::ARMV9_6A
, {"nosimd", "f8f32mm"}, {"neon", "f8f32mm"}, {}},
1809 {AArch64::ARMV9_6A
, {"f8f32mm", "nosimd"}, {}, {"neon", "f8f32mm"}},
1811 // simd -> {rdm, dotprod, fcma}
1812 {AArch64::ARMV8A
, {"nosimd", "rdm"}, {"neon", "rdm"}, {}},
1813 {AArch64::ARMV8A
, {"rdm", "nosimd"}, {}, {"neon", "rdm"}},
1814 {AArch64::ARMV8A
, {"nosimd", "dotprod"}, {"neon", "dotprod"}, {}},
1815 {AArch64::ARMV8A
, {"dotprod", "nosimd"}, {}, {"neon", "dotprod"}},
1816 {AArch64::ARMV8A
, {"nosimd", "fcma"}, {"neon", "complxnum"}, {}},
1817 {AArch64::ARMV8A
, {"fcma", "nosimd"}, {}, {"neon", "complxnum"}},
1819 // fp16 -> {fp16fml, sve}
1820 {AArch64::ARMV8A
, {"nofp16", "fp16fml"}, {"fullfp16", "fp16fml"}, {}},
1821 {AArch64::ARMV8A
, {"fp16fml", "nofp16"}, {}, {"fullfp16", "fp16fml"}},
1822 {AArch64::ARMV8A
, {"nofp16", "sve"}, {"fullfp16", "sve"}, {}},
1823 {AArch64::ARMV8A
, {"sve", "nofp16"}, {}, {"fullfp16", "sve"}},
1826 {AArch64::ARMV8A
, {"nobf16", "sme"}, {"bf16", "sme"}, {}},
1827 {AArch64::ARMV8A
, {"sme", "nobf16"}, {}, {"bf16", "sme"}},
1829 // sve -> {sve2, f32mm, f64mm, sve-f16f32mm}
1830 {AArch64::ARMV8A
, {"nosve", "sve2"}, {"sve", "sve2"}, {}},
1831 {AArch64::ARMV8A
, {"sve2", "nosve"}, {}, {"sve", "sve2"}},
1832 {AArch64::ARMV8A
, {"nosve", "f32mm"}, {"sve", "f32mm"}, {}},
1833 {AArch64::ARMV8A
, {"f32mm", "nosve"}, {}, {"sve", "f32mm"}},
1834 {AArch64::ARMV8A
, {"nosve", "f64mm"}, {"sve", "f64mm"}, {}},
1835 {AArch64::ARMV8A
, {"f64mm", "nosve"}, {}, {"sve", "f64mm"}},
1837 {"nosve", "sve-f16f32mm"},
1838 {"sve", "sve-f16f32mm"},
1841 {"sve-f16f32mm", "nosve"},
1843 {"sve", "sve-f16f32mm"}},
1846 {AArch64::ARMV8A
, {"noaes", "sve-aes"}, {"aes", "sve-aes"}, {}},
1847 {AArch64::ARMV8A
, {"sve-aes", "noaes"}, {}, {"aes", "sve-aes"}},
1849 // sve2 -> {sve2p1, sve2-bitperm, sve2-sha3, sve2-sm4, sve2-aes}
1850 {AArch64::ARMV8A
, {"nosve2", "sve2p1"}, {"sve2", "sve2p1"}, {}},
1851 {AArch64::ARMV8A
, {"sve2p1", "nosve2"}, {}, {"sve2", "sve2p1"}},
1853 {"nosve2", "sve2-bitperm"},
1854 {"sve2", "sve2-bitperm"},
1857 {"sve2-bitperm", "nosve2"},
1859 {"sve2", "sve2-bitperm"}},
1860 {AArch64::ARMV8A
, {"nosve2", "sve2-sha3"}, {"sve2", "sve2-sha3"}, {}},
1861 {AArch64::ARMV8A
, {"sve2-sha3", "nosve2"}, {}, {"sve2", "sve2-sha3"}},
1862 {AArch64::ARMV8A
, {"nosve2", "sve2-sm4"}, {"sve2", "sve2-sm4"}, {}},
1863 {AArch64::ARMV8A
, {"sve2-sm4", "nosve2"}, {}, {"sve2", "sve2-sm4"}},
1864 {AArch64::ARMV8A
, {"nosve2", "sve2-aes"}, {"sve2", "sve2-aes"}, {}},
1865 {AArch64::ARMV8A
, {"sve2-aes", "nosve2"}, {}, {"sve2", "sve2-aes"}},
1867 // sve-b16b16 -> {sme-b16b16}
1869 {"nosve-b16b16", "sme-b16b16"},
1870 {"sve-b16b16", "sme-b16b16"},
1873 {"sme-b16b16", "nosve-b16b16"},
1875 {"sve-b16b16", "sme-b16b16"}},
1877 // sve2p1 -> {sve2p2}
1878 {AArch64::ARMV9_6A
, {"nosve2p1", "sve2p2"}, {"sve2p1", "sve2p2"}, {}},
1879 {AArch64::ARMV9_6A
, {"sve2p2", "nosve2p1"}, {}, {"sve2p1", "sve2p2"}},
1881 // sme -> {sme2, sme-f16f16, sme-f64f64, sme-i16i64, sme-fa64}
1882 {AArch64::ARMV8A
, {"nosme", "sme2"}, {"sme", "sme2"}, {}},
1883 {AArch64::ARMV8A
, {"sme2", "nosme"}, {}, {"sme", "sme2"}},
1884 {AArch64::ARMV8A
, {"nosme", "sme-f16f16"}, {"sme", "sme-f16f16"}, {}},
1885 {AArch64::ARMV8A
, {"sme-f16f16", "nosme"}, {}, {"sme", "sme-f16f16"}},
1886 {AArch64::ARMV8A
, {"nosme", "sme-f64f64"}, {"sme", "sme-f64f64"}, {}},
1887 {AArch64::ARMV8A
, {"sme-f64f64", "nosme"}, {}, {"sme", "sme-f64f64"}},
1888 {AArch64::ARMV8A
, {"nosme", "sme-i16i64"}, {"sme", "sme-i16i64"}, {}},
1889 {AArch64::ARMV8A
, {"sme-i16i64", "nosme"}, {}, {"sme", "sme-i16i64"}},
1890 {AArch64::ARMV8A
, {"nosme", "sme-fa64"}, {"sme", "sme-fa64"}, {}},
1891 {AArch64::ARMV8A
, {"sme-fa64", "nosme"}, {}, {"sme", "sme-fa64"}},
1893 // sme2 -> {sme2p1, ssve-fp8fma, ssve-fp8dot2, ssve-fp8dot4, sme-f8f16,
1894 // sme-f8f32, sme-b16b16, ssve-aes}
1895 {AArch64::ARMV8A
, {"nosme2", "sme2p1"}, {"sme2", "sme2p1"}, {}},
1896 {AArch64::ARMV8A
, {"sme2p1", "nosme2"}, {}, {"sme2", "sme2p1"}},
1898 {"nosme2", "ssve-fp8fma"},
1899 {"sme2", "ssve-fp8fma"},
1902 {"ssve-fp8fma", "nosme2"},
1904 {"sme2", "ssve-fp8fma"}},
1906 {"nosme2", "ssve-fp8dot2"},
1907 {"sme2", "ssve-fp8dot2"},
1910 {"ssve-fp8dot2", "nosme2"},
1912 {"sme2", "ssve-fp8dot2"}},
1914 {"nosme2", "ssve-fp8dot4"},
1915 {"sme2", "ssve-fp8dot4"},
1918 {"ssve-fp8dot4", "nosme2"},
1920 {"sme2", "ssve-fp8dot4"}},
1921 {AArch64::ARMV8A
, {"nosme2", "sme-f8f16"}, {"sme2", "sme-f8f16"}, {}},
1922 {AArch64::ARMV8A
, {"sme-f8f16", "nosme2"}, {}, {"sme2", "sme-f8f16"}},
1923 {AArch64::ARMV8A
, {"nosme2", "sme-f8f32"}, {"sme2", "sme-f8f32"}, {}},
1924 {AArch64::ARMV8A
, {"sme-f8f32", "nosme2"}, {}, {"sme2", "sme-f8f32"}},
1925 {AArch64::ARMV8A
, {"nosme2", "sme-b16b16"}, {"sme2", "sme-b16b16"}, {}},
1926 {AArch64::ARMV8A
, {"sme-b16b16", "nosme2"}, {}, {"sme2", "sme-b16b16"}},
1927 {AArch64::ARMV9_6A
, {"nosme2", "ssve-aes"}, {"sme2", "ssve-aes"}, {}},
1928 {AArch64::ARMV9_6A
, {"ssve-aes", "nosme2"}, {}, {"ssve-aes", "sme2"}},
1930 // sme2p1 -> {sme2p2}
1931 {AArch64::ARMV9_6A
, {"nosme2p1", "sme2p2"}, {"sme2p2", "sme2p1"}, {}},
1932 {AArch64::ARMV9_6A
, {"sme2p2", "nosme2p1"}, {}, {"sme2p1", "sme2p2"}},
1934 // fp8 -> {sme-f8f16, sme-f8f32, f8f16mm, f8f32mm}
1935 {AArch64::ARMV8A
, {"nofp8", "sme-f8f16"}, {"fp8", "sme-f8f16"}, {}},
1936 {AArch64::ARMV8A
, {"sme-f8f16", "nofp8"}, {}, {"fp8", "sme-f8f16"}},
1937 {AArch64::ARMV8A
, {"nofp8", "sme-f8f32"}, {"fp8", "sme-f8f32"}, {}},
1938 {AArch64::ARMV8A
, {"sme-f8f32", "nofp8"}, {}, {"fp8", "sme-f8f32"}},
1939 {AArch64::ARMV9_6A
, {"nofp8", "f8f16mm"}, {"fp8", "f8f16mm"}, {}},
1940 {AArch64::ARMV9_6A
, {"f8f16mm", "nofp8"}, {}, {"fp8", "f8f16mm"}},
1941 {AArch64::ARMV9_6A
, {"nofp8", "f8f32mm"}, {"fp8", "f8f32mm"}, {}},
1942 {AArch64::ARMV9_6A
, {"f8f32mm", "nofp8"}, {}, {"fp8", "f8f32mm"}},
1945 {AArch64::ARMV8A
, {"nolse", "lse128"}, {"lse", "lse128"}, {}},
1946 {AArch64::ARMV8A
, {"lse128", "nolse"}, {}, {"lse", "lse128"}},
1948 // predres -> predres2
1950 {"nopredres", "predres2"},
1951 {"predres", "specres2"},
1954 {"predres2", "nopredres"},
1956 {"predres", "specres2"}},
1959 {AArch64::ARMV8A
, {"noras", "rasv2"}, {"ras", "rasv2"}, {}},
1960 {AArch64::ARMV8A
, {"rasv2", "noras"}, {}, {"ras", "rasv2"}},
1963 {AArch64::ARMV8A
, {"norcpc", "rcpc3"}, {"rcpc", "rcpc3"}, {}},
1964 {AArch64::ARMV8A
, {"rcpc3", "norcpc"}, {}, {"rcpc", "rcpc3"}},
1966 // sve-aes -> {ssve-aes, sve2-aes}
1968 {"nosve-aes", "ssve-aes"},
1969 {"sve-aes", "ssve-aes"},
1972 {"ssve-aes", "nosve-aes"},
1974 {"ssve-aes", "sve-aes"}},
1976 {"nosve-aes", "sve2-aes"},
1977 {"sve2-aes", "sve-aes"},
1980 {"sve2-aes", "nosve-aes"},
1982 {"sve2-aes", "sve-aes"}},
1984 // -sve2-aes should disable sve-aes (only)
1986 {"sve2", "sve-aes", "nosve2-aes"},
1988 {"sve2-aes", "sve-aes"}}};
1990 INSTANTIATE_TEST_SUITE_P(
1991 AArch64ExtensionDependenciesBaseArch
,
1992 AArch64ExtensionDependenciesBaseArchTestFixture
,
1993 ::testing::ValuesIn(AArch64ExtensionDependenciesArchData
));
1995 AArch64ExtensionDependenciesBaseCPUTestParams
1996 AArch64ExtensionDependenciesCPUData
[] = {
1997 // Base CPU features
2000 {"v8a", "aes", "crc", "fp-armv8", "sha2", "neon"},
2004 {"v8r", "crc", "dotprod", "fp-armv8", "fullfp16", "fp16fml", "lse",
2005 "ras", "rcpc", "rdm", "sb", "neon", "ssbs"},
2009 {"v9.2a", "bf16", "crc", "dotprod", "flagm", "fp-armv8",
2010 "fullfp16", "fp16fml", "i8mm", "lse", "mte", "pauth",
2011 "perfmon", "predres", "ras", "rcpc", "rdm", "sb",
2012 "neon", "ssbs", "sve", "sve2-bitperm", "sve2"},
2015 // Negative modifiers
2018 {"v8r", "crc", "lse", "ras", "rcpc", "sb", "ssbs"},
2019 {"fp-armv8", "neon", "fullfp16", "fp16fml", "dotprod", "rdm"}},
2022 INSTANTIATE_TEST_SUITE_P(
2023 AArch64ExtensionDependenciesBaseCPU
,
2024 AArch64ExtensionDependenciesBaseCPUTestFixture
,
2025 ::testing::ValuesIn(AArch64ExtensionDependenciesCPUData
));