Fix test failures introduced by PR #113697 (#116941)
[llvm-project.git] / llvm / unittests / TargetParser / TargetParserTest.cpp
blobd281c2cbd55d35b1d4b2cf87a22223c53ad3909b
1 //===----------- TargetParser.cpp - Target Parser -------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/TargetParser/TargetParser.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/StringExtras.h"
12 #include "llvm/ADT/StringMap.h"
13 #include "llvm/Support/ARMBuildAttributes.h"
14 #include "llvm/Support/Debug.h"
15 #include "llvm/Support/FormatVariadic.h"
16 #include "llvm/TargetParser/AArch64TargetParser.h"
17 #include "llvm/TargetParser/ARMTargetParser.h"
18 #include "llvm/TargetParser/ARMTargetParserCommon.h"
19 #include "llvm/TargetParser/Triple.h"
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22 #include <optional>
23 #include <sstream>
24 #include <string>
26 using namespace llvm;
28 using ::testing::Contains;
29 using ::testing::StrEq;
31 namespace {
32 const char *ARMArch[] = {
33 "armv4", "armv4t", "armv5", "armv5t", "armv5e",
34 "armv5te", "armv5tej", "armv6", "armv6j", "armv6k",
35 "armv6hl", "armv6t2", "armv6kz", "armv6z", "armv6zk",
36 "armv6-m", "armv6m", "armv6sm", "armv6s-m", "armv7-a",
37 "armv7", "armv7a", "armv7ve", "armv7hl", "armv7l",
38 "armv7-r", "armv7r", "armv7-m", "armv7m", "armv7k",
39 "armv7s", "armv7e-m", "armv7em", "armv8-a", "armv8",
40 "armv8a", "armv8l", "armv8.1-a", "armv8.1a", "armv8.2-a",
41 "armv8.2a", "armv8.3-a", "armv8.3a", "armv8.4-a", "armv8.4a",
42 "armv8.5-a", "armv8.5a", "armv8.6-a", "armv8.6a", "armv8.7-a",
43 "armv8.7a", "armv8.8-a", "armv8.8a", "armv8.9-a", "armv8.9a",
44 "armv8-r", "armv8r", "armv8-m.base", "armv8m.base", "armv8-m.main",
45 "armv8m.main", "iwmmxt", "iwmmxt2", "xscale", "armv8.1-m.main",
46 "armv9-a", "armv9", "armv9a", "armv9.1-a", "armv9.1a",
47 "armv9.2-a", "armv9.2a", "armv9.3-a", "armv9.3a", "armv9.4-a",
48 "armv9.4a", "armv9.5-a", "armv9.5a", "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("-");
63 }),
64 Features.end());
66 return llvm::join(Features, ", ");
69 std::string SerializeExtensionFlags(AArch64::ExtensionBitset Flags) {
70 std::string SerializedFlags;
71 std::ostringstream ss;
72 int HexValue = 0;
73 for (unsigned int i = 0; i < AArch64::AEK_NUM_EXTENSIONS; i++) {
74 HexValue <<= 1;
75 HexValue |= (int)Flags[i];
76 if ((i + 1) % 4 == 0) {
77 ss << std::hex << HexValue;
78 HexValue = 0;
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,
94 uint64_t GotFlags) {
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));
107 private:
108 StringRef CPUName;
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> &params) {
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;
123 else
124 os << SerializeExtensionFlags(params.ExpectedFlags);
125 os << ", \"" << params.CPUAttr.str() << "\"";
126 return os;
129 /// Print a gtest-compatible facsimile of the CPUName, to make the test's name
130 /// human-readable.
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();
136 for (char &C : Name)
137 if (!std::isalnum(C))
138 C = '_';
139 return Name;
142 StringRef CPUName;
143 StringRef ExpectedArch;
144 StringRef ExpectedFPU;
145 T ExpectedFlags;
146 StringRef CPUAttr;
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);
162 EXPECT_PRED_FORMAT2(
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,
175 ::testing::Values(
176 ARMCPUTestParams<uint64_t>("invalid", "invalid", "invalid",
177 ARM::AEK_NONE, ""),
178 ARMCPUTestParams<uint64_t>("generic", "invalid", "none", ARM::AEK_NONE,
179 ""),
181 ARMCPUTestParams<uint64_t>("arm8", "armv4", "none", ARM::AEK_NONE, "4"),
182 ARMCPUTestParams<uint64_t>("arm810", "armv4", "none", ARM::AEK_NONE,
183 "4"),
184 ARMCPUTestParams<uint64_t>("strongarm", "armv4", "none", ARM::AEK_NONE,
185 "4"),
186 ARMCPUTestParams<uint64_t>("strongarm110", "armv4", "none",
187 ARM::AEK_NONE, "4"),
188 ARMCPUTestParams<uint64_t>("strongarm1100", "armv4", "none",
189 ARM::AEK_NONE, "4"),
190 ARMCPUTestParams<uint64_t>("strongarm1110", "armv4", "none",
191 ARM::AEK_NONE, "4"),
192 ARMCPUTestParams<uint64_t>("arm7tdmi", "armv4t", "none", ARM::AEK_NONE,
193 "4T"),
194 ARMCPUTestParams<uint64_t>("arm7tdmi-s", "armv4t", "none",
195 ARM::AEK_NONE, "4T"),
196 ARMCPUTestParams<uint64_t>("arm710t", "armv4t", "none", ARM::AEK_NONE,
197 "4T"),
198 ARMCPUTestParams<uint64_t>("arm720t", "armv4t", "none", ARM::AEK_NONE,
199 "4T"),
200 ARMCPUTestParams<uint64_t>("arm9", "armv4t", "none", ARM::AEK_NONE,
201 "4T"),
202 ARMCPUTestParams<uint64_t>("arm9tdmi", "armv4t", "none", ARM::AEK_NONE,
203 "4T"),
204 ARMCPUTestParams<uint64_t>("arm920", "armv4t", "none", ARM::AEK_NONE,
205 "4T"),
206 ARMCPUTestParams<uint64_t>("arm920t", "armv4t", "none", ARM::AEK_NONE,
207 "4T"),
208 ARMCPUTestParams<uint64_t>("arm922t", "armv4t", "none", ARM::AEK_NONE,
209 "4T"),
210 ARMCPUTestParams<uint64_t>("arm940t", "armv4t", "none", ARM::AEK_NONE,
211 "4T"),
212 ARMCPUTestParams<uint64_t>("ep9312", "armv4t", "none", ARM::AEK_NONE,
213 "4T"),
214 ARMCPUTestParams<uint64_t>("arm10tdmi", "armv5t", "none", ARM::AEK_NONE,
215 "5T"),
216 ARMCPUTestParams<uint64_t>("arm1020t", "armv5t", "none", ARM::AEK_NONE,
217 "5T"),
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,
240 "6KZ"),
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,
247 "6KZ"),
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,
259 "6-M"),
260 ARMCPUTestParams<uint64_t>("cortex-a5", "armv7-a", "neon-vfpv4",
261 ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP,
262 "7-A"),
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,
267 "7-A"),
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,
276 ::testing::Values(
277 ARMCPUTestParams<uint64_t>("cortex-a9", "armv7-a", "neon-fp16",
278 ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP,
279 "7-A"),
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 |
283 ARM::AEK_DSP,
284 "7-A"),
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 |
288 ARM::AEK_DSP,
289 "7-A"),
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 |
293 ARM::AEK_DSP,
294 "7-A"),
295 ARMCPUTestParams<uint64_t>("krait", "armv7-a", "neon-vfpv4",
296 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
297 ARM::AEK_DSP,
298 "7-A"),
299 ARMCPUTestParams<uint64_t>("cortex-r4", "armv7-r", "none",
300 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB |
301 ARM::AEK_DSP,
302 "7-R"),
303 ARMCPUTestParams<uint64_t>("cortex-r4f", "armv7-r", "vfpv3-d16",
304 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB |
305 ARM::AEK_DSP,
306 "7-R"),
307 ARMCPUTestParams<uint64_t>("cortex-r5", "armv7-r", "vfpv3-d16",
308 ARM::AEK_MP | ARM::AEK_HWDIVARM |
309 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
310 "7-R"),
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,
314 "7-R"),
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,
318 "7-R"),
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,
323 "8-R"),
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,
328 "8-R"),
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 |
335 ARM::AEK_DSP,
336 "7E-M"),
337 ARMCPUTestParams<uint64_t>("cortex-m7", "armv7e-m", "fpv5-d16",
338 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB |
339 ARM::AEK_DSP,
340 "7E-M"),
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,
346 "8-A"),
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,
352 "8-A"),
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,
358 "8-A"),
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,
364 "8.2-A"),
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,
370 "8-A"),
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,
376 "8-A"),
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,
382 "8-A"),
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,
388 "8.2-A"),
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,
394 "8.2-A"),
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,
400 "8.2-A"),
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,
406 "8.2-A"),
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,
414 "9-A"),
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,
420 "8.2-A"),
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,
426 "8.2-A"),
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,
432 "8.2-A"),
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,
438 "8.2-A"),
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,
444 "8.2-A"),
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,
450 "8.2-A"),
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,
457 "9-A"),
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,
463 "8.4-A"),
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,
468 "8-A"),
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,
474 "8-A"),
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,
480 "8.2-A"),
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,
486 "8.2-A"),
487 ARMCPUTestParams<uint64_t>("cortex-m23", "armv8-m.base", "none",
488 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB,
489 "8-M.Baseline"),
490 ARMCPUTestParams<uint64_t>("cortex-m33", "armv8-m.main", "fpv5-sp-d16",
491 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
492 "8-M.Mainline"),
493 ARMCPUTestParams<uint64_t>("star-mc1", "armv8-m.main", "fpv5-sp-d16",
494 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
495 "8-M.Mainline"),
496 ARMCPUTestParams<uint64_t>("cortex-m35p", "armv8-m.main", "fpv5-sp-d16",
497 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
498 "8-M.Mainline"),
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,
503 "8.1-M.Mainline"),
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,
508 "8.1-M.Mainline"),
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,
513 "8.1-M.Mainline"),
514 ARMCPUTestParams<uint64_t>("iwmmxt", "iwmmxt", "none", ARM::AEK_NONE,
515 "iwmmxt"),
516 ARMCPUTestParams<uint64_t>("xscale", "xscale", "none", ARM::AEK_NONE,
517 "xscale"),
518 ARMCPUTestParams<uint64_t>("swift", "armv7s", "neon-vfpv4",
519 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
520 ARM::AEK_DSP,
521 "7-S")),
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,
545 unsigned ArchAttr) {
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);
551 return Result;
554 TEST(TargetParserTest, testARMArch) {
555 EXPECT_TRUE(
556 testARMArch("armv4", "strongarm", "v4", ARMBuildAttrs::CPUArch::v4));
557 EXPECT_TRUE(
558 testARMArch("armv4t", "arm7tdmi", "v4t", ARMBuildAttrs::CPUArch::v4T));
559 EXPECT_TRUE(
560 testARMArch("armv5t", "arm10tdmi", "v5", ARMBuildAttrs::CPUArch::v5T));
561 EXPECT_TRUE(
562 testARMArch("armv5te", "arm1022e", "v5e", ARMBuildAttrs::CPUArch::v5TE));
563 EXPECT_TRUE(testARMArch("armv5tej", "arm926ej-s", "v5e",
564 ARMBuildAttrs::CPUArch::v5TEJ));
565 EXPECT_TRUE(
566 testARMArch("armv6", "arm1136jf-s", "v6", ARMBuildAttrs::CPUArch::v6));
567 EXPECT_TRUE(
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));
573 EXPECT_TRUE(
574 testARMArch("armv6-m", "cortex-m0", "v6m", ARMBuildAttrs::CPUArch::v6_M));
575 EXPECT_TRUE(
576 testARMArch("armv7-a", "generic", "v7", ARMBuildAttrs::CPUArch::v7));
577 EXPECT_TRUE(
578 testARMArch("armv7ve", "generic", "v7ve", ARMBuildAttrs::CPUArch::v7));
579 EXPECT_TRUE(
580 testARMArch("armv7-r", "cortex-r4", "v7r", ARMBuildAttrs::CPUArch::v7));
581 EXPECT_TRUE(
582 testARMArch("armv7-m", "cortex-m3", "v7m", ARMBuildAttrs::CPUArch::v7));
583 EXPECT_TRUE(testARMArch("armv7e-m", "cortex-m4", "v7em",
584 ARMBuildAttrs::CPUArch::v7E_M));
585 EXPECT_TRUE(
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));
605 EXPECT_TRUE(
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));
619 EXPECT_TRUE(
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));
627 EXPECT_TRUE(
628 testARMArch("iwmmxt", "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE));
629 EXPECT_TRUE(
630 testARMArch("iwmmxt2", "generic", "", ARMBuildAttrs::CPUArch::v5TE));
631 EXPECT_TRUE(
632 testARMArch("xscale", "xscale", "v5e", ARMBuildAttrs::CPUArch::v5TE));
633 EXPECT_TRUE(
634 testARMArch("armv7s", "swift", "v7s", ARMBuildAttrs::CPUArch::v7));
635 EXPECT_TRUE(
636 testARMArch("armv7k", "generic", "v7k", ARMBuildAttrs::CPUArch::v7));
639 bool testARMExtension(StringRef CPUName, ARM::ArchKind ArchKind,
640 StringRef ArchExt) {
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"));
651 EXPECT_FALSE(
652 testARMExtension("arm1136jf-s", ARM::ArchKind::INVALID, "crypto"));
653 EXPECT_FALSE(
654 testARMExtension("arm1156t2-s", ARM::ArchKind::INVALID, "crypto"));
655 EXPECT_FALSE(
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"));
664 EXPECT_FALSE(
665 testARMExtension("cortex-a55", ARM::ArchKind::INVALID, "fp16fml"));
666 EXPECT_TRUE(testARMExtension("cortex-a75", ARM::ArchKind::INVALID, "fp16"));
667 EXPECT_FALSE(
668 testARMExtension("cortex-a75", ARM::ArchKind::INVALID, "fp16fml"));
669 EXPECT_FALSE(testARMExtension("cortex-r52", ARM::ArchKind::INVALID, "ras"));
670 EXPECT_FALSE(
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"));
700 EXPECT_FALSE(
701 testARMExtension("generic", ARM::ArchKind::ARMV8MBaseline, "crc"));
702 EXPECT_FALSE(
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));
718 else
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));
729 else
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));
741 else
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) {
762 // test +extension
763 Features.clear();
764 ARM::getExtensionFeatures(E.first, Features);
765 EXPECT_TRUE(llvm::is_contained(Features, E.second.at(0)));
766 EXPECT_EQ(Extensions.size(), Features.size());
768 // test -extension
769 Features.clear();
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));
783 else
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]));
818 static bool
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,
825 Features, FPUKind))
826 return false;
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",
859 "v8.1m.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));
876 if (i >= 4) {
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]));
909 break;
910 case ARM::ArchKind::ARMV7R:
911 case ARM::ArchKind::ARMV8R:
912 EXPECT_EQ(ARM::ProfileKind::R, ARM::parseArchProfile(ARMArch[i]));
913 break;
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]));
935 break;
936 default:
937 EXPECT_EQ(ARM::ProfileKind::INVALID, ARM::parseArchProfile(ARMArch[i]));
938 break;
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]));
947 else
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"
1020 " crypto\n"
1021 " sha2\n";
1023 StringMap<StringRef> DummyMap;
1024 DummyMap["crc"] = "This is a long dummy description";
1026 outs().flush();
1027 testing::internal::CaptureStdout();
1028 ARM::PrintSupportedExtensions(DummyMap);
1029 outs().flush();
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,
1049 /*ignored*/ "", {},
1050 /*ignored*/ "") {}
1051 /// Print a gtest-compatible facsimile of the CPUName, to make the test's name
1052 /// human-readable.
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))
1060 C = '_';
1061 return Name;
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);
1072 EXPECT_TRUE(Cpu);
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);
1201 if (!Extension)
1202 return false;
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);
1210 if (!Extension)
1211 return false;
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)
1343 ExtVal.set(Ext);
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
1444 // result.
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) {
1473 EXPECT_EQ(*A, *A);
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 : {
1483 &AArch64::ARMV8_1A,
1484 &AArch64::ARMV8_2A,
1485 &AArch64::ARMV8_3A,
1486 &AArch64::ARMV8_4A,
1487 &AArch64::ARMV8_5A,
1488 &AArch64::ARMV8_6A,
1489 &AArch64::ARMV8_7A,
1490 &AArch64::ARMV8_8A,
1491 &AArch64::ARMV8_9A,
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) "
1612 " Description\n";
1614 outs().flush();
1615 testing::internal::CaptureStdout();
1616 AArch64::PrintSupportedExtensions();
1617 outs().flush();
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 {
1644 StringRef CPUName;
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 = "+";
1669 PosString += E;
1670 std::string NegString = "-";
1671 NegString += E;
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 = "+";
1678 PosString += E;
1679 ASSERT_THAT(Features, Not(Contains(StrEq(PosString))));
1680 // Features default to off, so the negative string is not expected in many
1681 // cases.
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);
1692 EXPECT_TRUE(CPU);
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 = "+";
1703 PosString += E;
1704 std::string NegString = "-";
1705 NegString += E;
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 = "+";
1712 PosString += E;
1713 ASSERT_THAT(Features, Not(Contains(StrEq(PosString))));
1714 // Features default to off, so the negative string is not expected in many
1715 // cases.
1719 AArch64ExtensionDependenciesBaseArchTestParams
1720 AArch64ExtensionDependenciesArchData[] = {
1721 // Base architecture features
1722 {AArch64::ARMV8A, {}, {"v8a", "fp-armv8", "neon"}, {}},
1723 {AArch64::ARMV8_1A,
1725 {"v8.1a", "crc", "fp-armv8", "lse", "rdm", "neon"},
1726 {}},
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"}},
1736 // Mixed modifiers
1737 {AArch64::ARMV8A,
1738 {"fp16", "nofp16"},
1739 {"v8a", "fp-armv8", "neon"},
1740 {"fullfp16"}},
1741 {AArch64::ARMV8A,
1742 {"fp16", "nofp"},
1743 {"v8a"},
1744 {"fp-armv8", "neon", "fullfp16"}},
1746 // Long dependency chains: sve2-bitperm -> sve2 -> sve -> fp16 -> fp
1747 {AArch64::ARMV8A,
1748 {"nofp", "sve2-bitperm"},
1749 {"fp-armv8", "fullfp16", "sve", "sve2", "sve2-bitperm"},
1750 {}},
1751 {AArch64::ARMV8A,
1752 {"sve2-bitperm", "nofp16"},
1753 {"fp-armv8"},
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
1762 // enable them.
1763 {AArch64::ARMV8A,
1764 {"aes", "sha2", "sha3", "sm4", "nocrypto"},
1766 {"aes", "sha2", "sha3", "sm4"}},
1767 {AArch64::ARMV8_4A,
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"}, {}},
1777 // fp -> fp16
1778 {AArch64::ARMV8A, {"nofp", "fp16"}, {"fp-armv8", "fullfp16"}, {}},
1779 {AArch64::ARMV8A, {"fp16", "nofp"}, {}, {"fp-armv8", "fullfp16"}},
1781 // fp -> simd
1782 {AArch64::ARMV8A, {"nofp", "simd"}, {"fp-armv8", "neon"}, {}},
1783 {AArch64::ARMV8A, {"simd", "nofp"}, {}, {"fp-armv8", "neon"}},
1785 // fp -> jscvt
1786 {AArch64::ARMV8A, {"nofp", "jscvt"}, {"fp-armv8", "jsconv"}, {}},
1787 {AArch64::ARMV8A, {"jscvt", "nofp"}, {}, {"fp-armv8", "jsconv"}},
1789 // fp -> lsfe
1790 {AArch64::ARMV9_6A, {"nofp", "lsfe"}, {"fp-armv8", "lsfe"}, {}},
1791 {AArch64::ARMV9_6A, {"lsfe", "nofp"}, {}, {"fp-armv8", "lsfe"}},
1793 // fp -> fprcvt
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"}},
1825 // bf16 -> {sme}
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"}},
1836 {AArch64::ARMV9_6A,
1837 {"nosve", "sve-f16f32mm"},
1838 {"sve", "sve-f16f32mm"},
1839 {}},
1840 {AArch64::ARMV9_6A,
1841 {"sve-f16f32mm", "nosve"},
1843 {"sve", "sve-f16f32mm"}},
1845 // aes -> {sve-aes}
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"}},
1852 {AArch64::ARMV8A,
1853 {"nosve2", "sve2-bitperm"},
1854 {"sve2", "sve2-bitperm"},
1855 {}},
1856 {AArch64::ARMV8A,
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}
1868 {AArch64::ARMV9_4A,
1869 {"nosve-b16b16", "sme-b16b16"},
1870 {"sve-b16b16", "sme-b16b16"},
1871 {}},
1872 {AArch64::ARMV9_4A,
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"}},
1897 {AArch64::ARMV8A,
1898 {"nosme2", "ssve-fp8fma"},
1899 {"sme2", "ssve-fp8fma"},
1900 {}},
1901 {AArch64::ARMV8A,
1902 {"ssve-fp8fma", "nosme2"},
1904 {"sme2", "ssve-fp8fma"}},
1905 {AArch64::ARMV8A,
1906 {"nosme2", "ssve-fp8dot2"},
1907 {"sme2", "ssve-fp8dot2"},
1908 {}},
1909 {AArch64::ARMV8A,
1910 {"ssve-fp8dot2", "nosme2"},
1912 {"sme2", "ssve-fp8dot2"}},
1913 {AArch64::ARMV8A,
1914 {"nosme2", "ssve-fp8dot4"},
1915 {"sme2", "ssve-fp8dot4"},
1916 {}},
1917 {AArch64::ARMV8A,
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"}},
1944 // lse -> lse128
1945 {AArch64::ARMV8A, {"nolse", "lse128"}, {"lse", "lse128"}, {}},
1946 {AArch64::ARMV8A, {"lse128", "nolse"}, {}, {"lse", "lse128"}},
1948 // predres -> predres2
1949 {AArch64::ARMV8A,
1950 {"nopredres", "predres2"},
1951 {"predres", "specres2"},
1952 {}},
1953 {AArch64::ARMV8A,
1954 {"predres2", "nopredres"},
1956 {"predres", "specres2"}},
1958 // ras -> ras2
1959 {AArch64::ARMV8A, {"noras", "rasv2"}, {"ras", "rasv2"}, {}},
1960 {AArch64::ARMV8A, {"rasv2", "noras"}, {}, {"ras", "rasv2"}},
1962 // rcpc -> rcpc3
1963 {AArch64::ARMV8A, {"norcpc", "rcpc3"}, {"rcpc", "rcpc3"}, {}},
1964 {AArch64::ARMV8A, {"rcpc3", "norcpc"}, {}, {"rcpc", "rcpc3"}},
1966 // sve-aes -> {ssve-aes, sve2-aes}
1967 {AArch64::ARMV9_6A,
1968 {"nosve-aes", "ssve-aes"},
1969 {"sve-aes", "ssve-aes"},
1970 {}},
1971 {AArch64::ARMV9_6A,
1972 {"ssve-aes", "nosve-aes"},
1974 {"ssve-aes", "sve-aes"}},
1975 {AArch64::ARMV9_6A,
1976 {"nosve-aes", "sve2-aes"},
1977 {"sve2-aes", "sve-aes"},
1978 {}},
1979 {AArch64::ARMV9_6A,
1980 {"sve2-aes", "nosve-aes"},
1982 {"sve2-aes", "sve-aes"}},
1984 // -sve2-aes should disable sve-aes (only)
1985 {AArch64::ARMV9_6A,
1986 {"sve2", "sve-aes", "nosve2-aes"},
1987 {"sve2"},
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
1998 {"cortex-a57",
2000 {"v8a", "aes", "crc", "fp-armv8", "sha2", "neon"},
2001 {}},
2002 {"cortex-r82",
2004 {"v8r", "crc", "dotprod", "fp-armv8", "fullfp16", "fp16fml", "lse",
2005 "ras", "rcpc", "rdm", "sb", "neon", "ssbs"},
2006 {}},
2007 {"cortex-a520",
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"},
2013 {}},
2015 // Negative modifiers
2016 {"cortex-r82",
2017 {"nofp"},
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));
2027 } // namespace