[MLIR][NVVM] Add Op for TMA Store with reduction (#118853)
[llvm-project.git] / llvm / unittests / TargetParser / TargetParserTest.cpp
blob1f69190e4bec53416ce23a25c5c2d6c81d7e3989
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-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,
414 "9-A"),
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,
422 "9-A"),
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,
428 "8.2-A"),
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,
434 "8.2-A"),
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,
440 "8.2-A"),
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,
446 "8.2-A"),
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,
452 "8.2-A"),
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,
458 "8.2-A"),
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,
465 "9-A"),
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,
471 "8.4-A"),
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,
476 "8-A"),
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,
482 "8-A"),
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,
488 "8.2-A"),
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,
494 "8.2-A"),
495 ARMCPUTestParams<uint64_t>("cortex-m23", "armv8-m.base", "none",
496 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB,
497 "8-M.Baseline"),
498 ARMCPUTestParams<uint64_t>("cortex-m33", "armv8-m.main", "fpv5-sp-d16",
499 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
500 "8-M.Mainline"),
501 ARMCPUTestParams<uint64_t>("star-mc1", "armv8-m.main", "fpv5-sp-d16",
502 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
503 "8-M.Mainline"),
504 ARMCPUTestParams<uint64_t>("cortex-m35p", "armv8-m.main", "fpv5-sp-d16",
505 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
506 "8-M.Mainline"),
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,
511 "8.1-M.Mainline"),
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,
516 "8.1-M.Mainline"),
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,
521 "8.1-M.Mainline"),
522 ARMCPUTestParams<uint64_t>("iwmmxt", "iwmmxt", "none", ARM::AEK_NONE,
523 "iwmmxt"),
524 ARMCPUTestParams<uint64_t>("xscale", "xscale", "none", ARM::AEK_NONE,
525 "xscale"),
526 ARMCPUTestParams<uint64_t>("swift", "armv7s", "neon-vfpv4",
527 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
528 ARM::AEK_DSP,
529 "7-S")),
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,
553 unsigned ArchAttr) {
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);
559 return Result;
562 TEST(TargetParserTest, testARMArch) {
563 EXPECT_TRUE(
564 testARMArch("armv4", "strongarm", "v4", ARMBuildAttrs::CPUArch::v4));
565 EXPECT_TRUE(
566 testARMArch("armv4t", "arm7tdmi", "v4t", ARMBuildAttrs::CPUArch::v4T));
567 EXPECT_TRUE(
568 testARMArch("armv5t", "arm10tdmi", "v5", ARMBuildAttrs::CPUArch::v5T));
569 EXPECT_TRUE(
570 testARMArch("armv5te", "arm1022e", "v5e", ARMBuildAttrs::CPUArch::v5TE));
571 EXPECT_TRUE(testARMArch("armv5tej", "arm926ej-s", "v5e",
572 ARMBuildAttrs::CPUArch::v5TEJ));
573 EXPECT_TRUE(
574 testARMArch("armv6", "arm1136jf-s", "v6", ARMBuildAttrs::CPUArch::v6));
575 EXPECT_TRUE(
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));
581 EXPECT_TRUE(
582 testARMArch("armv6-m", "cortex-m0", "v6m", ARMBuildAttrs::CPUArch::v6_M));
583 EXPECT_TRUE(
584 testARMArch("armv7-a", "generic", "v7", ARMBuildAttrs::CPUArch::v7));
585 EXPECT_TRUE(
586 testARMArch("armv7ve", "generic", "v7ve", ARMBuildAttrs::CPUArch::v7));
587 EXPECT_TRUE(
588 testARMArch("armv7-r", "cortex-r4", "v7r", ARMBuildAttrs::CPUArch::v7));
589 EXPECT_TRUE(
590 testARMArch("armv7-m", "cortex-m3", "v7m", ARMBuildAttrs::CPUArch::v7));
591 EXPECT_TRUE(testARMArch("armv7e-m", "cortex-m4", "v7em",
592 ARMBuildAttrs::CPUArch::v7E_M));
593 EXPECT_TRUE(
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));
613 EXPECT_TRUE(
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));
627 EXPECT_TRUE(
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));
635 EXPECT_TRUE(
636 testARMArch("iwmmxt", "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE));
637 EXPECT_TRUE(
638 testARMArch("iwmmxt2", "generic", "", ARMBuildAttrs::CPUArch::v5TE));
639 EXPECT_TRUE(
640 testARMArch("xscale", "xscale", "v5e", ARMBuildAttrs::CPUArch::v5TE));
641 EXPECT_TRUE(
642 testARMArch("armv7s", "swift", "v7s", ARMBuildAttrs::CPUArch::v7));
643 EXPECT_TRUE(
644 testARMArch("armv7k", "generic", "v7k", ARMBuildAttrs::CPUArch::v7));
647 bool testARMExtension(StringRef CPUName, ARM::ArchKind ArchKind,
648 StringRef ArchExt) {
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"));
659 EXPECT_FALSE(
660 testARMExtension("arm1136jf-s", ARM::ArchKind::INVALID, "crypto"));
661 EXPECT_FALSE(
662 testARMExtension("arm1156t2-s", ARM::ArchKind::INVALID, "crypto"));
663 EXPECT_FALSE(
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"));
672 EXPECT_FALSE(
673 testARMExtension("cortex-a55", ARM::ArchKind::INVALID, "fp16fml"));
674 EXPECT_TRUE(testARMExtension("cortex-a75", ARM::ArchKind::INVALID, "fp16"));
675 EXPECT_FALSE(
676 testARMExtension("cortex-a75", ARM::ArchKind::INVALID, "fp16fml"));
677 EXPECT_FALSE(testARMExtension("cortex-r52", ARM::ArchKind::INVALID, "ras"));
678 EXPECT_FALSE(
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"));
708 EXPECT_FALSE(
709 testARMExtension("generic", ARM::ArchKind::ARMV8MBaseline, "crc"));
710 EXPECT_FALSE(
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));
726 else
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));
737 else
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));
749 else
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) {
770 // test +extension
771 Features.clear();
772 ARM::getExtensionFeatures(E.first, Features);
773 EXPECT_TRUE(llvm::is_contained(Features, E.second.at(0)));
774 EXPECT_EQ(Extensions.size(), Features.size());
776 // test -extension
777 Features.clear();
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));
791 else
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]));
826 static bool
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,
833 Features, FPUKind))
834 return false;
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",
867 "v8.1m.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));
884 if (i >= 4) {
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]));
917 break;
918 case ARM::ArchKind::ARMV7R:
919 case ARM::ArchKind::ARMV8R:
920 EXPECT_EQ(ARM::ProfileKind::R, ARM::parseArchProfile(ARMArch[i]));
921 break;
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]));
943 break;
944 default:
945 EXPECT_EQ(ARM::ProfileKind::INVALID, ARM::parseArchProfile(ARMArch[i]));
946 break;
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]));
955 else
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"
1028 " crypto\n"
1029 " sha2\n";
1031 StringMap<StringRef> DummyMap;
1032 DummyMap["crc"] = "This is a long dummy description";
1034 outs().flush();
1035 testing::internal::CaptureStdout();
1036 ARM::PrintSupportedExtensions(DummyMap);
1037 outs().flush();
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,
1057 /*ignored*/ "", {},
1058 /*ignored*/ "") {}
1059 /// Print a gtest-compatible facsimile of the CPUName, to make the test's name
1060 /// human-readable.
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))
1068 C = '_';
1069 return Name;
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);
1080 EXPECT_TRUE(Cpu);
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);
1210 if (!Extension)
1211 return false;
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);
1219 if (!Extension)
1220 return false;
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)
1352 ExtVal.set(Ext);
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
1453 // result.
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) {
1482 EXPECT_EQ(*A, *A);
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 : {
1492 &AArch64::ARMV8_1A,
1493 &AArch64::ARMV8_2A,
1494 &AArch64::ARMV8_3A,
1495 &AArch64::ARMV8_4A,
1496 &AArch64::ARMV8_5A,
1497 &AArch64::ARMV8_6A,
1498 &AArch64::ARMV8_7A,
1499 &AArch64::ARMV8_8A,
1500 &AArch64::ARMV8_9A,
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) "
1621 " Description\n";
1623 outs().flush();
1624 testing::internal::CaptureStdout();
1625 AArch64::PrintSupportedExtensions();
1626 outs().flush();
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 {
1653 StringRef CPUName;
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 = "+";
1678 PosString += E;
1679 std::string NegString = "-";
1680 NegString += E;
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 = "+";
1687 PosString += E;
1688 ASSERT_THAT(Features, Not(Contains(StrEq(PosString))));
1689 // Features default to off, so the negative string is not expected in many
1690 // cases.
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);
1701 EXPECT_TRUE(CPU);
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 = "+";
1712 PosString += E;
1713 std::string NegString = "-";
1714 NegString += E;
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 = "+";
1721 PosString += E;
1722 ASSERT_THAT(Features, Not(Contains(StrEq(PosString))));
1723 // Features default to off, so the negative string is not expected in many
1724 // cases.
1728 AArch64ExtensionDependenciesBaseArchTestParams
1729 AArch64ExtensionDependenciesArchData[] = {
1730 // Base architecture features
1731 {AArch64::ARMV8A, {}, {"v8a", "fp-armv8", "neon"}, {}},
1732 {AArch64::ARMV8_1A,
1734 {"v8.1a", "crc", "fp-armv8", "lse", "rdm", "neon"},
1735 {}},
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"}},
1745 // Mixed modifiers
1746 {AArch64::ARMV8A,
1747 {"fp16", "nofp16"},
1748 {"v8a", "fp-armv8", "neon"},
1749 {"fullfp16"}},
1750 {AArch64::ARMV8A,
1751 {"fp16", "nofp"},
1752 {"v8a"},
1753 {"fp-armv8", "neon", "fullfp16"}},
1755 // Long dependency chains: sve2-bitperm -> sve2 -> sve -> fp16 -> fp
1756 {AArch64::ARMV8A,
1757 {"nofp", "sve2-bitperm"},
1758 {"fp-armv8", "fullfp16", "sve", "sve2", "sve2-bitperm"},
1759 {}},
1760 {AArch64::ARMV8A,
1761 {"sve2-bitperm", "nofp16"},
1762 {"fp-armv8"},
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
1771 // enable them.
1772 {AArch64::ARMV8A,
1773 {"aes", "sha2", "sha3", "sm4", "nocrypto"},
1775 {"aes", "sha2", "sha3", "sm4"}},
1776 {AArch64::ARMV8_4A,
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"}, {}},
1786 // fp -> fp16
1787 {AArch64::ARMV8A, {"nofp", "fp16"}, {"fp-armv8", "fullfp16"}, {}},
1788 {AArch64::ARMV8A, {"fp16", "nofp"}, {}, {"fp-armv8", "fullfp16"}},
1790 // fp -> simd
1791 {AArch64::ARMV8A, {"nofp", "simd"}, {"fp-armv8", "neon"}, {}},
1792 {AArch64::ARMV8A, {"simd", "nofp"}, {}, {"fp-armv8", "neon"}},
1794 // fp -> jscvt
1795 {AArch64::ARMV8A, {"nofp", "jscvt"}, {"fp-armv8", "jsconv"}, {}},
1796 {AArch64::ARMV8A, {"jscvt", "nofp"}, {}, {"fp-armv8", "jsconv"}},
1798 // fp -> lsfe
1799 {AArch64::ARMV9_6A, {"nofp", "lsfe"}, {"fp-armv8", "lsfe"}, {}},
1800 {AArch64::ARMV9_6A, {"lsfe", "nofp"}, {}, {"fp-armv8", "lsfe"}},
1802 // fp -> fprcvt
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"}},
1834 // bf16 -> {sme}
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"}},
1845 {AArch64::ARMV9_6A,
1846 {"nosve", "sve-f16f32mm"},
1847 {"sve", "sve-f16f32mm"},
1848 {}},
1849 {AArch64::ARMV9_6A,
1850 {"sve-f16f32mm", "nosve"},
1852 {"sve", "sve-f16f32mm"}},
1854 // aes -> {sve-aes}
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"}},
1861 {AArch64::ARMV8A,
1862 {"nosve2", "sve2-bitperm"},
1863 {"sve2", "sve2-bitperm"},
1864 {}},
1865 {AArch64::ARMV8A,
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}
1877 {AArch64::ARMV9_4A,
1878 {"nosve-b16b16", "sme-b16b16"},
1879 {"sve-b16b16", "sme-b16b16"},
1880 {}},
1881 {AArch64::ARMV9_4A,
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"}},
1906 {AArch64::ARMV8A,
1907 {"nosme2", "ssve-fp8fma"},
1908 {"sme2", "ssve-fp8fma"},
1909 {}},
1910 {AArch64::ARMV8A,
1911 {"ssve-fp8fma", "nosme2"},
1913 {"sme2", "ssve-fp8fma"}},
1914 {AArch64::ARMV8A,
1915 {"nosme2", "ssve-fp8dot2"},
1916 {"sme2", "ssve-fp8dot2"},
1917 {}},
1918 {AArch64::ARMV8A,
1919 {"ssve-fp8dot2", "nosme2"},
1921 {"sme2", "ssve-fp8dot2"}},
1922 {AArch64::ARMV8A,
1923 {"nosme2", "ssve-fp8dot4"},
1924 {"sme2", "ssve-fp8dot4"},
1925 {}},
1926 {AArch64::ARMV8A,
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"}},
1953 // lse -> lse128
1954 {AArch64::ARMV8A, {"nolse", "lse128"}, {"lse", "lse128"}, {}},
1955 {AArch64::ARMV8A, {"lse128", "nolse"}, {}, {"lse", "lse128"}},
1957 // predres -> predres2
1958 {AArch64::ARMV8A,
1959 {"nopredres", "predres2"},
1960 {"predres", "specres2"},
1961 {}},
1962 {AArch64::ARMV8A,
1963 {"predres2", "nopredres"},
1965 {"predres", "specres2"}},
1967 // ras -> ras2
1968 {AArch64::ARMV8A, {"noras", "rasv2"}, {"ras", "rasv2"}, {}},
1969 {AArch64::ARMV8A, {"rasv2", "noras"}, {}, {"ras", "rasv2"}},
1971 // rcpc -> rcpc3
1972 {AArch64::ARMV8A, {"norcpc", "rcpc3"}, {"rcpc", "rcpc3"}, {}},
1973 {AArch64::ARMV8A, {"rcpc3", "norcpc"}, {}, {"rcpc", "rcpc3"}},
1975 // sve-aes -> {ssve-aes, sve2-aes}
1976 {AArch64::ARMV9_6A,
1977 {"nosve-aes", "ssve-aes"},
1978 {"sve-aes", "ssve-aes"},
1979 {}},
1980 {AArch64::ARMV9_6A,
1981 {"ssve-aes", "nosve-aes"},
1983 {"ssve-aes", "sve-aes"}},
1984 {AArch64::ARMV9_6A,
1985 {"nosve-aes", "sve2-aes"},
1986 {"sve2-aes", "sve-aes"},
1987 {}},
1988 {AArch64::ARMV9_6A,
1989 {"sve2-aes", "nosve-aes"},
1991 {"sve2-aes", "sve-aes"}},
1993 // -sve2-aes should disable sve-aes (only)
1994 {AArch64::ARMV9_6A,
1995 {"sve2", "sve-aes", "nosve2-aes"},
1996 {"sve2"},
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
2007 {"cortex-a57",
2009 {"v8a", "aes", "crc", "fp-armv8", "sha2", "neon"},
2010 {}},
2011 {"cortex-r82",
2013 {"v8r", "crc", "dotprod", "fp-armv8", "fullfp16", "fp16fml", "lse",
2014 "ras", "rcpc", "rdm", "sb", "neon", "ssbs"},
2015 {}},
2016 {"cortex-a520",
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"},
2022 {}},
2024 // Negative modifiers
2025 {"cortex-r82",
2026 {"nofp"},
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));
2036 } // namespace