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-a510", "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>("cortex-a710", "armv9-a", "neon-fp-armv8",
416 ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
417 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
|
418 ARM::AEK_DSP
| ARM::AEK_CRC
|
419 ARM::AEK_RAS
| ARM::AEK_DOTPROD
|
420 ARM::AEK_FP16FML
| ARM::AEK_BF16
|
421 ARM::AEK_I8MM
| ARM::AEK_SB
,
423 ARMCPUTestParams
<uint64_t>(
424 "cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8",
425 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
426 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
|
427 ARM::AEK_FP16
| ARM::AEK_RAS
| ARM::AEK_DOTPROD
,
429 ARMCPUTestParams
<uint64_t>(
430 "cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8",
431 ARM::AEK_DOTPROD
| ARM::AEK_FP16
| ARM::AEK_SEC
| ARM::AEK_MP
|
432 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
|
433 ARM::AEK_DSP
| ARM::AEK_CRC
| ARM::AEK_RAS
,
435 ARMCPUTestParams
<uint64_t>(
436 "cortex-a78ae", "armv8.2-a", "crypto-neon-fp-armv8",
437 ARM::AEK_RAS
| ARM::AEK_DOTPROD
| ARM::AEK_SEC
| ARM::AEK_MP
|
438 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
|
439 ARM::AEK_DSP
| ARM::AEK_CRC
| ARM::AEK_RAS
,
441 ARMCPUTestParams
<uint64_t>(
442 "cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8",
443 ARM::AEK_RAS
| ARM::AEK_FP16
| ARM::AEK_DOTPROD
| ARM::AEK_SEC
|
444 ARM::AEK_MP
| ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
445 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
| ARM::AEK_CRC
,
447 ARMCPUTestParams
<uint64_t>(
448 "cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8",
449 ARM::AEK_RAS
| ARM::AEK_FP16
| ARM::AEK_DOTPROD
| ARM::AEK_SEC
|
450 ARM::AEK_MP
| ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
451 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
| ARM::AEK_CRC
,
453 ARMCPUTestParams
<uint64_t>(
454 "neoverse-n1", "armv8.2-a", "crypto-neon-fp-armv8",
455 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
456 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
|
457 ARM::AEK_FP16
| ARM::AEK_RAS
| ARM::AEK_DOTPROD
,
459 ARMCPUTestParams
<uint64_t>(
460 "neoverse-n2", "armv9-a", "neon-fp-armv8",
461 ARM::AEK_CRC
| ARM::AEK_HWDIVTHUMB
| ARM::AEK_HWDIVARM
|
462 ARM::AEK_MP
| ARM::AEK_SEC
| ARM::AEK_VIRT
| ARM::AEK_DSP
|
463 ARM::AEK_BF16
| ARM::AEK_DOTPROD
| ARM::AEK_RAS
|
464 ARM::AEK_I8MM
| ARM::AEK_FP16FML
| ARM::AEK_SB
,
466 ARMCPUTestParams
<uint64_t>(
467 "neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8",
468 ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
469 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
| ARM::AEK_CRC
|
470 ARM::AEK_RAS
| ARM::AEK_FP16
| ARM::AEK_BF16
| ARM::AEK_DOTPROD
,
472 ARMCPUTestParams
<uint64_t>("cyclone", "armv8-a", "crypto-neon-fp-armv8",
473 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
|
474 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
475 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
477 ARMCPUTestParams
<uint64_t>("exynos-m3", "armv8-a",
478 "crypto-neon-fp-armv8",
479 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
|
480 ARM::AEK_VIRT
| ARM::AEK_HWDIVARM
|
481 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
483 ARMCPUTestParams
<uint64_t>(
484 "exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8",
485 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
486 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
|
487 ARM::AEK_DOTPROD
| ARM::AEK_FP16
| ARM::AEK_RAS
,
489 ARMCPUTestParams
<uint64_t>(
490 "exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
491 ARM::AEK_CRC
| ARM::AEK_SEC
| ARM::AEK_MP
| ARM::AEK_VIRT
|
492 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
|
493 ARM::AEK_DOTPROD
| ARM::AEK_FP16
| ARM::AEK_RAS
,
495 ARMCPUTestParams
<uint64_t>("cortex-m23", "armv8-m.base", "none",
496 ARM::AEK_NONE
| ARM::AEK_HWDIVTHUMB
,
498 ARMCPUTestParams
<uint64_t>("cortex-m33", "armv8-m.main", "fpv5-sp-d16",
499 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
501 ARMCPUTestParams
<uint64_t>("star-mc1", "armv8-m.main", "fpv5-sp-d16",
502 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
504 ARMCPUTestParams
<uint64_t>("cortex-m35p", "armv8-m.main", "fpv5-sp-d16",
505 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
,
507 ARMCPUTestParams
<uint64_t>(
508 "cortex-m55", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
509 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
| ARM::AEK_SIMD
| ARM::AEK_FP
|
510 ARM::AEK_RAS
| ARM::AEK_LOB
| ARM::AEK_FP16
,
512 ARMCPUTestParams
<uint64_t>(
513 "cortex-m85", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
514 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
| ARM::AEK_SIMD
| ARM::AEK_FP
|
515 ARM::AEK_RAS
| ARM::AEK_LOB
| ARM::AEK_FP16
| ARM::AEK_PACBTI
,
517 ARMCPUTestParams
<uint64_t>(
518 "cortex-m52", "armv8.1-m.main", "fp-armv8-fullfp16-d16",
519 ARM::AEK_HWDIVTHUMB
| ARM::AEK_DSP
| ARM::AEK_SIMD
| ARM::AEK_FP
|
520 ARM::AEK_RAS
| ARM::AEK_LOB
| ARM::AEK_FP16
| ARM::AEK_PACBTI
,
522 ARMCPUTestParams
<uint64_t>("iwmmxt", "iwmmxt", "none", ARM::AEK_NONE
,
524 ARMCPUTestParams
<uint64_t>("xscale", "xscale", "none", ARM::AEK_NONE
,
526 ARMCPUTestParams
<uint64_t>("swift", "armv7s", "neon-vfpv4",
527 ARM::AEK_HWDIVARM
| ARM::AEK_HWDIVTHUMB
|
530 ARMCPUTestParams
<uint64_t>::PrintToStringParamName
);
532 static constexpr unsigned NumARMCPUArchs
= 94;
534 TEST(TargetParserTest
, testARMCPUArchList
) {
535 SmallVector
<StringRef
, NumARMCPUArchs
> List
;
536 ARM::fillValidCPUArchList(List
);
538 // No list exists for these in this test suite, so ensure all are
539 // valid, and match the expected 'magic' count.
540 EXPECT_EQ(List
.size(), NumARMCPUArchs
);
541 for (StringRef CPU
: List
) {
542 EXPECT_NE(ARM::parseCPUArch(CPU
), ARM::ArchKind::INVALID
);
546 TEST(TargetParserTest
, testInvalidARMArch
) {
547 auto InvalidArchStrings
= {"armv", "armv99", "noarm"};
548 for (const char *InvalidArch
: InvalidArchStrings
)
549 EXPECT_EQ(ARM::parseArch(InvalidArch
), ARM::ArchKind::INVALID
);
552 bool testARMArch(StringRef Arch
, StringRef DefaultCPU
, StringRef SubArch
,
554 ARM::ArchKind AK
= ARM::parseArch(Arch
);
555 bool Result
= (AK
!= ARM::ArchKind::INVALID
);
556 Result
&= ARM::getDefaultCPU(Arch
) == DefaultCPU
;
557 Result
&= ARM::getSubArch(AK
) == SubArch
;
558 Result
&= (ARM::getArchAttr(AK
) == ArchAttr
);
562 TEST(TargetParserTest
, testARMArch
) {
564 testARMArch("armv4", "strongarm", "v4", ARMBuildAttrs::CPUArch::v4
));
566 testARMArch("armv4t", "arm7tdmi", "v4t", ARMBuildAttrs::CPUArch::v4T
));
568 testARMArch("armv5t", "arm10tdmi", "v5", ARMBuildAttrs::CPUArch::v5T
));
570 testARMArch("armv5te", "arm1022e", "v5e", ARMBuildAttrs::CPUArch::v5TE
));
571 EXPECT_TRUE(testARMArch("armv5tej", "arm926ej-s", "v5e",
572 ARMBuildAttrs::CPUArch::v5TEJ
));
574 testARMArch("armv6", "arm1136jf-s", "v6", ARMBuildAttrs::CPUArch::v6
));
576 testARMArch("armv6k", "mpcore", "v6k", ARMBuildAttrs::CPUArch::v6K
));
577 EXPECT_TRUE(testARMArch("armv6t2", "arm1156t2-s", "v6t2",
578 ARMBuildAttrs::CPUArch::v6T2
));
579 EXPECT_TRUE(testARMArch("armv6kz", "arm1176jzf-s", "v6kz",
580 ARMBuildAttrs::CPUArch::v6KZ
));
582 testARMArch("armv6-m", "cortex-m0", "v6m", ARMBuildAttrs::CPUArch::v6_M
));
584 testARMArch("armv7-a", "generic", "v7", ARMBuildAttrs::CPUArch::v7
));
586 testARMArch("armv7ve", "generic", "v7ve", ARMBuildAttrs::CPUArch::v7
));
588 testARMArch("armv7-r", "cortex-r4", "v7r", ARMBuildAttrs::CPUArch::v7
));
590 testARMArch("armv7-m", "cortex-m3", "v7m", ARMBuildAttrs::CPUArch::v7
));
591 EXPECT_TRUE(testARMArch("armv7e-m", "cortex-m4", "v7em",
592 ARMBuildAttrs::CPUArch::v7E_M
));
594 testARMArch("armv8-a", "generic", "v8a", ARMBuildAttrs::CPUArch::v8_A
));
595 EXPECT_TRUE(testARMArch("armv8.1-a", "generic", "v8.1a",
596 ARMBuildAttrs::CPUArch::v8_A
));
597 EXPECT_TRUE(testARMArch("armv8.2-a", "generic", "v8.2a",
598 ARMBuildAttrs::CPUArch::v8_A
));
599 EXPECT_TRUE(testARMArch("armv8.3-a", "generic", "v8.3a",
600 ARMBuildAttrs::CPUArch::v8_A
));
601 EXPECT_TRUE(testARMArch("armv8.4-a", "generic", "v8.4a",
602 ARMBuildAttrs::CPUArch::v8_A
));
603 EXPECT_TRUE(testARMArch("armv8.5-a", "generic", "v8.5a",
604 ARMBuildAttrs::CPUArch::v8_A
));
605 EXPECT_TRUE(testARMArch("armv8.6-a", "generic", "v8.6a",
606 ARMBuildAttrs::CPUArch::v8_A
));
607 EXPECT_TRUE(testARMArch("armv8.7-a", "generic", "v8.7a",
608 ARMBuildAttrs::CPUArch::v8_A
));
609 EXPECT_TRUE(testARMArch("armv8.8-a", "generic", "v8.8a",
610 ARMBuildAttrs::CPUArch::v8_A
));
611 EXPECT_TRUE(testARMArch("armv8.9-a", "generic", "v8.9a",
612 ARMBuildAttrs::CPUArch::v8_A
));
614 testARMArch("armv9-a", "generic", "v9a", ARMBuildAttrs::CPUArch::v9_A
));
615 EXPECT_TRUE(testARMArch("armv9.1-a", "generic", "v9.1a",
616 ARMBuildAttrs::CPUArch::v9_A
));
617 EXPECT_TRUE(testARMArch("armv9.2-a", "generic", "v9.2a",
618 ARMBuildAttrs::CPUArch::v9_A
));
619 EXPECT_TRUE(testARMArch("armv9.3-a", "generic", "v9.3a",
620 ARMBuildAttrs::CPUArch::v9_A
));
621 EXPECT_TRUE(testARMArch("armv9.4-a", "generic", "v9.4a",
622 ARMBuildAttrs::CPUArch::v9_A
));
623 EXPECT_TRUE(testARMArch("armv9.5-a", "generic", "v9.5a",
624 ARMBuildAttrs::CPUArch::v9_A
));
625 EXPECT_TRUE(testARMArch("armv9.6-a", "generic", "v9.6a",
626 ARMBuildAttrs::CPUArch::v9_A
));
628 testARMArch("armv8-r", "generic", "v8r", ARMBuildAttrs::CPUArch::v8_R
));
629 EXPECT_TRUE(testARMArch("armv8-m.base", "generic", "v8m.base",
630 ARMBuildAttrs::CPUArch::v8_M_Base
));
631 EXPECT_TRUE(testARMArch("armv8-m.main", "generic", "v8m.main",
632 ARMBuildAttrs::CPUArch::v8_M_Main
));
633 EXPECT_TRUE(testARMArch("armv8.1-m.main", "generic", "v8.1m.main",
634 ARMBuildAttrs::CPUArch::v8_1_M_Main
));
636 testARMArch("iwmmxt", "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE
));
638 testARMArch("iwmmxt2", "generic", "", ARMBuildAttrs::CPUArch::v5TE
));
640 testARMArch("xscale", "xscale", "v5e", ARMBuildAttrs::CPUArch::v5TE
));
642 testARMArch("armv7s", "swift", "v7s", ARMBuildAttrs::CPUArch::v7
));
644 testARMArch("armv7k", "generic", "v7k", ARMBuildAttrs::CPUArch::v7
));
647 bool testARMExtension(StringRef CPUName
, ARM::ArchKind ArchKind
,
649 return ARM::getDefaultExtensions(CPUName
, ArchKind
) &
650 ARM::parseArchExt(ArchExt
);
653 TEST(TargetParserTest
, testARMExtension
) {
654 EXPECT_FALSE(testARMExtension("strongarm", ARM::ArchKind::INVALID
, "dsp"));
655 EXPECT_FALSE(testARMExtension("arm7tdmi", ARM::ArchKind::INVALID
, "dsp"));
656 EXPECT_FALSE(testARMExtension("arm10tdmi", ARM::ArchKind::INVALID
, "simd"));
657 EXPECT_FALSE(testARMExtension("arm1022e", ARM::ArchKind::INVALID
, "simd"));
658 EXPECT_FALSE(testARMExtension("arm926ej-s", ARM::ArchKind::INVALID
, "simd"));
660 testARMExtension("arm1136jf-s", ARM::ArchKind::INVALID
, "crypto"));
662 testARMExtension("arm1156t2-s", ARM::ArchKind::INVALID
, "crypto"));
664 testARMExtension("arm1176jzf-s", ARM::ArchKind::INVALID
, "crypto"));
665 EXPECT_FALSE(testARMExtension("cortex-m0", ARM::ArchKind::INVALID
, "crypto"));
666 EXPECT_FALSE(testARMExtension("cortex-a8", ARM::ArchKind::INVALID
, "crypto"));
667 EXPECT_FALSE(testARMExtension("cortex-r4", ARM::ArchKind::INVALID
, "crypto"));
668 EXPECT_FALSE(testARMExtension("cortex-m3", ARM::ArchKind::INVALID
, "crypto"));
669 EXPECT_FALSE(testARMExtension("cortex-a53", ARM::ArchKind::INVALID
, "ras"));
670 EXPECT_FALSE(testARMExtension("cortex-a53", ARM::ArchKind::INVALID
, "fp16"));
671 EXPECT_TRUE(testARMExtension("cortex-a55", ARM::ArchKind::INVALID
, "fp16"));
673 testARMExtension("cortex-a55", ARM::ArchKind::INVALID
, "fp16fml"));
674 EXPECT_TRUE(testARMExtension("cortex-a75", ARM::ArchKind::INVALID
, "fp16"));
676 testARMExtension("cortex-a75", ARM::ArchKind::INVALID
, "fp16fml"));
677 EXPECT_FALSE(testARMExtension("cortex-r52", ARM::ArchKind::INVALID
, "ras"));
679 testARMExtension("cortex-r52plus", ARM::ArchKind::INVALID
, "ras"));
680 EXPECT_FALSE(testARMExtension("iwmmxt", ARM::ArchKind::INVALID
, "crc"));
681 EXPECT_FALSE(testARMExtension("xscale", ARM::ArchKind::INVALID
, "crc"));
682 EXPECT_FALSE(testARMExtension("swift", ARM::ArchKind::INVALID
, "crc"));
684 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4
, "dsp"));
685 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4T
, "dsp"));
686 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5T
, "simd"));
687 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TE
, "simd"));
688 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TEJ
, "simd"));
689 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6
, "crypto"));
690 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6K
, "crypto"));
691 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6T2
, "crypto"));
692 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6KZ
, "crypto"));
693 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6M
, "crypto"));
694 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7A
, "crypto"));
695 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7R
, "crypto"));
696 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7M
, "crypto"));
697 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7EM
, "crypto"));
698 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8A
, "ras"));
699 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_1A
, "ras"));
700 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A
, "profile"));
701 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A
, "fp16"));
702 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A
, "fp16fml"));
703 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A
, "fp16"));
704 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A
, "fp16fml"));
705 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A
, "fp16"));
706 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A
, "fp16fml"));
707 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8R
, "ras"));
709 testARMExtension("generic", ARM::ArchKind::ARMV8MBaseline
, "crc"));
711 testARMExtension("generic", ARM::ArchKind::ARMV8MMainline
, "crc"));
712 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT
, "crc"));
713 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT2
, "crc"));
714 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::XSCALE
, "crc"));
715 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7S
, "crypto"));
716 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7K
, "crypto"));
719 TEST(TargetParserTest
, ARMFPUVersion
) {
720 for (ARM::FPUKind FK
= static_cast<ARM::FPUKind
>(0);
721 FK
<= ARM::FPUKind::FK_LAST
;
722 FK
= static_cast<ARM::FPUKind
>(static_cast<unsigned>(FK
) + 1))
723 if (FK
== ARM::FK_LAST
|| ARM::getFPUName(FK
) == "invalid" ||
724 ARM::getFPUName(FK
) == "none" || ARM::getFPUName(FK
) == "softvfp")
725 EXPECT_EQ(ARM::FPUVersion::NONE
, ARM::getFPUVersion(FK
));
727 EXPECT_NE(ARM::FPUVersion::NONE
, ARM::getFPUVersion(FK
));
730 TEST(TargetParserTest
, ARMFPUNeonSupportLevel
) {
731 for (ARM::FPUKind FK
= static_cast<ARM::FPUKind
>(0);
732 FK
<= ARM::FPUKind::FK_LAST
;
733 FK
= static_cast<ARM::FPUKind
>(static_cast<unsigned>(FK
) + 1))
734 if (FK
== ARM::FK_LAST
||
735 ARM::getFPUName(FK
).find("neon") == std::string::npos
)
736 EXPECT_EQ(ARM::NeonSupportLevel::None
, ARM::getFPUNeonSupportLevel(FK
));
738 EXPECT_NE(ARM::NeonSupportLevel::None
, ARM::getFPUNeonSupportLevel(FK
));
741 TEST(TargetParserTest
, ARMFPURestriction
) {
742 for (ARM::FPUKind FK
= static_cast<ARM::FPUKind
>(0);
743 FK
<= ARM::FPUKind::FK_LAST
;
744 FK
= static_cast<ARM::FPUKind
>(static_cast<unsigned>(FK
) + 1)) {
745 if (FK
== ARM::FK_LAST
||
746 (ARM::getFPUName(FK
).find("d16") == std::string::npos
&&
747 ARM::getFPUName(FK
).find("vfpv3xd") == std::string::npos
))
748 EXPECT_EQ(ARM::FPURestriction::None
, ARM::getFPURestriction(FK
));
750 EXPECT_NE(ARM::FPURestriction::None
, ARM::getFPURestriction(FK
));
754 TEST(TargetParserTest
, ARMExtensionFeatures
) {
755 std::map
<uint64_t, std::vector
<StringRef
>> Extensions
;
757 for (auto &Ext
: ARM::ARCHExtNames
) {
758 if (!Ext
.Feature
.empty() && !Ext
.NegFeature
.empty())
759 Extensions
[Ext
.ID
] = {Ext
.Feature
, Ext
.NegFeature
};
762 Extensions
[ARM::AEK_HWDIVARM
] = {"+hwdiv-arm", "-hwdiv-arm"};
763 Extensions
[ARM::AEK_HWDIVTHUMB
] = {"+hwdiv", "-hwdiv"};
765 std::vector
<StringRef
> Features
;
767 EXPECT_FALSE(ARM::getExtensionFeatures(ARM::AEK_INVALID
, Features
));
769 for (auto &E
: Extensions
) {
772 ARM::getExtensionFeatures(E
.first
, Features
);
773 EXPECT_TRUE(llvm::is_contained(Features
, E
.second
.at(0)));
774 EXPECT_EQ(Extensions
.size(), Features
.size());
778 ARM::getExtensionFeatures(~E
.first
, Features
);
779 EXPECT_TRUE(llvm::is_contained(Features
, E
.second
.at(1)));
780 EXPECT_EQ(Extensions
.size(), Features
.size());
784 TEST(TargetParserTest
, ARMFPUFeatures
) {
785 std::vector
<StringRef
> Features
;
786 for (ARM::FPUKind FK
= static_cast<ARM::FPUKind
>(0);
787 FK
<= ARM::FPUKind::FK_LAST
;
788 FK
= static_cast<ARM::FPUKind
>(static_cast<unsigned>(FK
) + 1)) {
789 if (FK
== ARM::FK_INVALID
|| FK
>= ARM::FK_LAST
)
790 EXPECT_FALSE(ARM::getFPUFeatures(FK
, Features
));
792 EXPECT_TRUE(ARM::getFPUFeatures(FK
, Features
));
796 TEST(TargetParserTest
, ARMArchExtFeature
) {
797 const char *ArchExt
[][4] = {{"crc", "nocrc", "+crc", "-crc"},
798 {"crypto", "nocrypto", "+crypto", "-crypto"},
799 {"dsp", "nodsp", "+dsp", "-dsp"},
800 {"fp", "nofp", nullptr, nullptr},
801 {"idiv", "noidiv", nullptr, nullptr},
802 {"mp", "nomp", nullptr, nullptr},
803 {"simd", "nosimd", nullptr, nullptr},
804 {"sec", "nosec", nullptr, nullptr},
805 {"virt", "novirt", nullptr, nullptr},
806 {"fp16", "nofp16", "+fullfp16", "-fullfp16"},
807 {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"},
808 {"ras", "noras", "+ras", "-ras"},
809 {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
810 {"os", "noos", nullptr, nullptr},
811 {"iwmmxt", "noiwmmxt", nullptr, nullptr},
812 {"iwmmxt2", "noiwmmxt2", nullptr, nullptr},
813 {"maverick", "maverick", nullptr, nullptr},
814 {"xscale", "noxscale", nullptr, nullptr},
815 {"sb", "nosb", "+sb", "-sb"},
816 {"i8mm", "noi8mm", "+i8mm", "-i8mm"},
817 {"mve", "nomve", "+mve", "-mve"},
818 {"mve.fp", "nomve.fp", "+mve.fp", "-mve.fp"}};
820 for (unsigned i
= 0; i
< std::size(ArchExt
); i
++) {
821 EXPECT_EQ(StringRef(ArchExt
[i
][2]), ARM::getArchExtFeature(ArchExt
[i
][0]));
822 EXPECT_EQ(StringRef(ArchExt
[i
][3]), ARM::getArchExtFeature(ArchExt
[i
][1]));
827 testArchExtDependency(const char *ArchExt
,
828 const std::initializer_list
<const char *> &Expected
) {
829 std::vector
<StringRef
> Features
;
830 ARM::FPUKind FPUKind
;
832 if (!ARM::appendArchExtFeatures("", ARM::ArchKind::ARMV8_1MMainline
, ArchExt
,
836 return llvm::all_of(Expected
, [&](StringRef Ext
) {
837 return llvm::is_contained(Features
, Ext
);
841 TEST(TargetParserTest
, ARMArchExtDependencies
) {
842 EXPECT_TRUE(testArchExtDependency("mve", {"+mve", "+dsp"}));
843 EXPECT_TRUE(testArchExtDependency("mve.fp", {"+mve.fp", "+mve", "+dsp"}));
844 EXPECT_TRUE(testArchExtDependency("nodsp", {"-dsp", "-mve", "-mve.fp"}));
845 EXPECT_TRUE(testArchExtDependency("nomve", {"-mve", "-mve.fp"}));
848 TEST(TargetParserTest
, ARMparseHWDiv
) {
849 const char *hwdiv
[] = {"thumb", "arm", "arm,thumb", "thumb,arm"};
851 for (unsigned i
= 0; i
< std::size(hwdiv
); i
++)
852 EXPECT_NE(ARM::AEK_INVALID
, ARM::parseHWDiv((StringRef
)hwdiv
[i
]));
855 TEST(TargetParserTest
, ARMparseArchEndianAndISA
) {
856 const char *Arch
[] = {
857 "v2", "v2a", "v3", "v3m", "v4", "v4t",
858 "v5", "v5t", "v5e", "v5te", "v5tej", "v6",
859 "v6j", "v6k", "v6hl", "v6t2", "v6kz", "v6z",
860 "v6zk", "v6-m", "v6m", "v6sm", "v6s-m", "v7-a",
861 "v7", "v7a", "v7ve", "v7hl", "v7l", "v7-r",
862 "v7r", "v7-m", "v7m", "v7k", "v7s", "v7e-m",
863 "v7em", "v8-a", "v8", "v8a", "v8l", "v8.1-a",
864 "v8.1a", "v8.2-a", "v8.2a", "v8.3-a", "v8.3a", "v8.4-a",
865 "v8.4a", "v8.5-a", "v8.5a", "v8.6-a", "v8.6a", "v8.7-a",
866 "v8.7a", "v8.8-a", "v8.8a", "v8-r", "v8m.base", "v8m.main",
869 for (unsigned i
= 0; i
< std::size(Arch
); i
++) {
870 std::string arm_1
= "armeb" + (std::string
)(Arch
[i
]);
871 std::string arm_2
= "arm" + (std::string
)(Arch
[i
]) + "eb";
872 std::string arm_3
= "arm" + (std::string
)(Arch
[i
]);
873 std::string thumb_1
= "thumbeb" + (std::string
)(Arch
[i
]);
874 std::string thumb_2
= "thumb" + (std::string
)(Arch
[i
]) + "eb";
875 std::string thumb_3
= "thumb" + (std::string
)(Arch
[i
]);
877 EXPECT_EQ(ARM::EndianKind::BIG
, ARM::parseArchEndian(arm_1
));
878 EXPECT_EQ(ARM::EndianKind::BIG
, ARM::parseArchEndian(arm_2
));
879 EXPECT_EQ(ARM::EndianKind::LITTLE
, ARM::parseArchEndian(arm_3
));
881 EXPECT_EQ(ARM::ISAKind::ARM
, ARM::parseArchISA(arm_1
));
882 EXPECT_EQ(ARM::ISAKind::ARM
, ARM::parseArchISA(arm_2
));
883 EXPECT_EQ(ARM::ISAKind::ARM
, ARM::parseArchISA(arm_3
));
885 EXPECT_EQ(ARM::EndianKind::BIG
, ARM::parseArchEndian(thumb_1
));
886 EXPECT_EQ(ARM::EndianKind::BIG
, ARM::parseArchEndian(thumb_2
));
887 EXPECT_EQ(ARM::EndianKind::LITTLE
, ARM::parseArchEndian(thumb_3
));
889 EXPECT_EQ(ARM::ISAKind::THUMB
, ARM::parseArchISA(thumb_1
));
890 EXPECT_EQ(ARM::ISAKind::THUMB
, ARM::parseArchISA(thumb_2
));
891 EXPECT_EQ(ARM::ISAKind::THUMB
, ARM::parseArchISA(thumb_3
));
895 EXPECT_EQ(ARM::EndianKind::LITTLE
, ARM::parseArchEndian("aarch64"));
896 EXPECT_EQ(ARM::EndianKind::LITTLE
, ARM::parseArchEndian("arm64_32"));
897 EXPECT_EQ(ARM::EndianKind::BIG
, ARM::parseArchEndian("aarch64_be"));
899 EXPECT_EQ(ARM::ISAKind::AARCH64
, ARM::parseArchISA("aarch64"));
900 EXPECT_EQ(ARM::ISAKind::AARCH64
, ARM::parseArchISA("aarch64_be"));
901 EXPECT_EQ(ARM::ISAKind::AARCH64
, ARM::parseArchISA("arm64"));
902 EXPECT_EQ(ARM::ISAKind::AARCH64
, ARM::parseArchISA("arm64_be"));
903 EXPECT_EQ(ARM::ISAKind::AARCH64
, ARM::parseArchISA("arm64_32"));
904 EXPECT_EQ(ARM::ISAKind::AARCH64
, ARM::parseArchISA("aarch64_32"));
907 TEST(TargetParserTest
, ARMparseArchProfile
) {
908 for (unsigned i
= 0; i
< std::size(ARMArch
); i
++) {
909 switch (ARM::parseArch(ARMArch
[i
])) {
910 case ARM::ArchKind::ARMV6M
:
911 case ARM::ArchKind::ARMV7M
:
912 case ARM::ArchKind::ARMV7EM
:
913 case ARM::ArchKind::ARMV8MMainline
:
914 case ARM::ArchKind::ARMV8MBaseline
:
915 case ARM::ArchKind::ARMV8_1MMainline
:
916 EXPECT_EQ(ARM::ProfileKind::M
, ARM::parseArchProfile(ARMArch
[i
]));
918 case ARM::ArchKind::ARMV7R
:
919 case ARM::ArchKind::ARMV8R
:
920 EXPECT_EQ(ARM::ProfileKind::R
, ARM::parseArchProfile(ARMArch
[i
]));
922 case ARM::ArchKind::ARMV7A
:
923 case ARM::ArchKind::ARMV7VE
:
924 case ARM::ArchKind::ARMV7K
:
925 case ARM::ArchKind::ARMV8A
:
926 case ARM::ArchKind::ARMV8_1A
:
927 case ARM::ArchKind::ARMV8_2A
:
928 case ARM::ArchKind::ARMV8_3A
:
929 case ARM::ArchKind::ARMV8_4A
:
930 case ARM::ArchKind::ARMV8_5A
:
931 case ARM::ArchKind::ARMV8_6A
:
932 case ARM::ArchKind::ARMV8_7A
:
933 case ARM::ArchKind::ARMV8_8A
:
934 case ARM::ArchKind::ARMV8_9A
:
935 case ARM::ArchKind::ARMV9A
:
936 case ARM::ArchKind::ARMV9_1A
:
937 case ARM::ArchKind::ARMV9_2A
:
938 case ARM::ArchKind::ARMV9_3A
:
939 case ARM::ArchKind::ARMV9_4A
:
940 case ARM::ArchKind::ARMV9_5A
:
941 case ARM::ArchKind::ARMV9_6A
:
942 EXPECT_EQ(ARM::ProfileKind::A
, ARM::parseArchProfile(ARMArch
[i
]));
945 EXPECT_EQ(ARM::ProfileKind::INVALID
, ARM::parseArchProfile(ARMArch
[i
]));
951 TEST(TargetParserTest
, ARMparseArchVersion
) {
952 for (unsigned i
= 0; i
< std::size(ARMArch
); i
++)
953 if (((std::string
)ARMArch
[i
]).substr(0, 4) == "armv")
954 EXPECT_EQ((ARMArch
[i
][4] - 48u), ARM::parseArchVersion(ARMArch
[i
]));
956 EXPECT_EQ(5u, ARM::parseArchVersion(ARMArch
[i
]));
959 TEST(TargetParserTest
, getARMCPUForArch
) {
960 // Platform specific defaults.
962 llvm::Triple
Triple("arm--nacl");
963 EXPECT_EQ("cortex-a8", ARM::getARMCPUForArch(Triple
));
966 llvm::Triple
Triple("arm--openbsd");
967 EXPECT_EQ("cortex-a8", ARM::getARMCPUForArch(Triple
));
970 llvm::Triple
Triple("armv6-unknown-freebsd");
971 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple
));
974 llvm::Triple
Triple("thumbv6-unknown-freebsd");
975 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple
));
978 llvm::Triple
Triple("armebv6-unknown-freebsd");
979 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple
));
982 llvm::Triple
Triple("arm--win32");
983 EXPECT_EQ("cortex-a9", ARM::getARMCPUForArch(Triple
));
984 EXPECT_EQ("generic", ARM::getARMCPUForArch(Triple
, "armv8-a"));
986 // Some alternative architectures
988 llvm::Triple
Triple("armv7k-apple-ios9");
989 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple
));
992 llvm::Triple
Triple("armv7k-apple-watchos3");
993 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple
));
996 llvm::Triple
Triple("armv7k-apple-tvos9");
997 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple
));
999 // armeb is permitted, but armebeb is not
1001 llvm::Triple
Triple("armeb-none-eabi");
1002 EXPECT_EQ("arm7tdmi", ARM::getARMCPUForArch(Triple
));
1005 llvm::Triple
Triple("armebeb-none-eabi");
1006 EXPECT_EQ("", ARM::getARMCPUForArch(Triple
));
1009 llvm::Triple
Triple("armebv6eb-none-eabi");
1010 EXPECT_EQ("", ARM::getARMCPUForArch(Triple
));
1012 // xscaleeb is permitted, but armebxscale is not
1014 llvm::Triple
Triple("xscaleeb-none-eabi");
1015 EXPECT_EQ("xscale", ARM::getARMCPUForArch(Triple
));
1018 llvm::Triple
Triple("armebxscale-none-eabi");
1019 EXPECT_EQ("", ARM::getARMCPUForArch(Triple
));
1023 TEST(TargetParserTest
, ARMPrintSupportedExtensions
) {
1024 std::string expected
=
1025 "All available -march extensions for ARM\n\n"
1026 " Name Description\n"
1027 " crc This is a long dummy description\n"
1031 StringMap
<StringRef
> DummyMap
;
1032 DummyMap
["crc"] = "This is a long dummy description";
1035 testing::internal::CaptureStdout();
1036 ARM::PrintSupportedExtensions(DummyMap
);
1038 std::string captured
= testing::internal::GetCapturedStdout();
1040 // Check that the start of the output is as expected.
1041 EXPECT_EQ(0ULL, captured
.find(expected
));
1043 // Should not include "none" or "invalid".
1044 EXPECT_EQ(std::string::npos
, captured
.find("none"));
1045 EXPECT_EQ(std::string::npos
, captured
.find("invalid"));
1046 // Should not include anything that lacks a feature name. Checking a few here
1047 // but not all as if one is hidden correctly the rest should be.
1048 EXPECT_EQ(std::string::npos
, captured
.find("simd"));
1049 EXPECT_EQ(std::string::npos
, captured
.find("maverick"));
1050 EXPECT_EQ(std::string::npos
, captured
.find("xscale"));
1053 struct AArch64CPUTestParams
1054 : public ARMCPUTestParams
<AArch64::ExtensionBitset
> {
1055 AArch64CPUTestParams(StringRef CPUName
, StringRef ExpectedArch
)
1056 : ARMCPUTestParams
<AArch64::ExtensionBitset
>(CPUName
, ExpectedArch
,
1059 /// Print a gtest-compatible facsimile of the CPUName, to make the test's name
1062 /// https://github.com/google/googletest/blob/main/docs/advanced.md#specifying-names-for-value-parameterized-test-parameters
1063 static std::string
PrintToStringParamName(
1064 const testing::TestParamInfo
<AArch64CPUTestParams
> &Info
) {
1065 std::string Name
= Info
.param
.CPUName
.str();
1066 for (char &C
: Name
)
1067 if (!std::isalnum(C
))
1073 class AArch64CPUTestFixture
1074 : public ::testing::TestWithParam
<AArch64CPUTestParams
> {};
1076 TEST_P(AArch64CPUTestFixture
, testAArch64CPU
) {
1077 auto params
= GetParam();
1079 const std::optional
<AArch64::CpuInfo
> Cpu
= AArch64::parseCpu(params
.CPUName
);
1081 EXPECT_EQ(params
.ExpectedArch
, Cpu
->Arch
.Name
);
1084 INSTANTIATE_TEST_SUITE_P(
1085 AArch64CPUTests
, AArch64CPUTestFixture
,
1086 ::testing::Values(AArch64CPUTestParams("cortex-a34", "armv8-a"),
1087 AArch64CPUTestParams("cortex-a35", "armv8-a"),
1088 AArch64CPUTestParams("cortex-a53", "armv8-a"),
1089 AArch64CPUTestParams("cortex-a55", "armv8.2-a"),
1090 AArch64CPUTestParams("cortex-a510", "armv9-a"),
1091 AArch64CPUTestParams("cortex-a520", "armv9.2-a"),
1092 AArch64CPUTestParams("cortex-a520ae", "armv9.2-a"),
1093 AArch64CPUTestParams("cortex-a57", "armv8-a"),
1094 AArch64CPUTestParams("cortex-a65", "armv8.2-a"),
1095 AArch64CPUTestParams("cortex-a65ae", "armv8.2-a"),
1096 AArch64CPUTestParams("cortex-a72", "armv8-a"),
1097 AArch64CPUTestParams("cortex-a73", "armv8-a"),
1098 AArch64CPUTestParams("cortex-a75", "armv8.2-a"),
1099 AArch64CPUTestParams("cortex-a76", "armv8.2-a"),
1100 AArch64CPUTestParams("cortex-a76ae", "armv8.2-a"),
1101 AArch64CPUTestParams("cortex-a77", "armv8.2-a"),
1102 AArch64CPUTestParams("cortex-a78", "armv8.2-a"),
1103 AArch64CPUTestParams("cortex-a78ae", "armv8.2-a"),
1104 AArch64CPUTestParams("cortex-a78c", "armv8.2-a"),
1105 AArch64CPUTestParams("cortex-a710", "armv9-a"),
1106 AArch64CPUTestParams("cortex-a715", "armv9-a"),
1107 AArch64CPUTestParams("cortex-a720", "armv9.2-a"),
1108 AArch64CPUTestParams("cortex-a720ae", "armv9.2-a"),
1109 AArch64CPUTestParams("cortex-a725", "armv9.2-a"),
1110 AArch64CPUTestParams("neoverse-v1", "armv8.4-a"),
1111 AArch64CPUTestParams("neoverse-v2", "armv9-a"),
1112 AArch64CPUTestParams("neoverse-v3", "armv9.2-a"),
1113 AArch64CPUTestParams("neoverse-v3ae", "armv9.2-a"),
1114 AArch64CPUTestParams("cortex-r82", "armv8-r"),
1115 AArch64CPUTestParams("cortex-r82ae", "armv8-r"),
1116 AArch64CPUTestParams("cortex-x1", "armv8.2-a"),
1117 AArch64CPUTestParams("cortex-x1c", "armv8.2-a"),
1118 AArch64CPUTestParams("cortex-x2", "armv9-a"),
1119 AArch64CPUTestParams("cortex-x3", "armv9-a"),
1120 AArch64CPUTestParams("cortex-x4", "armv9.2-a"),
1121 AArch64CPUTestParams("cortex-x925", "armv9.2-a"),
1122 AArch64CPUTestParams("cyclone", "armv8-a"),
1123 AArch64CPUTestParams("apple-a7", "armv8-a"),
1124 AArch64CPUTestParams("apple-a8", "armv8-a"),
1125 AArch64CPUTestParams("apple-a9", "armv8-a"),
1126 AArch64CPUTestParams("apple-a10", "armv8-a"),
1127 AArch64CPUTestParams("apple-a11", "armv8.2-a"),
1128 AArch64CPUTestParams("apple-a12", "armv8.3-a"),
1129 AArch64CPUTestParams("apple-s4", "armv8.3-a"),
1130 AArch64CPUTestParams("apple-s5", "armv8.3-a"),
1131 AArch64CPUTestParams("apple-a13", "armv8.4-a"),
1132 AArch64CPUTestParams("apple-a14", "armv8.4-a"),
1133 AArch64CPUTestParams("apple-m1", "armv8.4-a"),
1134 AArch64CPUTestParams("apple-a15", "armv8.6-a"),
1135 AArch64CPUTestParams("apple-m2", "armv8.6-a"),
1136 AArch64CPUTestParams("apple-a16", "armv8.6-a"),
1137 AArch64CPUTestParams("apple-m3", "armv8.6-a"),
1138 AArch64CPUTestParams("apple-a17", "armv8.6-a"),
1139 AArch64CPUTestParams("apple-m4", "armv8.7-a"),
1140 AArch64CPUTestParams("exynos-m3", "armv8-a"),
1141 AArch64CPUTestParams("exynos-m4", "armv8.2-a"),
1142 AArch64CPUTestParams("exynos-m5", "armv8.2-a"),
1143 AArch64CPUTestParams("falkor", "armv8-a"),
1144 AArch64CPUTestParams("kryo", "armv8-a"),
1145 AArch64CPUTestParams("neoverse-e1", "armv8.2-a"),
1146 AArch64CPUTestParams("neoverse-n1", "armv8.2-a"),
1147 AArch64CPUTestParams("neoverse-n2", "armv9-a"),
1148 AArch64CPUTestParams("neoverse-n3", "armv9.2-a"),
1149 AArch64CPUTestParams("ampere1", "armv8.6-a"),
1150 AArch64CPUTestParams("ampere1a", "armv8.6-a"),
1151 AArch64CPUTestParams("ampere1b", "armv8.7-a"),
1152 AArch64CPUTestParams("neoverse-512tvb", "armv8.4-a"),
1153 AArch64CPUTestParams("thunderx2t99", "armv8.1-a"),
1154 AArch64CPUTestParams("thunderx3t110", "armv8.3-a"),
1155 AArch64CPUTestParams("thunderx", "armv8-a"),
1156 AArch64CPUTestParams("thunderxt81", "armv8-a"),
1157 AArch64CPUTestParams("thunderxt83", "armv8-a"),
1158 AArch64CPUTestParams("thunderxt88", "armv8-a"),
1159 AArch64CPUTestParams("tsv110", "armv8.2-a"),
1160 AArch64CPUTestParams("a64fx", "armv8.2-a"),
1161 AArch64CPUTestParams("fujitsu-monaka", "armv9.3-a"),
1162 AArch64CPUTestParams("carmel", "armv8.2-a"),
1163 AArch64CPUTestParams("saphira", "armv8.4-a"),
1164 AArch64CPUTestParams("oryon-1", "armv8.6-a")),
1165 AArch64CPUTestParams::PrintToStringParamName
);
1167 // Note: number of CPUs includes aliases.
1168 static constexpr unsigned NumAArch64CPUArchs
= 82;
1170 TEST(TargetParserTest
, testAArch64CPUArchList
) {
1171 SmallVector
<StringRef
, NumAArch64CPUArchs
> List
;
1172 AArch64::fillValidCPUArchList(List
);
1174 // No list exists for these in this test suite, so ensure all are
1175 // valid, and match the expected 'magic' count.
1176 EXPECT_EQ(List
.size(), NumAArch64CPUArchs
);
1177 for (StringRef CPU
: List
) {
1178 EXPECT_TRUE(AArch64::parseCpu(CPU
));
1182 bool testAArch64Arch(StringRef Arch
) {
1183 const AArch64::ArchInfo
*AI
= AArch64::parseArch(Arch
);
1184 return AI
!= nullptr;
1187 TEST(TargetParserTest
, testAArch64Arch
) {
1188 EXPECT_TRUE(testAArch64Arch("armv8-a"));
1189 EXPECT_TRUE(testAArch64Arch("armv8.1-a"));
1190 EXPECT_TRUE(testAArch64Arch("armv8.2-a"));
1191 EXPECT_TRUE(testAArch64Arch("armv8.3-a"));
1192 EXPECT_TRUE(testAArch64Arch("armv8.4-a"));
1193 EXPECT_TRUE(testAArch64Arch("armv8.5-a"));
1194 EXPECT_TRUE(testAArch64Arch("armv8.6-a"));
1195 EXPECT_TRUE(testAArch64Arch("armv8.7-a"));
1196 EXPECT_TRUE(testAArch64Arch("armv8.8-a"));
1197 EXPECT_TRUE(testAArch64Arch("armv8.9-a"));
1198 EXPECT_TRUE(testAArch64Arch("armv9-a"));
1199 EXPECT_TRUE(testAArch64Arch("armv9.1-a"));
1200 EXPECT_TRUE(testAArch64Arch("armv9.2-a"));
1201 EXPECT_TRUE(testAArch64Arch("armv9.3-a"));
1202 EXPECT_TRUE(testAArch64Arch("armv9.4-a"));
1203 EXPECT_TRUE(testAArch64Arch("armv9.5-a"));
1204 EXPECT_TRUE(testAArch64Arch("armv9.6-a"));
1207 bool testAArch64Extension(StringRef CPUName
, StringRef ArchExt
) {
1208 std::optional
<AArch64::ExtensionInfo
> Extension
=
1209 AArch64::parseArchExtension(ArchExt
);
1212 std::optional
<AArch64::CpuInfo
> CpuInfo
= AArch64::parseCpu(CPUName
);
1213 return CpuInfo
->getImpliedExtensions().test(Extension
->ID
);
1216 bool testAArch64Extension(const AArch64::ArchInfo
&AI
, StringRef ArchExt
) {
1217 std::optional
<AArch64::ExtensionInfo
> Extension
=
1218 AArch64::parseArchExtension(ArchExt
);
1221 return AI
.DefaultExts
.test(Extension
->ID
);
1224 TEST(TargetParserTest
, testAArch64Extension
) {
1225 EXPECT_FALSE(testAArch64Extension("cortex-a34", "ras"));
1226 EXPECT_FALSE(testAArch64Extension("cortex-a35", "ras"));
1227 EXPECT_FALSE(testAArch64Extension("cortex-a53", "ras"));
1228 EXPECT_TRUE(testAArch64Extension("cortex-a55", "ras"));
1229 EXPECT_TRUE(testAArch64Extension("cortex-a55", "fp16"));
1230 EXPECT_FALSE(testAArch64Extension("cortex-a55", "fp16fml"));
1231 EXPECT_TRUE(testAArch64Extension("cortex-a55", "dotprod"));
1232 EXPECT_FALSE(testAArch64Extension("cortex-a57", "ras"));
1233 EXPECT_FALSE(testAArch64Extension("cortex-a72", "ras"));
1234 EXPECT_FALSE(testAArch64Extension("cortex-a73", "ras"));
1235 EXPECT_TRUE(testAArch64Extension("cortex-a75", "ras"));
1236 EXPECT_TRUE(testAArch64Extension("cortex-a75", "fp16"));
1237 EXPECT_FALSE(testAArch64Extension("cortex-a75", "fp16fml"));
1238 EXPECT_TRUE(testAArch64Extension("cortex-a75", "dotprod"));
1239 EXPECT_TRUE(testAArch64Extension("cortex-r82", "ras"));
1240 EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16"));
1241 EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16fml"));
1242 EXPECT_TRUE(testAArch64Extension("cortex-r82", "dotprod"));
1243 EXPECT_TRUE(testAArch64Extension("cortex-r82", "lse"));
1244 EXPECT_FALSE(testAArch64Extension("cyclone", "ras"));
1245 EXPECT_FALSE(testAArch64Extension("exynos-m3", "ras"));
1246 EXPECT_TRUE(testAArch64Extension("exynos-m4", "dotprod"));
1247 EXPECT_TRUE(testAArch64Extension("exynos-m4", "fp16"));
1248 EXPECT_TRUE(testAArch64Extension("exynos-m4", "lse"));
1249 EXPECT_TRUE(testAArch64Extension("exynos-m4", "ras"));
1250 EXPECT_TRUE(testAArch64Extension("exynos-m4", "rdm"));
1251 EXPECT_TRUE(testAArch64Extension("exynos-m5", "dotprod"));
1252 EXPECT_TRUE(testAArch64Extension("exynos-m5", "fp16"));
1253 EXPECT_TRUE(testAArch64Extension("exynos-m5", "lse"));
1254 EXPECT_TRUE(testAArch64Extension("exynos-m5", "ras"));
1255 EXPECT_TRUE(testAArch64Extension("exynos-m5", "rdm"));
1256 EXPECT_TRUE(testAArch64Extension("falkor", "rdm"));
1257 EXPECT_FALSE(testAArch64Extension("kryo", "ras"));
1258 EXPECT_TRUE(testAArch64Extension("saphira", "crc"));
1259 EXPECT_TRUE(testAArch64Extension("saphira", "lse"));
1260 EXPECT_TRUE(testAArch64Extension("saphira", "rdm"));
1261 EXPECT_TRUE(testAArch64Extension("saphira", "ras"));
1262 EXPECT_TRUE(testAArch64Extension("saphira", "rcpc"));
1263 EXPECT_TRUE(testAArch64Extension("saphira", "profile"));
1264 EXPECT_FALSE(testAArch64Extension("saphira", "fp16"));
1265 EXPECT_FALSE(testAArch64Extension("thunderx2t99", "ras"));
1266 EXPECT_FALSE(testAArch64Extension("thunderx", "lse"));
1267 EXPECT_FALSE(testAArch64Extension("thunderxt81", "lse"));
1268 EXPECT_FALSE(testAArch64Extension("thunderxt83", "lse"));
1269 EXPECT_FALSE(testAArch64Extension("thunderxt88", "lse"));
1270 EXPECT_TRUE(testAArch64Extension("tsv110", "aes"));
1271 EXPECT_TRUE(testAArch64Extension("tsv110", "sha2"));
1272 EXPECT_FALSE(testAArch64Extension("tsv110", "sha3"));
1273 EXPECT_FALSE(testAArch64Extension("tsv110", "sm4"));
1274 EXPECT_TRUE(testAArch64Extension("tsv110", "ras"));
1275 EXPECT_TRUE(testAArch64Extension("tsv110", "profile"));
1276 EXPECT_TRUE(testAArch64Extension("tsv110", "fp16"));
1277 EXPECT_TRUE(testAArch64Extension("tsv110", "fp16fml"));
1278 EXPECT_TRUE(testAArch64Extension("tsv110", "dotprod"));
1279 EXPECT_TRUE(testAArch64Extension("tsv110", "jscvt"));
1280 EXPECT_TRUE(testAArch64Extension("tsv110", "fcma"));
1281 EXPECT_TRUE(testAArch64Extension("a64fx", "fp16"));
1282 EXPECT_TRUE(testAArch64Extension("a64fx", "sve"));
1283 EXPECT_FALSE(testAArch64Extension("a64fx", "sve2"));
1284 EXPECT_TRUE(testAArch64Extension("carmel", "aes"));
1285 EXPECT_TRUE(testAArch64Extension("carmel", "sha2"));
1286 EXPECT_TRUE(testAArch64Extension("carmel", "fp16"));
1288 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8A
, "ras"));
1289 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_1A
, "ras"));
1290 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A
, "profile"));
1291 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A
, "fp16"));
1292 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A
, "fp16fml"));
1293 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A
, "fp16"));
1294 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A
, "fp16fml"));
1295 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A
, "fp16"));
1296 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A
, "fp16fml"));
1299 TEST(TargetParserTest
, AArch64ExtensionFeatures
) {
1300 std::vector
<uint64_t> Extensions
= {
1301 AArch64::AEK_CRC
, AArch64::AEK_LSE
,
1302 AArch64::AEK_RDM
, AArch64::AEK_CRYPTO
,
1303 AArch64::AEK_SM4
, AArch64::AEK_SHA3
,
1304 AArch64::AEK_SHA2
, AArch64::AEK_AES
,
1305 AArch64::AEK_DOTPROD
, AArch64::AEK_FP
,
1306 AArch64::AEK_SIMD
, AArch64::AEK_FP16
,
1307 AArch64::AEK_FP16FML
, AArch64::AEK_PROFILE
,
1308 AArch64::AEK_RAS
, AArch64::AEK_SVE
,
1309 AArch64::AEK_SVE2
, AArch64::AEK_SVE2AES
,
1310 AArch64::AEK_SVE2SM4
, AArch64::AEK_SVE2SHA3
,
1311 AArch64::AEK_SVE2BITPERM
, AArch64::AEK_RCPC
,
1312 AArch64::AEK_RAND
, AArch64::AEK_MTE
,
1313 AArch64::AEK_SSBS
, AArch64::AEK_SB
,
1314 AArch64::AEK_PREDRES
, AArch64::AEK_BF16
,
1315 AArch64::AEK_I8MM
, AArch64::AEK_F32MM
,
1316 AArch64::AEK_F64MM
, AArch64::AEK_TME
,
1317 AArch64::AEK_LS64
, AArch64::AEK_BRBE
,
1318 AArch64::AEK_PAUTH
, AArch64::AEK_FLAGM
,
1319 AArch64::AEK_SME
, AArch64::AEK_SMEF64F64
,
1320 AArch64::AEK_SMEI16I64
, AArch64::AEK_SME2
,
1321 AArch64::AEK_HBC
, AArch64::AEK_MOPS
,
1322 AArch64::AEK_PERFMON
, AArch64::AEK_SVE2P1
,
1323 AArch64::AEK_SME2P1
, AArch64::AEK_SMEB16B16
,
1324 AArch64::AEK_SMEF16F16
, AArch64::AEK_CSSC
,
1325 AArch64::AEK_RCPC3
, AArch64::AEK_THE
,
1326 AArch64::AEK_D128
, AArch64::AEK_LSE128
,
1327 AArch64::AEK_SPECRES2
, AArch64::AEK_RASV2
,
1328 AArch64::AEK_ITE
, AArch64::AEK_GCS
,
1329 AArch64::AEK_FAMINMAX
, AArch64::AEK_FP8FMA
,
1330 AArch64::AEK_SSVE_FP8FMA
, AArch64::AEK_FP8DOT2
,
1331 AArch64::AEK_SSVE_FP8DOT2
, AArch64::AEK_FP8DOT4
,
1332 AArch64::AEK_SSVE_FP8DOT4
, AArch64::AEK_LUT
,
1333 AArch64::AEK_SME_LUTV2
, AArch64::AEK_SMEF8F16
,
1334 AArch64::AEK_SMEF8F32
, AArch64::AEK_SMEFA64
,
1335 AArch64::AEK_CPA
, AArch64::AEK_PAUTHLR
,
1336 AArch64::AEK_TLBIW
, AArch64::AEK_JSCVT
,
1337 AArch64::AEK_FCMA
, AArch64::AEK_FP8
,
1338 AArch64::AEK_SVEB16B16
, AArch64::AEK_SVE2P2
,
1339 AArch64::AEK_SME2P2
, AArch64::AEK_SVE_BFSCALE
,
1340 AArch64::AEK_SVE_F16F32MM
, AArch64::AEK_SVE_AES2
,
1341 AArch64::AEK_SSVE_AES
, AArch64::AEK_F8F32MM
,
1342 AArch64::AEK_F8F16MM
, AArch64::AEK_LSFE
,
1343 AArch64::AEK_FPRCVT
, AArch64::AEK_CMPBR
,
1344 AArch64::AEK_LSUI
, AArch64::AEK_OCCMO
,
1345 AArch64::AEK_PCDPHINT
, AArch64::AEK_POPS
,
1346 AArch64::AEK_SVEAES
};
1348 std::vector
<StringRef
> Features
;
1350 AArch64::ExtensionBitset ExtVal
;
1351 for (auto Ext
: Extensions
)
1354 // Test an empty set of features.
1355 EXPECT_TRUE(AArch64::getExtensionFeatures({}, Features
));
1356 EXPECT_TRUE(Features
.size() == 0);
1358 AArch64::getExtensionFeatures(ExtVal
, Features
);
1359 EXPECT_EQ(Extensions
.size(), Features
.size());
1361 EXPECT_TRUE(llvm::is_contained(Features
, "+crc"));
1362 EXPECT_TRUE(llvm::is_contained(Features
, "+lse"));
1363 EXPECT_TRUE(llvm::is_contained(Features
, "+rdm"));
1364 EXPECT_TRUE(llvm::is_contained(Features
, "+crypto"));
1365 EXPECT_TRUE(llvm::is_contained(Features
, "+sm4"));
1366 EXPECT_TRUE(llvm::is_contained(Features
, "+sha3"));
1367 EXPECT_TRUE(llvm::is_contained(Features
, "+sha2"));
1368 EXPECT_TRUE(llvm::is_contained(Features
, "+aes"));
1369 EXPECT_TRUE(llvm::is_contained(Features
, "+dotprod"));
1370 EXPECT_TRUE(llvm::is_contained(Features
, "+fp-armv8"));
1371 EXPECT_TRUE(llvm::is_contained(Features
, "+neon"));
1372 EXPECT_TRUE(llvm::is_contained(Features
, "+fullfp16"));
1373 EXPECT_TRUE(llvm::is_contained(Features
, "+fp16fml"));
1374 EXPECT_TRUE(llvm::is_contained(Features
, "+spe"));
1375 EXPECT_TRUE(llvm::is_contained(Features
, "+ras"));
1376 EXPECT_TRUE(llvm::is_contained(Features
, "+sve"));
1377 EXPECT_TRUE(llvm::is_contained(Features
, "+sve-b16b16"));
1378 EXPECT_TRUE(llvm::is_contained(Features
, "+sve-bfscale"));
1379 EXPECT_TRUE(llvm::is_contained(Features
, "+sve-f16f32mm"));
1380 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2"));
1381 EXPECT_TRUE(llvm::is_contained(Features
, "+sve-aes"));
1382 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2-aes"));
1383 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2-sm4"));
1384 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2-sha3"));
1385 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2-bitperm"));
1386 EXPECT_TRUE(llvm::is_contained(Features
, "+sve-aes2"));
1387 EXPECT_TRUE(llvm::is_contained(Features
, "+ssve-aes"));
1388 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2p1"));
1389 EXPECT_TRUE(llvm::is_contained(Features
, "+sve2p2"));
1390 EXPECT_TRUE(llvm::is_contained(Features
, "+rcpc"));
1391 EXPECT_TRUE(llvm::is_contained(Features
, "+rand"));
1392 EXPECT_TRUE(llvm::is_contained(Features
, "+mte"));
1393 EXPECT_TRUE(llvm::is_contained(Features
, "+ssbs"));
1394 EXPECT_TRUE(llvm::is_contained(Features
, "+sb"));
1395 EXPECT_TRUE(llvm::is_contained(Features
, "+predres"));
1396 EXPECT_TRUE(llvm::is_contained(Features
, "+bf16"));
1397 EXPECT_TRUE(llvm::is_contained(Features
, "+i8mm"));
1398 EXPECT_TRUE(llvm::is_contained(Features
, "+f32mm"));
1399 EXPECT_TRUE(llvm::is_contained(Features
, "+f64mm"));
1400 EXPECT_TRUE(llvm::is_contained(Features
, "+tme"));
1401 EXPECT_TRUE(llvm::is_contained(Features
, "+ls64"));
1402 EXPECT_TRUE(llvm::is_contained(Features
, "+brbe"));
1403 EXPECT_TRUE(llvm::is_contained(Features
, "+pauth"));
1404 EXPECT_TRUE(llvm::is_contained(Features
, "+flagm"));
1405 EXPECT_TRUE(llvm::is_contained(Features
, "+sme"));
1406 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-f64f64"));
1407 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-i16i64"));
1408 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-f16f16"));
1409 EXPECT_TRUE(llvm::is_contained(Features
, "+sme2"));
1410 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-b16b16"));
1411 EXPECT_TRUE(llvm::is_contained(Features
, "+sme2p1"));
1412 EXPECT_TRUE(llvm::is_contained(Features
, "+sme2p2"));
1413 EXPECT_TRUE(llvm::is_contained(Features
, "+hbc"));
1414 EXPECT_TRUE(llvm::is_contained(Features
, "+mops"));
1415 EXPECT_TRUE(llvm::is_contained(Features
, "+perfmon"));
1416 EXPECT_TRUE(llvm::is_contained(Features
, "+cssc"));
1417 EXPECT_TRUE(llvm::is_contained(Features
, "+rcpc3"));
1418 EXPECT_TRUE(llvm::is_contained(Features
, "+the"));
1419 EXPECT_TRUE(llvm::is_contained(Features
, "+d128"));
1420 EXPECT_TRUE(llvm::is_contained(Features
, "+lse128"));
1421 EXPECT_TRUE(llvm::is_contained(Features
, "+specres2"));
1422 EXPECT_TRUE(llvm::is_contained(Features
, "+ite"));
1423 EXPECT_TRUE(llvm::is_contained(Features
, "+gcs"));
1424 EXPECT_TRUE(llvm::is_contained(Features
, "+fp8"));
1425 EXPECT_TRUE(llvm::is_contained(Features
, "+faminmax"));
1426 EXPECT_TRUE(llvm::is_contained(Features
, "+fp8fma"));
1427 EXPECT_TRUE(llvm::is_contained(Features
, "+ssve-fp8fma"));
1428 EXPECT_TRUE(llvm::is_contained(Features
, "+fp8dot2"));
1429 EXPECT_TRUE(llvm::is_contained(Features
, "+ssve-fp8dot2"));
1430 EXPECT_TRUE(llvm::is_contained(Features
, "+fp8dot4"));
1431 EXPECT_TRUE(llvm::is_contained(Features
, "+ssve-fp8dot4"));
1432 EXPECT_TRUE(llvm::is_contained(Features
, "+f8f32mm"));
1433 EXPECT_TRUE(llvm::is_contained(Features
, "+f8f16mm"));
1434 EXPECT_TRUE(llvm::is_contained(Features
, "+lut"));
1435 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-lutv2"));
1436 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-f8f16"));
1437 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-f8f32"));
1438 EXPECT_TRUE(llvm::is_contained(Features
, "+sme-fa64"));
1439 EXPECT_TRUE(llvm::is_contained(Features
, "+cpa"));
1440 EXPECT_TRUE(llvm::is_contained(Features
, "+pauth-lr"));
1441 EXPECT_TRUE(llvm::is_contained(Features
, "+tlbiw"));
1442 EXPECT_TRUE(llvm::is_contained(Features
, "+jsconv"));
1443 EXPECT_TRUE(llvm::is_contained(Features
, "+complxnum"));
1444 EXPECT_TRUE(llvm::is_contained(Features
, "+lsfe"));
1445 EXPECT_TRUE(llvm::is_contained(Features
, "+fprcvt"));
1446 EXPECT_TRUE(llvm::is_contained(Features
, "+cmpbr"));
1447 EXPECT_TRUE(llvm::is_contained(Features
, "+lsui"));
1448 EXPECT_TRUE(llvm::is_contained(Features
, "+occmo"));
1449 EXPECT_TRUE(llvm::is_contained(Features
, "+pcdphint"));
1450 EXPECT_TRUE(llvm::is_contained(Features
, "+pops"));
1452 // Assuming we listed every extension above, this should produce the same
1454 std::vector
<StringRef
> AllFeatures
;
1455 EXPECT_TRUE(AArch64::getExtensionFeatures(ExtVal
, AllFeatures
));
1456 EXPECT_THAT(Features
, ::testing::ContainerEq(AllFeatures
));
1459 TEST(TargetParserTest
, AArch64ArchFeatures
) {
1460 EXPECT_EQ(AArch64::ARMV8A
.ArchFeature
, "+v8a");
1461 EXPECT_EQ(AArch64::ARMV8_1A
.ArchFeature
, "+v8.1a");
1462 EXPECT_EQ(AArch64::ARMV8_2A
.ArchFeature
, "+v8.2a");
1463 EXPECT_EQ(AArch64::ARMV8_3A
.ArchFeature
, "+v8.3a");
1464 EXPECT_EQ(AArch64::ARMV8_4A
.ArchFeature
, "+v8.4a");
1465 EXPECT_EQ(AArch64::ARMV8_5A
.ArchFeature
, "+v8.5a");
1466 EXPECT_EQ(AArch64::ARMV8_6A
.ArchFeature
, "+v8.6a");
1467 EXPECT_EQ(AArch64::ARMV8_7A
.ArchFeature
, "+v8.7a");
1468 EXPECT_EQ(AArch64::ARMV8_8A
.ArchFeature
, "+v8.8a");
1469 EXPECT_EQ(AArch64::ARMV8_9A
.ArchFeature
, "+v8.9a");
1470 EXPECT_EQ(AArch64::ARMV9A
.ArchFeature
, "+v9a");
1471 EXPECT_EQ(AArch64::ARMV9_1A
.ArchFeature
, "+v9.1a");
1472 EXPECT_EQ(AArch64::ARMV9_2A
.ArchFeature
, "+v9.2a");
1473 EXPECT_EQ(AArch64::ARMV9_3A
.ArchFeature
, "+v9.3a");
1474 EXPECT_EQ(AArch64::ARMV9_4A
.ArchFeature
, "+v9.4a");
1475 EXPECT_EQ(AArch64::ARMV9_5A
.ArchFeature
, "+v9.5a");
1476 EXPECT_EQ(AArch64::ARMV9_6A
.ArchFeature
, "+v9.6a");
1477 EXPECT_EQ(AArch64::ARMV8R
.ArchFeature
, "+v8r");
1480 TEST(TargetParserTest
, AArch64ArchPartialOrder
) {
1481 for (const auto *A
: AArch64::ArchInfos
) {
1484 // v8r has no relation to other valid architectures
1485 if (*A
!= AArch64::ARMV8R
) {
1486 EXPECT_FALSE(A
->implies(AArch64::ARMV8R
));
1487 EXPECT_FALSE(AArch64::ARMV8R
.implies(*A
));
1491 for (const auto *A
: {
1502 EXPECT_TRUE(A
->implies(AArch64::ARMV8A
));
1504 for (const auto *A
:
1505 {&AArch64::ARMV9_1A
, &AArch64::ARMV9_2A
, &AArch64::ARMV9_3A
,
1506 &AArch64::ARMV9_4A
, &AArch64::ARMV9_5A
, &AArch64::ARMV9_6A
})
1507 EXPECT_TRUE(A
->implies(AArch64::ARMV9A
));
1509 EXPECT_TRUE(AArch64::ARMV8_1A
.implies(AArch64::ARMV8A
));
1510 EXPECT_TRUE(AArch64::ARMV8_2A
.implies(AArch64::ARMV8_1A
));
1511 EXPECT_TRUE(AArch64::ARMV8_3A
.implies(AArch64::ARMV8_2A
));
1512 EXPECT_TRUE(AArch64::ARMV8_4A
.implies(AArch64::ARMV8_3A
));
1513 EXPECT_TRUE(AArch64::ARMV8_5A
.implies(AArch64::ARMV8_4A
));
1514 EXPECT_TRUE(AArch64::ARMV8_6A
.implies(AArch64::ARMV8_5A
));
1515 EXPECT_TRUE(AArch64::ARMV8_7A
.implies(AArch64::ARMV8_6A
));
1516 EXPECT_TRUE(AArch64::ARMV8_8A
.implies(AArch64::ARMV8_7A
));
1517 EXPECT_TRUE(AArch64::ARMV8_9A
.implies(AArch64::ARMV8_8A
));
1519 EXPECT_TRUE(AArch64::ARMV9_1A
.implies(AArch64::ARMV9A
));
1520 EXPECT_TRUE(AArch64::ARMV9_2A
.implies(AArch64::ARMV9_1A
));
1521 EXPECT_TRUE(AArch64::ARMV9_3A
.implies(AArch64::ARMV9_2A
));
1522 EXPECT_TRUE(AArch64::ARMV9_4A
.implies(AArch64::ARMV9_3A
));
1523 EXPECT_TRUE(AArch64::ARMV9_5A
.implies(AArch64::ARMV9_4A
));
1524 EXPECT_TRUE(AArch64::ARMV9_6A
.implies(AArch64::ARMV9_5A
));
1526 EXPECT_TRUE(AArch64::ARMV9A
.implies(AArch64::ARMV8_5A
));
1527 EXPECT_TRUE(AArch64::ARMV9_1A
.implies(AArch64::ARMV8_6A
));
1528 EXPECT_TRUE(AArch64::ARMV9_2A
.implies(AArch64::ARMV8_7A
));
1529 EXPECT_TRUE(AArch64::ARMV9_3A
.implies(AArch64::ARMV8_8A
));
1530 EXPECT_TRUE(AArch64::ARMV9_4A
.implies(AArch64::ARMV8_9A
));
1533 TEST(TargetParserTest
, AArch64ArchExtFeature
) {
1534 const char *ArchExt
[][4] = {
1535 {"crc", "nocrc", "+crc", "-crc"},
1536 {"crypto", "nocrypto", "+crypto", "-crypto"},
1537 {"flagm", "noflagm", "+flagm", "-flagm"},
1538 {"fp", "nofp", "+fp-armv8", "-fp-armv8"},
1539 {"simd", "nosimd", "+neon", "-neon"},
1540 {"fp16", "nofp16", "+fullfp16", "-fullfp16"},
1541 {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"},
1542 {"profile", "noprofile", "+spe", "-spe"},
1543 {"ras", "noras", "+ras", "-ras"},
1544 {"lse", "nolse", "+lse", "-lse"},
1545 {"rdm", "nordm", "+rdm", "-rdm"},
1546 {"sve", "nosve", "+sve", "-sve"},
1547 {"sve-b16b16", "nosve-b16b16", "+sve-b16b16", "-sve-b16b16"},
1548 {"sve-bfscale", "nosve-bfscale", "+sve-bfscale", "-sve-bfscale"},
1549 {"sve-f16f32mm", "nosve-f16f32mm", "+sve-f16f32mm", "-sve-f16f32mm"},
1550 {"sve2", "nosve2", "+sve2", "-sve2"},
1551 {"sve-aes", "nosve-aes", "+sve-aes", "-sve-aes"},
1552 {"sve2-aes", "nosve2-aes", "+sve2-aes", "-sve2-aes"},
1553 {"sve2-sm4", "nosve2-sm4", "+sve2-sm4", "-sve2-sm4"},
1554 {"sve2-sha3", "nosve2-sha3", "+sve2-sha3", "-sve2-sha3"},
1555 {"sve2p1", "nosve2p1", "+sve2p1", "-sve2p1"},
1556 {"sve2p2", "nosve2p2", "+sve2p2", "-sve2p2"},
1557 {"sve2-bitperm", "nosve2-bitperm", "+sve2-bitperm", "-sve2-bitperm"},
1558 {"sve-aes2", "nosve-aes2", "+sve-aes2", "-sve-aes2"},
1559 {"ssve-aes", "nossve-aes", "+ssve-aes", "-ssve-aes"},
1560 {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
1561 {"rcpc", "norcpc", "+rcpc", "-rcpc"},
1562 {"rng", "norng", "+rand", "-rand"},
1563 {"memtag", "nomemtag", "+mte", "-mte"},
1564 {"tme", "notme", "+tme", "-tme"},
1565 {"pauth", "nopauth", "+pauth", "-pauth"},
1566 {"ssbs", "nossbs", "+ssbs", "-ssbs"},
1567 {"sb", "nosb", "+sb", "-sb"},
1568 {"predres", "nopredres", "+predres", "-predres"},
1569 {"i8mm", "noi8mm", "+i8mm", "-i8mm"},
1570 {"f32mm", "nof32mm", "+f32mm", "-f32mm"},
1571 {"f64mm", "nof64mm", "+f64mm", "-f64mm"},
1572 {"f8f32mm", "nof8f32mm", "+f8f32mm", "-f8f32mm"},
1573 {"f8f16mm", "nof8f16mm", "+f8f16mm", "-f8f16mm"},
1574 {"sme", "nosme", "+sme", "-sme"},
1575 {"sme-fa64", "nosme-fa64", "+sme-fa64", "-sme-fa64"},
1576 {"sme-f64f64", "nosme-f64f64", "+sme-f64f64", "-sme-f64f64"},
1577 {"sme-i16i64", "nosme-i16i64", "+sme-i16i64", "-sme-i16i64"},
1578 {"sme-f16f16", "nosme-f16f16", "+sme-f16f16", "-sme-f16f16"},
1579 {"sme2", "nosme2", "+sme2", "-sme2"},
1580 {"sme-b16b16", "nosme-b16b16", "+sme-b16b16", "-sme-b16b16"},
1581 {"sme2p1", "nosme2p1", "+sme2p1", "-sme2p1"},
1582 {"sme2p2", "nosme2p2", "+sme2p2", "-sme2p2"},
1583 {"hbc", "nohbc", "+hbc", "-hbc"},
1584 {"mops", "nomops", "+mops", "-mops"},
1585 {"pmuv3", "nopmuv3", "+perfmon", "-perfmon"},
1586 {"predres2", "nopredres2", "+specres2", "-specres2"},
1587 {"rasv2", "norasv2", "+rasv2", "-rasv2"},
1588 {"gcs", "nogcs", "+gcs", "-gcs"},
1589 {"fp8", "nofp8", "+fp8", "-fp8"},
1590 {"faminmax", "nofaminmax", "+faminmax", "-faminmax"},
1591 {"fp8fma", "nofp8fma", "+fp8fma", "-fp8fma"},
1592 {"ssve-fp8fma", "nossve-fp8fma", "+ssve-fp8fma", "-ssve-fp8fma"},
1593 {"fp8dot2", "nofp8dot2", "+fp8dot2", "-fp8dot2"},
1594 {"ssve-fp8dot2", "nossve-fp8dot2", "+ssve-fp8dot2", "-ssve-fp8dot2"},
1595 {"fp8dot4", "nofp8dot4", "+fp8dot4", "-fp8dot4"},
1596 {"ssve-fp8dot4", "nossve-fp8dot4", "+ssve-fp8dot4", "-ssve-fp8dot4"},
1597 {"lut", "nolut", "+lut", "-lut"},
1598 {"sme-lutv2", "nosme-lutv2", "+sme-lutv2", "-sme-lutv2"},
1599 {"sme-f8f16", "nosme-f8f16", "+sme-f8f16", "-sme-f8f16"},
1600 {"sme-f8f32", "nosme-f8f32", "+sme-f8f32", "-sme-f8f32"},
1601 {"lsfe", "nolsfe", "+lsfe", "-lsfe"},
1602 {"fprcvt", "nofprcvt", "+fprcvt", "-fprcvt"},
1603 {"cmpbr", "nocmpbr", "+cmpbr", "-cmpbr"},
1604 {"lsui", "nolsui", "+lsui", "-lsui"},
1605 {"occmo", "nooccmo", "+occmo", "-occmo"},
1606 {"pcdphint", "nopcdphint", "+pcdphint", "-pcdphint"},
1607 {"pops", "nopops", "+pops", "-pops"},
1610 for (unsigned i
= 0; i
< std::size(ArchExt
); i
++) {
1611 EXPECT_EQ(StringRef(ArchExt
[i
][2]),
1612 AArch64::getArchExtFeature(ArchExt
[i
][0]));
1613 EXPECT_EQ(StringRef(ArchExt
[i
][3]),
1614 AArch64::getArchExtFeature(ArchExt
[i
][1]));
1618 TEST(TargetParserTest
, AArch64PrintSupportedExtensions
) {
1619 std::string expected
= "All available -march extensions for AArch64\n\n"
1620 " Name Architecture Feature(s) "
1624 testing::internal::CaptureStdout();
1625 AArch64::PrintSupportedExtensions();
1627 std::string captured
= testing::internal::GetCapturedStdout();
1629 // Check that the start of the output is as expected.
1630 EXPECT_EQ(0ULL, captured
.find(expected
));
1632 // Should not include "none".
1633 EXPECT_EQ(std::string::npos
, captured
.find("none"));
1634 // Should not include anything that lacks a feature name. Checking a few here
1635 // but not all as if one is hidden correctly the rest should be.
1636 EXPECT_EQ(std::string::npos
, captured
.find("memtag3"));
1637 EXPECT_EQ(std::string::npos
, captured
.find("sha1"));
1638 EXPECT_EQ(std::string::npos
, captured
.find("ssbs2"));
1641 struct AArch64ExtensionDependenciesBaseArchTestParams
{
1642 const llvm::AArch64::ArchInfo
&Arch
;
1643 std::vector
<StringRef
> Modifiers
;
1644 std::vector
<StringRef
> ExpectedPos
;
1645 std::vector
<StringRef
> ExpectedNeg
;
1648 class AArch64ExtensionDependenciesBaseArchTestFixture
1649 : public ::testing::TestWithParam
<
1650 AArch64ExtensionDependenciesBaseArchTestParams
> {};
1652 struct AArch64ExtensionDependenciesBaseCPUTestParams
{
1654 std::vector
<StringRef
> Modifiers
;
1655 std::vector
<StringRef
> ExpectedPos
;
1656 std::vector
<StringRef
> ExpectedNeg
;
1659 class AArch64ExtensionDependenciesBaseCPUTestFixture
1660 : public ::testing::TestWithParam
<
1661 AArch64ExtensionDependenciesBaseCPUTestParams
> {};
1663 TEST_P(AArch64ExtensionDependenciesBaseArchTestFixture
,
1664 AArch64ExtensionDependenciesBaseArch
) {
1665 auto Params
= GetParam();
1667 llvm::AArch64::ExtensionSet Extensions
;
1668 Extensions
.addArchDefaults(Params
.Arch
);
1669 for (auto M
: Params
.Modifiers
) {
1670 bool success
= Extensions
.parseModifier(M
);
1671 EXPECT_TRUE(success
);
1673 std::vector
<StringRef
> Features
;
1674 Extensions
.toLLVMFeatureList(Features
);
1676 for (auto E
: Params
.ExpectedPos
) {
1677 std::string PosString
= "+";
1679 std::string NegString
= "-";
1681 ASSERT_THAT(Features
, Contains(StrEq(PosString
)));
1682 ASSERT_THAT(Features
, Not(Contains(StrEq(NegString
))));
1685 for (auto E
: Params
.ExpectedNeg
) {
1686 std::string PosString
= "+";
1688 ASSERT_THAT(Features
, Not(Contains(StrEq(PosString
))));
1689 // Features default to off, so the negative string is not expected in many
1694 TEST_P(AArch64ExtensionDependenciesBaseCPUTestFixture
,
1695 AArch64ExtensionDependenciesBaseCPU
) {
1696 auto Params
= GetParam();
1698 llvm::AArch64::ExtensionSet Extensions
;
1699 const std::optional
<llvm::AArch64::CpuInfo
> CPU
=
1700 llvm::AArch64::parseCpu(Params
.CPUName
);
1702 Extensions
.addCPUDefaults(*CPU
);
1703 for (auto M
: Params
.Modifiers
) {
1704 bool success
= Extensions
.parseModifier(M
);
1705 EXPECT_TRUE(success
);
1707 std::vector
<StringRef
> Features
;
1708 Extensions
.toLLVMFeatureList(Features
);
1710 for (auto E
: Params
.ExpectedPos
) {
1711 std::string PosString
= "+";
1713 std::string NegString
= "-";
1715 ASSERT_THAT(Features
, Contains(StrEq(PosString
)));
1716 ASSERT_THAT(Features
, Not(Contains(StrEq(NegString
))));
1719 for (auto E
: Params
.ExpectedNeg
) {
1720 std::string PosString
= "+";
1722 ASSERT_THAT(Features
, Not(Contains(StrEq(PosString
))));
1723 // Features default to off, so the negative string is not expected in many
1728 AArch64ExtensionDependenciesBaseArchTestParams
1729 AArch64ExtensionDependenciesArchData
[] = {
1730 // Base architecture features
1731 {AArch64::ARMV8A
, {}, {"v8a", "fp-armv8", "neon"}, {}},
1734 {"v8.1a", "crc", "fp-armv8", "lse", "rdm", "neon"},
1736 {AArch64::ARMV9_5A
, {}, {"v9.5a", "mops", "cpa"}, {}},
1738 // Positive modifiers
1739 {AArch64::ARMV8A
, {"fp16"}, {"fullfp16"}, {}},
1740 {AArch64::ARMV8A
, {"dotprod"}, {"dotprod"}, {}},
1742 // Negative modifiers
1743 {AArch64::ARMV8A
, {"nofp"}, {"v8a"}, {"fp-armv8", "neon"}},
1748 {"v8a", "fp-armv8", "neon"},
1753 {"fp-armv8", "neon", "fullfp16"}},
1755 // Long dependency chains: sve2-bitperm -> sve2 -> sve -> fp16 -> fp
1757 {"nofp", "sve2-bitperm"},
1758 {"fp-armv8", "fullfp16", "sve", "sve2", "sve2-bitperm"},
1761 {"sve2-bitperm", "nofp16"},
1763 {"full-fp16", "sve", "sve2", "sve2-bitperm"}},
1765 // Meaning of +crypto varies with base architecture.
1766 {AArch64::ARMV8A
, {"crypto"}, {"aes", "sha2"}, {}},
1767 {AArch64::ARMV8_4A
, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}},
1768 {AArch64::ARMV9A
, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}},
1770 // -crypto always disables all crypto features, even if it wouldn't
1773 {"aes", "sha2", "sha3", "sm4", "nocrypto"},
1775 {"aes", "sha2", "sha3", "sm4"}},
1777 {"aes", "sha2", "sha3", "sm4", "nocrypto"},
1779 {"aes", "sha2", "sha3", "sm4"}},
1781 // +fp16 implies +fp16fml for v8.4A+, but not v9.0-A+
1782 {AArch64::ARMV8_3A
, {"fp16"}, {"fullfp16"}, {"fp16fml"}},
1783 {AArch64::ARMV9A
, {"fp16"}, {"fullfp16"}, {"fp16fml"}},
1784 {AArch64::ARMV8_4A
, {"fp16"}, {"fullfp16", "fp16fml"}, {}},
1787 {AArch64::ARMV8A
, {"nofp", "fp16"}, {"fp-armv8", "fullfp16"}, {}},
1788 {AArch64::ARMV8A
, {"fp16", "nofp"}, {}, {"fp-armv8", "fullfp16"}},
1791 {AArch64::ARMV8A
, {"nofp", "simd"}, {"fp-armv8", "neon"}, {}},
1792 {AArch64::ARMV8A
, {"simd", "nofp"}, {}, {"fp-armv8", "neon"}},
1795 {AArch64::ARMV8A
, {"nofp", "jscvt"}, {"fp-armv8", "jsconv"}, {}},
1796 {AArch64::ARMV8A
, {"jscvt", "nofp"}, {}, {"fp-armv8", "jsconv"}},
1799 {AArch64::ARMV9_6A
, {"nofp", "lsfe"}, {"fp-armv8", "lsfe"}, {}},
1800 {AArch64::ARMV9_6A
, {"lsfe", "nofp"}, {}, {"fp-armv8", "lsfe"}},
1803 {AArch64::ARMV9_6A
, {"nofp", "fprcvt"}, {"fp-armv8", "fprcvt"}, {}},
1804 {AArch64::ARMV9_6A
, {"fprcvt", "nofp"}, {}, {"fp-armv8", "fprcvt"}},
1806 // simd -> {aes, sha2, sha3, sm4, f8f16mm, f8f32mm}
1807 {AArch64::ARMV8A
, {"nosimd", "aes"}, {"neon", "aes"}, {}},
1808 {AArch64::ARMV8A
, {"aes", "nosimd"}, {}, {"neon", "aes"}},
1809 {AArch64::ARMV8A
, {"nosimd", "sha2"}, {"neon", "sha2"}, {}},
1810 {AArch64::ARMV8A
, {"sha2", "nosimd"}, {}, {"neon", "sha2"}},
1811 {AArch64::ARMV8A
, {"nosimd", "sha3"}, {"neon", "sha3"}, {}},
1812 {AArch64::ARMV8A
, {"sha3", "nosimd"}, {}, {"neon", "sha3"}},
1813 {AArch64::ARMV8A
, {"nosimd", "sm4"}, {"neon", "sm4"}, {}},
1814 {AArch64::ARMV8A
, {"sm4", "nosimd"}, {}, {"neon", "sm4"}},
1815 {AArch64::ARMV9_6A
, {"nosimd", "f8f16mm"}, {"neon", "f8f16mm"}, {}},
1816 {AArch64::ARMV9_6A
, {"f8f16mm", "nosimd"}, {}, {"neon", "f8f16mm"}},
1817 {AArch64::ARMV9_6A
, {"nosimd", "f8f32mm"}, {"neon", "f8f32mm"}, {}},
1818 {AArch64::ARMV9_6A
, {"f8f32mm", "nosimd"}, {}, {"neon", "f8f32mm"}},
1820 // simd -> {rdm, dotprod, fcma}
1821 {AArch64::ARMV8A
, {"nosimd", "rdm"}, {"neon", "rdm"}, {}},
1822 {AArch64::ARMV8A
, {"rdm", "nosimd"}, {}, {"neon", "rdm"}},
1823 {AArch64::ARMV8A
, {"nosimd", "dotprod"}, {"neon", "dotprod"}, {}},
1824 {AArch64::ARMV8A
, {"dotprod", "nosimd"}, {}, {"neon", "dotprod"}},
1825 {AArch64::ARMV8A
, {"nosimd", "fcma"}, {"neon", "complxnum"}, {}},
1826 {AArch64::ARMV8A
, {"fcma", "nosimd"}, {}, {"neon", "complxnum"}},
1828 // fp16 -> {fp16fml, sve}
1829 {AArch64::ARMV8A
, {"nofp16", "fp16fml"}, {"fullfp16", "fp16fml"}, {}},
1830 {AArch64::ARMV8A
, {"fp16fml", "nofp16"}, {}, {"fullfp16", "fp16fml"}},
1831 {AArch64::ARMV8A
, {"nofp16", "sve"}, {"fullfp16", "sve"}, {}},
1832 {AArch64::ARMV8A
, {"sve", "nofp16"}, {}, {"fullfp16", "sve"}},
1835 {AArch64::ARMV8A
, {"nobf16", "sme"}, {"bf16", "sme"}, {}},
1836 {AArch64::ARMV8A
, {"sme", "nobf16"}, {}, {"bf16", "sme"}},
1838 // sve -> {sve2, f32mm, f64mm, sve-f16f32mm}
1839 {AArch64::ARMV8A
, {"nosve", "sve2"}, {"sve", "sve2"}, {}},
1840 {AArch64::ARMV8A
, {"sve2", "nosve"}, {}, {"sve", "sve2"}},
1841 {AArch64::ARMV8A
, {"nosve", "f32mm"}, {"sve", "f32mm"}, {}},
1842 {AArch64::ARMV8A
, {"f32mm", "nosve"}, {}, {"sve", "f32mm"}},
1843 {AArch64::ARMV8A
, {"nosve", "f64mm"}, {"sve", "f64mm"}, {}},
1844 {AArch64::ARMV8A
, {"f64mm", "nosve"}, {}, {"sve", "f64mm"}},
1846 {"nosve", "sve-f16f32mm"},
1847 {"sve", "sve-f16f32mm"},
1850 {"sve-f16f32mm", "nosve"},
1852 {"sve", "sve-f16f32mm"}},
1855 {AArch64::ARMV8A
, {"noaes", "sve-aes"}, {"aes", "sve-aes"}, {}},
1856 {AArch64::ARMV8A
, {"sve-aes", "noaes"}, {}, {"aes", "sve-aes"}},
1858 // sve2 -> {sve2p1, sve2-bitperm, sve2-sha3, sve2-sm4, sve2-aes}
1859 {AArch64::ARMV8A
, {"nosve2", "sve2p1"}, {"sve2", "sve2p1"}, {}},
1860 {AArch64::ARMV8A
, {"sve2p1", "nosve2"}, {}, {"sve2", "sve2p1"}},
1862 {"nosve2", "sve2-bitperm"},
1863 {"sve2", "sve2-bitperm"},
1866 {"sve2-bitperm", "nosve2"},
1868 {"sve2", "sve2-bitperm"}},
1869 {AArch64::ARMV8A
, {"nosve2", "sve2-sha3"}, {"sve2", "sve2-sha3"}, {}},
1870 {AArch64::ARMV8A
, {"sve2-sha3", "nosve2"}, {}, {"sve2", "sve2-sha3"}},
1871 {AArch64::ARMV8A
, {"nosve2", "sve2-sm4"}, {"sve2", "sve2-sm4"}, {}},
1872 {AArch64::ARMV8A
, {"sve2-sm4", "nosve2"}, {}, {"sve2", "sve2-sm4"}},
1873 {AArch64::ARMV8A
, {"nosve2", "sve2-aes"}, {"sve2", "sve2-aes"}, {}},
1874 {AArch64::ARMV8A
, {"sve2-aes", "nosve2"}, {}, {"sve2", "sve2-aes"}},
1876 // sve-b16b16 -> {sme-b16b16}
1878 {"nosve-b16b16", "sme-b16b16"},
1879 {"sve-b16b16", "sme-b16b16"},
1882 {"sme-b16b16", "nosve-b16b16"},
1884 {"sve-b16b16", "sme-b16b16"}},
1886 // sve2p1 -> {sve2p2}
1887 {AArch64::ARMV9_6A
, {"nosve2p1", "sve2p2"}, {"sve2p1", "sve2p2"}, {}},
1888 {AArch64::ARMV9_6A
, {"sve2p2", "nosve2p1"}, {}, {"sve2p1", "sve2p2"}},
1890 // sme -> {sme2, sme-f16f16, sme-f64f64, sme-i16i64, sme-fa64}
1891 {AArch64::ARMV8A
, {"nosme", "sme2"}, {"sme", "sme2"}, {}},
1892 {AArch64::ARMV8A
, {"sme2", "nosme"}, {}, {"sme", "sme2"}},
1893 {AArch64::ARMV8A
, {"nosme", "sme-f16f16"}, {"sme", "sme-f16f16"}, {}},
1894 {AArch64::ARMV8A
, {"sme-f16f16", "nosme"}, {}, {"sme", "sme-f16f16"}},
1895 {AArch64::ARMV8A
, {"nosme", "sme-f64f64"}, {"sme", "sme-f64f64"}, {}},
1896 {AArch64::ARMV8A
, {"sme-f64f64", "nosme"}, {}, {"sme", "sme-f64f64"}},
1897 {AArch64::ARMV8A
, {"nosme", "sme-i16i64"}, {"sme", "sme-i16i64"}, {}},
1898 {AArch64::ARMV8A
, {"sme-i16i64", "nosme"}, {}, {"sme", "sme-i16i64"}},
1899 {AArch64::ARMV8A
, {"nosme", "sme-fa64"}, {"sme", "sme-fa64"}, {}},
1900 {AArch64::ARMV8A
, {"sme-fa64", "nosme"}, {}, {"sme", "sme-fa64"}},
1902 // sme2 -> {sme2p1, ssve-fp8fma, ssve-fp8dot2, ssve-fp8dot4, sme-f8f16,
1903 // sme-f8f32, sme-b16b16, ssve-aes}
1904 {AArch64::ARMV8A
, {"nosme2", "sme2p1"}, {"sme2", "sme2p1"}, {}},
1905 {AArch64::ARMV8A
, {"sme2p1", "nosme2"}, {}, {"sme2", "sme2p1"}},
1907 {"nosme2", "ssve-fp8fma"},
1908 {"sme2", "ssve-fp8fma"},
1911 {"ssve-fp8fma", "nosme2"},
1913 {"sme2", "ssve-fp8fma"}},
1915 {"nosme2", "ssve-fp8dot2"},
1916 {"sme2", "ssve-fp8dot2"},
1919 {"ssve-fp8dot2", "nosme2"},
1921 {"sme2", "ssve-fp8dot2"}},
1923 {"nosme2", "ssve-fp8dot4"},
1924 {"sme2", "ssve-fp8dot4"},
1927 {"ssve-fp8dot4", "nosme2"},
1929 {"sme2", "ssve-fp8dot4"}},
1930 {AArch64::ARMV8A
, {"nosme2", "sme-f8f16"}, {"sme2", "sme-f8f16"}, {}},
1931 {AArch64::ARMV8A
, {"sme-f8f16", "nosme2"}, {}, {"sme2", "sme-f8f16"}},
1932 {AArch64::ARMV8A
, {"nosme2", "sme-f8f32"}, {"sme2", "sme-f8f32"}, {}},
1933 {AArch64::ARMV8A
, {"sme-f8f32", "nosme2"}, {}, {"sme2", "sme-f8f32"}},
1934 {AArch64::ARMV8A
, {"nosme2", "sme-b16b16"}, {"sme2", "sme-b16b16"}, {}},
1935 {AArch64::ARMV8A
, {"sme-b16b16", "nosme2"}, {}, {"sme2", "sme-b16b16"}},
1936 {AArch64::ARMV9_6A
, {"nosme2", "ssve-aes"}, {"sme2", "ssve-aes"}, {}},
1937 {AArch64::ARMV9_6A
, {"ssve-aes", "nosme2"}, {}, {"ssve-aes", "sme2"}},
1939 // sme2p1 -> {sme2p2}
1940 {AArch64::ARMV9_6A
, {"nosme2p1", "sme2p2"}, {"sme2p2", "sme2p1"}, {}},
1941 {AArch64::ARMV9_6A
, {"sme2p2", "nosme2p1"}, {}, {"sme2p1", "sme2p2"}},
1943 // fp8 -> {sme-f8f16, sme-f8f32, f8f16mm, f8f32mm}
1944 {AArch64::ARMV8A
, {"nofp8", "sme-f8f16"}, {"fp8", "sme-f8f16"}, {}},
1945 {AArch64::ARMV8A
, {"sme-f8f16", "nofp8"}, {}, {"fp8", "sme-f8f16"}},
1946 {AArch64::ARMV8A
, {"nofp8", "sme-f8f32"}, {"fp8", "sme-f8f32"}, {}},
1947 {AArch64::ARMV8A
, {"sme-f8f32", "nofp8"}, {}, {"fp8", "sme-f8f32"}},
1948 {AArch64::ARMV9_6A
, {"nofp8", "f8f16mm"}, {"fp8", "f8f16mm"}, {}},
1949 {AArch64::ARMV9_6A
, {"f8f16mm", "nofp8"}, {}, {"fp8", "f8f16mm"}},
1950 {AArch64::ARMV9_6A
, {"nofp8", "f8f32mm"}, {"fp8", "f8f32mm"}, {}},
1951 {AArch64::ARMV9_6A
, {"f8f32mm", "nofp8"}, {}, {"fp8", "f8f32mm"}},
1954 {AArch64::ARMV8A
, {"nolse", "lse128"}, {"lse", "lse128"}, {}},
1955 {AArch64::ARMV8A
, {"lse128", "nolse"}, {}, {"lse", "lse128"}},
1957 // predres -> predres2
1959 {"nopredres", "predres2"},
1960 {"predres", "specres2"},
1963 {"predres2", "nopredres"},
1965 {"predres", "specres2"}},
1968 {AArch64::ARMV8A
, {"noras", "rasv2"}, {"ras", "rasv2"}, {}},
1969 {AArch64::ARMV8A
, {"rasv2", "noras"}, {}, {"ras", "rasv2"}},
1972 {AArch64::ARMV8A
, {"norcpc", "rcpc3"}, {"rcpc", "rcpc3"}, {}},
1973 {AArch64::ARMV8A
, {"rcpc3", "norcpc"}, {}, {"rcpc", "rcpc3"}},
1975 // sve-aes -> {ssve-aes, sve2-aes}
1977 {"nosve-aes", "ssve-aes"},
1978 {"sve-aes", "ssve-aes"},
1981 {"ssve-aes", "nosve-aes"},
1983 {"ssve-aes", "sve-aes"}},
1985 {"nosve-aes", "sve2-aes"},
1986 {"sve2-aes", "sve-aes"},
1989 {"sve2-aes", "nosve-aes"},
1991 {"sve2-aes", "sve-aes"}},
1993 // -sve2-aes should disable sve-aes (only)
1995 {"sve2", "sve-aes", "nosve2-aes"},
1997 {"sve2-aes", "sve-aes"}}};
1999 INSTANTIATE_TEST_SUITE_P(
2000 AArch64ExtensionDependenciesBaseArch
,
2001 AArch64ExtensionDependenciesBaseArchTestFixture
,
2002 ::testing::ValuesIn(AArch64ExtensionDependenciesArchData
));
2004 AArch64ExtensionDependenciesBaseCPUTestParams
2005 AArch64ExtensionDependenciesCPUData
[] = {
2006 // Base CPU features
2009 {"v8a", "aes", "crc", "fp-armv8", "sha2", "neon"},
2013 {"v8r", "crc", "dotprod", "fp-armv8", "fullfp16", "fp16fml", "lse",
2014 "ras", "rcpc", "rdm", "sb", "neon", "ssbs"},
2018 {"v9.2a", "bf16", "crc", "dotprod", "flagm", "fp-armv8",
2019 "fullfp16", "fp16fml", "i8mm", "lse", "mte", "pauth",
2020 "perfmon", "predres", "ras", "rcpc", "rdm", "sb",
2021 "neon", "ssbs", "sve", "sve2-bitperm", "sve2"},
2024 // Negative modifiers
2027 {"v8r", "crc", "lse", "ras", "rcpc", "sb", "ssbs"},
2028 {"fp-armv8", "neon", "fullfp16", "fp16fml", "dotprod", "rdm"}},
2031 INSTANTIATE_TEST_SUITE_P(
2032 AArch64ExtensionDependenciesBaseCPU
,
2033 AArch64ExtensionDependenciesBaseCPUTestFixture
,
2034 ::testing::ValuesIn(AArch64ExtensionDependenciesCPUData
));