[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / unittests / Support / TargetParserTest.cpp
bloba7dd672d92a4f0ca4873c2b0e2f3c861d58ee5eb
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/ADT/STLExtras.h"
10 #include "llvm/ADT/StringExtras.h"
11 #include "llvm/Support/AArch64TargetParser.h"
12 #include "llvm/Support/ARMBuildAttributes.h"
13 #include "llvm/Support/FormatVariadic.h"
14 #include "llvm/Support/TargetParser.h"
15 #include "gmock/gmock.h"
16 #include "gtest/gtest.h"
17 #include <string>
19 using namespace llvm;
21 namespace {
22 const char *ARMArch[] = {
23 "armv2", "armv2a", "armv3", "armv3m", "armv4",
24 "armv4t", "armv5", "armv5t", "armv5e", "armv5te",
25 "armv5tej", "armv6", "armv6j", "armv6k", "armv6hl",
26 "armv6t2", "armv6kz", "armv6z", "armv6zk", "armv6-m",
27 "armv6m", "armv6sm", "armv6s-m", "armv7-a", "armv7",
28 "armv7a", "armv7ve", "armv7hl", "armv7l", "armv7-r",
29 "armv7r", "armv7-m", "armv7m", "armv7k", "armv7s",
30 "armv7e-m", "armv7em", "armv8-a", "armv8", "armv8a",
31 "armv8l", "armv8.1-a", "armv8.1a", "armv8.2-a", "armv8.2a",
32 "armv8.3-a", "armv8.3a", "armv8.4-a", "armv8.4a", "armv8.5-a",
33 "armv8.5a", "armv8.6-a", "armv8.6a", "armv8.7-a", "armv8.7a",
34 "armv8.8-a", "armv8.8a", "armv8-r", "armv8r", "armv8-m.base",
35 "armv8m.base", "armv8-m.main", "armv8m.main", "iwmmxt", "iwmmxt2",
36 "xscale", "armv8.1-m.main", "armv9-a", "armv9", "armv9a",
37 "armv9.1-a", "armv9.1a", "armv9.2-a", "armv9.2a",
40 template <ARM::ISAKind ISAKind>
41 std::string FormatExtensionFlags(uint64_t Flags) {
42 std::vector<StringRef> Features;
44 if (ISAKind == ARM::ISAKind::AARCH64) {
45 // AEK_NONE is not meant to be shown to the user so the target parser
46 // does not recognise it. It is relevant here though.
47 if (Flags & AArch64::AEK_NONE)
48 Features.push_back("none");
49 AArch64::getExtensionFeatures(Flags, Features);
50 } else {
51 if (Flags & ARM::AEK_NONE)
52 Features.push_back("none");
53 ARM::getExtensionFeatures(Flags, Features);
56 // The target parser also includes every extension you don't have.
57 // E.g. if AEK_CRC is not set then it adds "-crc". Not useful here.
58 Features.erase(std::remove_if(Features.begin(), Features.end(),
59 [](StringRef extension) {
60 return extension.startswith("-");
61 }),
62 Features.end());
64 return llvm::join(Features, ", ");
67 template <ARM::ISAKind ISAKind>
68 testing::AssertionResult
69 AssertSameExtensionFlags(const char *m_expr, const char *n_expr,
70 uint64_t ExpectedFlags, uint64_t GotFlags) {
71 if (ExpectedFlags == GotFlags)
72 return testing::AssertionSuccess();
74 return testing::AssertionFailure() << llvm::formatv(
75 "Expected extension flags: {0} ({1:x})\n"
76 " Got extension flags: {2} ({3:x})\n",
77 FormatExtensionFlags<ISAKind>(ExpectedFlags), ExpectedFlags,
78 FormatExtensionFlags<ISAKind>(GotFlags), GotFlags);
81 struct ARMCPUTestParams {
82 ARMCPUTestParams(StringRef CPUName, StringRef ExpectedArch,
83 StringRef ExpectedFPU, uint64_t ExpectedFlags,
84 StringRef CPUAttr)
85 : CPUName(CPUName), ExpectedArch(ExpectedArch), ExpectedFPU(ExpectedFPU),
86 ExpectedFlags(ExpectedFlags), CPUAttr(CPUAttr) {}
88 friend std::ostream &operator<<(std::ostream &os,
89 const ARMCPUTestParams &params) {
90 return os << "\"" << params.CPUName.str() << "\", \""
91 << params.ExpectedArch.str() << "\", \""
92 << params.ExpectedFPU.str() << "\", 0x" << std::hex
93 << params.ExpectedFlags << ", \"" << params.CPUAttr.str() << "\"";
96 StringRef CPUName;
97 StringRef ExpectedArch;
98 StringRef ExpectedFPU;
99 uint64_t ExpectedFlags;
100 StringRef CPUAttr;
103 class ARMCPUTestFixture : public ::testing::TestWithParam<ARMCPUTestParams> {};
105 TEST_P(ARMCPUTestFixture, ARMCPUTests) {
106 auto params = GetParam();
108 ARM::ArchKind AK = ARM::parseCPUArch(params.CPUName);
109 EXPECT_EQ(params.ExpectedArch, ARM::getArchName(AK));
111 unsigned FPUKind = ARM::getDefaultFPU(params.CPUName, AK);
112 EXPECT_EQ(params.ExpectedFPU, ARM::getFPUName(FPUKind));
114 uint64_t default_extensions = ARM::getDefaultExtensions(params.CPUName, AK);
115 EXPECT_PRED_FORMAT2(AssertSameExtensionFlags<ARM::ISAKind::ARM>,
116 params.ExpectedFlags, default_extensions);
118 EXPECT_EQ(params.CPUAttr, ARM::getCPUAttr(AK));
121 // Note that we include ARM::AEK_NONE even when there are other extensions
122 // we expect. This is because the default extensions for a CPU are the sum
123 // of the default extensions for its architecture and for the CPU.
124 // So if a CPU has no extra extensions, it adds AEK_NONE.
125 INSTANTIATE_TEST_SUITE_P(
126 ARMCPUTestsPart1, ARMCPUTestFixture,
127 ::testing::Values(
128 ARMCPUTestParams("invalid", "invalid", "invalid", ARM::AEK_NONE, ""),
129 ARMCPUTestParams("generic", "invalid", "none", ARM::AEK_NONE, ""),
131 ARMCPUTestParams("arm8", "armv4", "none", ARM::AEK_NONE, "4"),
132 ARMCPUTestParams("arm810", "armv4", "none", ARM::AEK_NONE, "4"),
133 ARMCPUTestParams("strongarm", "armv4", "none", ARM::AEK_NONE, "4"),
134 ARMCPUTestParams("strongarm110", "armv4", "none", ARM::AEK_NONE, "4"),
135 ARMCPUTestParams("strongarm1100", "armv4", "none", ARM::AEK_NONE, "4"),
136 ARMCPUTestParams("strongarm1110", "armv4", "none", ARM::AEK_NONE, "4"),
137 ARMCPUTestParams("arm7tdmi", "armv4t", "none", ARM::AEK_NONE, "4T"),
138 ARMCPUTestParams("arm7tdmi-s", "armv4t", "none", ARM::AEK_NONE, "4T"),
139 ARMCPUTestParams("arm710t", "armv4t", "none", ARM::AEK_NONE, "4T"),
140 ARMCPUTestParams("arm720t", "armv4t", "none", ARM::AEK_NONE, "4T"),
141 ARMCPUTestParams("arm9", "armv4t", "none", ARM::AEK_NONE, "4T"),
142 ARMCPUTestParams("arm9tdmi", "armv4t", "none", ARM::AEK_NONE, "4T"),
143 ARMCPUTestParams("arm920", "armv4t", "none", ARM::AEK_NONE, "4T"),
144 ARMCPUTestParams("arm920t", "armv4t", "none", ARM::AEK_NONE, "4T"),
145 ARMCPUTestParams("arm922t", "armv4t", "none", ARM::AEK_NONE, "4T"),
146 ARMCPUTestParams("arm940t", "armv4t", "none", ARM::AEK_NONE, "4T"),
147 ARMCPUTestParams("ep9312", "armv4t", "none", ARM::AEK_NONE, "4T"),
148 ARMCPUTestParams("arm10tdmi", "armv5t", "none", ARM::AEK_NONE, "5T"),
149 ARMCPUTestParams("arm1020t", "armv5t", "none", ARM::AEK_NONE, "5T"),
150 ARMCPUTestParams("arm9e", "armv5te", "none",
151 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
152 ARMCPUTestParams("arm946e-s", "armv5te", "none",
153 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
154 ARMCPUTestParams("arm966e-s", "armv5te", "none",
155 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
156 ARMCPUTestParams("arm968e-s", "armv5te", "none",
157 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
158 ARMCPUTestParams("arm10e", "armv5te", "none",
159 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
160 ARMCPUTestParams("arm1020e", "armv5te", "none",
161 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
162 ARMCPUTestParams("arm1022e", "armv5te", "none",
163 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"),
164 ARMCPUTestParams("arm926ej-s", "armv5tej", "none",
165 ARM::AEK_NONE | ARM::AEK_DSP, "5TEJ"),
166 ARMCPUTestParams("arm1136j-s", "armv6", "none",
167 ARM::AEK_NONE | ARM::AEK_DSP, "6"),
168 ARMCPUTestParams("arm1136jf-s", "armv6", "vfpv2",
169 ARM::AEK_NONE | ARM::AEK_DSP, "6"),
170 ARMCPUTestParams("arm1176jz-s", "armv6kz", "none",
171 ARM::AEK_NONE | ARM::AEK_SEC | ARM::AEK_DSP, "6KZ"),
172 ARMCPUTestParams("mpcore", "armv6k", "vfpv2",
173 ARM::AEK_NONE | ARM::AEK_DSP, "6K"),
174 ARMCPUTestParams("mpcorenovfp", "armv6k", "none",
175 ARM::AEK_NONE | ARM::AEK_DSP, "6K"),
176 ARMCPUTestParams("arm1176jzf-s", "armv6kz", "vfpv2",
177 ARM::AEK_NONE | ARM::AEK_SEC | ARM::AEK_DSP, "6KZ"),
178 ARMCPUTestParams("arm1156t2-s", "armv6t2", "none",
179 ARM::AEK_NONE | ARM::AEK_DSP, "6T2"),
180 ARMCPUTestParams("arm1156t2f-s", "armv6t2", "vfpv2",
181 ARM::AEK_NONE | ARM::AEK_DSP, "6T2"),
182 ARMCPUTestParams("cortex-m0", "armv6-m", "none", ARM::AEK_NONE, "6-M"),
183 ARMCPUTestParams("cortex-m0plus", "armv6-m", "none", ARM::AEK_NONE,
184 "6-M"),
185 ARMCPUTestParams("cortex-m1", "armv6-m", "none", ARM::AEK_NONE, "6-M"),
186 ARMCPUTestParams("sc000", "armv6-m", "none", ARM::AEK_NONE, "6-M"),
187 ARMCPUTestParams("cortex-a5", "armv7-a", "neon-vfpv4",
188 ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP, "7-A"),
189 ARMCPUTestParams("cortex-a7", "armv7-a", "neon-vfpv4",
190 ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM | ARM::AEK_MP |
191 ARM::AEK_SEC | ARM::AEK_VIRT | ARM::AEK_DSP,
192 "7-A"),
193 ARMCPUTestParams("cortex-a8", "armv7-a", "neon",
194 ARM::AEK_SEC | ARM::AEK_DSP, "7-A")));
196 // gtest in llvm has a limit of 50 test cases when using ::Values so we split
197 // them into 2 blocks
198 INSTANTIATE_TEST_SUITE_P(
199 ARMCPUTestsPart2, ARMCPUTestFixture,
200 ::testing::Values(
201 ARMCPUTestParams("cortex-a9", "armv7-a", "neon-fp16",
202 ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP, "7-A"),
203 ARMCPUTestParams("cortex-a12", "armv7-a", "neon-vfpv4",
204 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
205 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
206 ARM::AEK_DSP,
207 "7-A"),
208 ARMCPUTestParams("cortex-a15", "armv7-a", "neon-vfpv4",
209 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
210 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
211 ARM::AEK_DSP,
212 "7-A"),
213 ARMCPUTestParams("cortex-a17", "armv7-a", "neon-vfpv4",
214 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
215 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
216 ARM::AEK_DSP,
217 "7-A"),
218 ARMCPUTestParams("krait", "armv7-a", "neon-vfpv4",
219 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
220 "7-A"),
221 ARMCPUTestParams("cortex-r4", "armv7-r", "none",
222 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
223 "7-R"),
224 ARMCPUTestParams("cortex-r4f", "armv7-r", "vfpv3-d16",
225 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
226 "7-R"),
227 ARMCPUTestParams("cortex-r5", "armv7-r", "vfpv3-d16",
228 ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
229 ARM::AEK_DSP,
230 "7-R"),
231 ARMCPUTestParams("cortex-r7", "armv7-r", "vfpv3-d16-fp16",
232 ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
233 ARM::AEK_DSP,
234 "7-R"),
235 ARMCPUTestParams("cortex-r8", "armv7-r", "vfpv3-d16-fp16",
236 ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
237 ARM::AEK_DSP,
238 "7-R"),
239 ARMCPUTestParams("cortex-r52", "armv8-r", "neon-fp-armv8",
240 ARM::AEK_NONE | ARM::AEK_CRC | ARM::AEK_MP |
241 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
242 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
243 "8-R"),
244 ARMCPUTestParams("sc300", "armv7-m", "none",
245 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "7-M"),
246 ARMCPUTestParams("cortex-m3", "armv7-m", "none",
247 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "7-M"),
248 ARMCPUTestParams("cortex-m4", "armv7e-m", "fpv4-sp-d16",
249 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
250 "7E-M"),
251 ARMCPUTestParams("cortex-m7", "armv7e-m", "fpv5-d16",
252 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
253 "7E-M"),
254 ARMCPUTestParams("cortex-a32", "armv8-a", "crypto-neon-fp-armv8",
255 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
256 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
257 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
258 "8-A"),
259 ARMCPUTestParams("cortex-a35", "armv8-a", "crypto-neon-fp-armv8",
260 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
261 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
262 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
263 "8-A"),
264 ARMCPUTestParams("cortex-a53", "armv8-a", "crypto-neon-fp-armv8",
265 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
266 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
267 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
268 "8-A"),
269 ARMCPUTestParams("cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",
270 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
271 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
272 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
273 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
274 "8.2-A"),
275 ARMCPUTestParams("cortex-a57", "armv8-a", "crypto-neon-fp-armv8",
276 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
277 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
278 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
279 "8-A"),
280 ARMCPUTestParams("cortex-a72", "armv8-a", "crypto-neon-fp-armv8",
281 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
282 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
283 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
284 "8-A"),
285 ARMCPUTestParams("cortex-a73", "armv8-a", "crypto-neon-fp-armv8",
286 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
287 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
288 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
289 "8-A"),
290 ARMCPUTestParams("cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",
291 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
292 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
293 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
294 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
295 "8.2-A"),
296 ARMCPUTestParams("cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8",
297 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
298 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
299 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
300 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
301 "8.2-A"),
302 ARMCPUTestParams("cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",
303 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
304 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
305 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
306 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
307 "8.2-A"),
308 ARMCPUTestParams("cortex-a78c", "armv8.2-a", "crypto-neon-fp-armv8",
309 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
310 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
311 ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS |
312 ARM::AEK_FP16 | ARM::AEK_DOTPROD,
313 "8.2-A"),
314 ARMCPUTestParams("cortex-a710", "armv9-a", "neon-fp-armv8",
315 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
316 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
317 ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS |
318 ARM::AEK_DOTPROD | ARM::AEK_FP16FML |
319 ARM::AEK_BF16 | ARM::AEK_I8MM | ARM::AEK_SB,
320 "9-A"),
321 ARMCPUTestParams("cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8",
322 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
323 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
324 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
325 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
326 "8.2-A"),
327 ARMCPUTestParams("cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8",
328 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_SEC |
329 ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
330 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC |
331 ARM::AEK_RAS,
332 "8.2-A"),
333 ARMCPUTestParams("cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8",
334 ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD |
335 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
336 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
337 ARM::AEK_DSP | ARM::AEK_CRC,
338 "8.2-A"),
339 ARMCPUTestParams("cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8",
340 ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD |
341 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
342 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
343 ARM::AEK_DSP | ARM::AEK_CRC,
344 "8.2-A"),
345 ARMCPUTestParams("neoverse-n1", "armv8.2-a", "crypto-neon-fp-armv8",
346 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
347 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
348 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
349 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD,
350 "8.2-A"),
351 ARMCPUTestParams("neoverse-n2", "armv8.5-a", "crypto-neon-fp-armv8",
352 ARM::AEK_CRC | ARM::AEK_HWDIVTHUMB |
353 ARM::AEK_HWDIVARM | ARM::AEK_MP | ARM::AEK_SEC |
354 ARM::AEK_VIRT | ARM::AEK_DSP | ARM::AEK_BF16 |
355 ARM::AEK_DOTPROD | ARM::AEK_RAS | ARM::AEK_I8MM |
356 ARM::AEK_SB,
357 "8.5-A"),
358 ARMCPUTestParams("neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8",
359 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
360 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
361 ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS |
362 ARM::AEK_FP16 | ARM::AEK_BF16 | ARM::AEK_DOTPROD,
363 "8.4-A"),
364 ARMCPUTestParams("cyclone", "armv8-a", "crypto-neon-fp-armv8",
365 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
366 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
367 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
368 "8-A"),
369 ARMCPUTestParams("exynos-m3", "armv8-a", "crypto-neon-fp-armv8",
370 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
371 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
372 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
373 "8-A"),
374 ARMCPUTestParams("exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8",
375 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
376 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
377 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
378 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS,
379 "8.2-A"),
380 ARMCPUTestParams("exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
381 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
382 ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
383 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP |
384 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS,
385 "8.2-A"),
386 ARMCPUTestParams("cortex-m23", "armv8-m.base", "none",
387 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "8-M.Baseline"),
388 ARMCPUTestParams("cortex-m33", "armv8-m.main", "fpv5-sp-d16",
389 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "8-M.Mainline"),
390 ARMCPUTestParams("cortex-m35p", "armv8-m.main", "fpv5-sp-d16",
391 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "8-M.Mainline"),
392 ARMCPUTestParams("cortex-m55", "armv8.1-m.main",
393 "fp-armv8-fullfp16-d16",
394 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD |
395 ARM::AEK_FP | ARM::AEK_RAS | ARM::AEK_LOB |
396 ARM::AEK_FP16,
397 "8.1-M.Mainline"),
398 ARMCPUTestParams("cortex-m85", "armv8.1-m.main",
399 "fp-armv8-fullfp16-d16",
400 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD |
401 ARM::AEK_FP | ARM::AEK_RAS | ARM::AEK_LOB |
402 ARM::AEK_FP16 | ARM::AEK_PACBTI,
403 "8.1-M.Mainline"),
404 ARMCPUTestParams("iwmmxt", "iwmmxt", "none", ARM::AEK_NONE, "iwmmxt"),
405 ARMCPUTestParams("xscale", "xscale", "none", ARM::AEK_NONE, "xscale"),
406 ARMCPUTestParams("swift", "armv7s", "neon-vfpv4",
407 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
408 "7-S")));
410 static constexpr unsigned NumARMCPUArchs = 89;
412 TEST(TargetParserTest, testARMCPUArchList) {
413 SmallVector<StringRef, NumARMCPUArchs> List;
414 ARM::fillValidCPUArchList(List);
416 // No list exists for these in this test suite, so ensure all are
417 // valid, and match the expected 'magic' count.
418 EXPECT_EQ(List.size(), NumARMCPUArchs);
419 for(StringRef CPU : List) {
420 EXPECT_NE(ARM::parseCPUArch(CPU), ARM::ArchKind::INVALID);
424 TEST(TargetParserTest, testInvalidARMArch) {
425 auto InvalidArchStrings = {"armv", "armv99", "noarm"};
426 for (const char* InvalidArch : InvalidArchStrings)
427 EXPECT_EQ(ARM::parseArch(InvalidArch), ARM::ArchKind::INVALID);
430 bool testARMArch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch,
431 unsigned ArchAttr) {
432 ARM::ArchKind AK = ARM::parseArch(Arch);
433 bool Result = (AK != ARM::ArchKind::INVALID);
434 Result &= ARM::getDefaultCPU(Arch).equals(DefaultCPU);
435 Result &= ARM::getSubArch(AK).equals(SubArch);
436 Result &= (ARM::getArchAttr(AK) == ArchAttr);
437 return Result;
440 TEST(TargetParserTest, testARMArch) {
441 EXPECT_TRUE(
442 testARMArch("armv2", "generic", "v2", ARMBuildAttrs::CPUArch::Pre_v4));
443 EXPECT_TRUE(
444 testARMArch("armv2a", "generic", "v2a", ARMBuildAttrs::CPUArch::Pre_v4));
445 EXPECT_TRUE(
446 testARMArch("armv3", "generic", "v3", ARMBuildAttrs::CPUArch::Pre_v4));
447 EXPECT_TRUE(
448 testARMArch("armv3m", "generic", "v3m", ARMBuildAttrs::CPUArch::Pre_v4));
449 EXPECT_TRUE(
450 testARMArch("armv4", "strongarm", "v4",
451 ARMBuildAttrs::CPUArch::v4));
452 EXPECT_TRUE(
453 testARMArch("armv4t", "arm7tdmi", "v4t",
454 ARMBuildAttrs::CPUArch::v4T));
455 EXPECT_TRUE(
456 testARMArch("armv5t", "arm10tdmi", "v5",
457 ARMBuildAttrs::CPUArch::v5T));
458 EXPECT_TRUE(
459 testARMArch("armv5te", "arm1022e", "v5e",
460 ARMBuildAttrs::CPUArch::v5TE));
461 EXPECT_TRUE(
462 testARMArch("armv5tej", "arm926ej-s", "v5e",
463 ARMBuildAttrs::CPUArch::v5TEJ));
464 EXPECT_TRUE(
465 testARMArch("armv6", "arm1136jf-s", "v6",
466 ARMBuildAttrs::CPUArch::v6));
467 EXPECT_TRUE(
468 testARMArch("armv6k", "mpcore", "v6k",
469 ARMBuildAttrs::CPUArch::v6K));
470 EXPECT_TRUE(
471 testARMArch("armv6t2", "arm1156t2-s", "v6t2",
472 ARMBuildAttrs::CPUArch::v6T2));
473 EXPECT_TRUE(
474 testARMArch("armv6kz", "arm1176jzf-s", "v6kz",
475 ARMBuildAttrs::CPUArch::v6KZ));
476 EXPECT_TRUE(
477 testARMArch("armv6-m", "cortex-m0", "v6m",
478 ARMBuildAttrs::CPUArch::v6_M));
479 EXPECT_TRUE(
480 testARMArch("armv7-a", "generic", "v7",
481 ARMBuildAttrs::CPUArch::v7));
482 EXPECT_TRUE(
483 testARMArch("armv7ve", "generic", "v7ve",
484 ARMBuildAttrs::CPUArch::v7));
485 EXPECT_TRUE(
486 testARMArch("armv7-r", "cortex-r4", "v7r",
487 ARMBuildAttrs::CPUArch::v7));
488 EXPECT_TRUE(
489 testARMArch("armv7-m", "cortex-m3", "v7m",
490 ARMBuildAttrs::CPUArch::v7));
491 EXPECT_TRUE(
492 testARMArch("armv7e-m", "cortex-m4", "v7em",
493 ARMBuildAttrs::CPUArch::v7E_M));
494 EXPECT_TRUE(
495 testARMArch("armv8-a", "generic", "v8",
496 ARMBuildAttrs::CPUArch::v8_A));
497 EXPECT_TRUE(
498 testARMArch("armv8.1-a", "generic", "v8.1a",
499 ARMBuildAttrs::CPUArch::v8_A));
500 EXPECT_TRUE(
501 testARMArch("armv8.2-a", "generic", "v8.2a",
502 ARMBuildAttrs::CPUArch::v8_A));
503 EXPECT_TRUE(
504 testARMArch("armv8.3-a", "generic", "v8.3a",
505 ARMBuildAttrs::CPUArch::v8_A));
506 EXPECT_TRUE(
507 testARMArch("armv8.4-a", "generic", "v8.4a",
508 ARMBuildAttrs::CPUArch::v8_A));
509 EXPECT_TRUE(
510 testARMArch("armv8.5-a", "generic", "v8.5a",
511 ARMBuildAttrs::CPUArch::v8_A));
512 EXPECT_TRUE(
513 testARMArch("armv8.6-a", "generic", "v8.6a",
514 ARMBuildAttrs::CPUArch::v8_A));
515 EXPECT_TRUE(
516 testARMArch("armv8.7-a", "generic", "v8.7a",
517 ARMBuildAttrs::CPUArch::v8_A));
518 EXPECT_TRUE(testARMArch("armv8.8-a", "generic", "v8.8a",
519 ARMBuildAttrs::CPUArch::v8_A));
520 EXPECT_TRUE(
521 testARMArch("armv9-a", "generic", "v9a",
522 ARMBuildAttrs::CPUArch::v9_A));
523 EXPECT_TRUE(
524 testARMArch("armv9.1-a", "generic", "v9.1a",
525 ARMBuildAttrs::CPUArch::v9_A));
526 EXPECT_TRUE(
527 testARMArch("armv9.2-a", "generic", "v9.2a",
528 ARMBuildAttrs::CPUArch::v9_A));
529 EXPECT_TRUE(
530 testARMArch("armv9.3-a", "generic", "v9.3a",
531 ARMBuildAttrs::CPUArch::v9_A));
532 EXPECT_TRUE(
533 testARMArch("armv8-r", "cortex-r52", "v8r",
534 ARMBuildAttrs::CPUArch::v8_R));
535 EXPECT_TRUE(
536 testARMArch("armv8-m.base", "generic", "v8m.base",
537 ARMBuildAttrs::CPUArch::v8_M_Base));
538 EXPECT_TRUE(
539 testARMArch("armv8-m.main", "generic", "v8m.main",
540 ARMBuildAttrs::CPUArch::v8_M_Main));
541 EXPECT_TRUE(
542 testARMArch("armv8.1-m.main", "generic", "v8.1m.main",
543 ARMBuildAttrs::CPUArch::v8_1_M_Main));
544 EXPECT_TRUE(
545 testARMArch("iwmmxt", "iwmmxt", "",
546 ARMBuildAttrs::CPUArch::v5TE));
547 EXPECT_TRUE(
548 testARMArch("iwmmxt2", "generic", "",
549 ARMBuildAttrs::CPUArch::v5TE));
550 EXPECT_TRUE(
551 testARMArch("xscale", "xscale", "v5e",
552 ARMBuildAttrs::CPUArch::v5TE));
553 EXPECT_TRUE(
554 testARMArch("armv7s", "swift", "v7s",
555 ARMBuildAttrs::CPUArch::v7));
556 EXPECT_TRUE(
557 testARMArch("armv7k", "generic", "v7k",
558 ARMBuildAttrs::CPUArch::v7));
561 bool testARMExtension(StringRef CPUName,ARM::ArchKind ArchKind, StringRef ArchExt) {
562 return ARM::getDefaultExtensions(CPUName, ArchKind) &
563 ARM::parseArchExt(ArchExt);
566 TEST(TargetParserTest, testARMExtension) {
567 EXPECT_FALSE(testARMExtension("strongarm", ARM::ArchKind::INVALID, "dsp"));
568 EXPECT_FALSE(testARMExtension("arm7tdmi", ARM::ArchKind::INVALID, "dsp"));
569 EXPECT_FALSE(testARMExtension("arm10tdmi",
570 ARM::ArchKind::INVALID, "simd"));
571 EXPECT_FALSE(testARMExtension("arm1022e", ARM::ArchKind::INVALID, "simd"));
572 EXPECT_FALSE(testARMExtension("arm926ej-s",
573 ARM::ArchKind::INVALID, "simd"));
574 EXPECT_FALSE(testARMExtension("arm1136jf-s",
575 ARM::ArchKind::INVALID, "crypto"));
576 EXPECT_FALSE(testARMExtension("arm1156t2-s",
577 ARM::ArchKind::INVALID, "crypto"));
578 EXPECT_FALSE(testARMExtension("arm1176jzf-s",
579 ARM::ArchKind::INVALID, "crypto"));
580 EXPECT_FALSE(testARMExtension("cortex-m0",
581 ARM::ArchKind::INVALID, "crypto"));
582 EXPECT_FALSE(testARMExtension("cortex-a8",
583 ARM::ArchKind::INVALID, "crypto"));
584 EXPECT_FALSE(testARMExtension("cortex-r4",
585 ARM::ArchKind::INVALID, "crypto"));
586 EXPECT_FALSE(testARMExtension("cortex-m3",
587 ARM::ArchKind::INVALID, "crypto"));
588 EXPECT_FALSE(testARMExtension("cortex-a53",
589 ARM::ArchKind::INVALID, "ras"));
590 EXPECT_FALSE(testARMExtension("cortex-a53",
591 ARM::ArchKind::INVALID, "fp16"));
592 EXPECT_TRUE(testARMExtension("cortex-a55",
593 ARM::ArchKind::INVALID, "fp16"));
594 EXPECT_FALSE(testARMExtension("cortex-a55",
595 ARM::ArchKind::INVALID, "fp16fml"));
596 EXPECT_TRUE(testARMExtension("cortex-a75",
597 ARM::ArchKind::INVALID, "fp16"));
598 EXPECT_FALSE(testARMExtension("cortex-a75",
599 ARM::ArchKind::INVALID, "fp16fml"));
600 EXPECT_FALSE(testARMExtension("cortex-r52",
601 ARM::ArchKind::INVALID, "ras"));
602 EXPECT_FALSE(testARMExtension("iwmmxt", ARM::ArchKind::INVALID, "crc"));
603 EXPECT_FALSE(testARMExtension("xscale", ARM::ArchKind::INVALID, "crc"));
604 EXPECT_FALSE(testARMExtension("swift", ARM::ArchKind::INVALID, "crc"));
606 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV2, "thumb"));
607 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV2A, "thumb"));
608 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV3, "thumb"));
609 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV3M, "thumb"));
610 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4, "dsp"));
611 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4T, "dsp"));
612 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5T, "simd"));
613 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TE, "simd"));
614 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TEJ, "simd"));
615 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6, "crypto"));
616 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6K, "crypto"));
617 EXPECT_FALSE(testARMExtension("generic",
618 ARM::ArchKind::ARMV6T2, "crypto"));
619 EXPECT_FALSE(testARMExtension("generic",
620 ARM::ArchKind::ARMV6KZ, "crypto"));
621 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6M, "crypto"));
622 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7A, "crypto"));
623 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7R, "crypto"));
624 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7M, "crypto"));
625 EXPECT_FALSE(testARMExtension("generic",
626 ARM::ArchKind::ARMV7EM, "crypto"));
627 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8A, "ras"));
628 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_1A, "ras"));
629 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "profile"));
630 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16"));
631 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16fml"));
632 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A, "fp16"));
633 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A, "fp16fml"));
634 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A, "fp16"));
635 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A, "fp16fml"));
636 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8R, "ras"));
637 EXPECT_FALSE(testARMExtension("generic",
638 ARM::ArchKind::ARMV8MBaseline, "crc"));
639 EXPECT_FALSE(testARMExtension("generic",
640 ARM::ArchKind::ARMV8MMainline, "crc"));
641 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT, "crc"));
642 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT2, "crc"));
643 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::XSCALE, "crc"));
644 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7S, "crypto"));
645 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7K, "crypto"));
648 TEST(TargetParserTest, ARMFPUVersion) {
649 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
650 FK <= ARM::FPUKind::FK_LAST;
651 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
652 if (FK == ARM::FK_LAST || ARM::getFPUName(FK) == "invalid" ||
653 ARM::getFPUName(FK) == "none" || ARM::getFPUName(FK) == "softvfp")
654 EXPECT_EQ(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK));
655 else
656 EXPECT_NE(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK));
659 TEST(TargetParserTest, ARMFPUNeonSupportLevel) {
660 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
661 FK <= ARM::FPUKind::FK_LAST;
662 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
663 if (FK == ARM::FK_LAST ||
664 ARM::getFPUName(FK).find("neon") == std::string::npos)
665 EXPECT_EQ(ARM::NeonSupportLevel::None,
666 ARM::getFPUNeonSupportLevel(FK));
667 else
668 EXPECT_NE(ARM::NeonSupportLevel::None,
669 ARM::getFPUNeonSupportLevel(FK));
672 TEST(TargetParserTest, ARMFPURestriction) {
673 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
674 FK <= ARM::FPUKind::FK_LAST;
675 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) {
676 if (FK == ARM::FK_LAST ||
677 (ARM::getFPUName(FK).find("d16") == std::string::npos &&
678 ARM::getFPUName(FK).find("vfpv3xd") == std::string::npos))
679 EXPECT_EQ(ARM::FPURestriction::None, ARM::getFPURestriction(FK));
680 else
681 EXPECT_NE(ARM::FPURestriction::None, ARM::getFPURestriction(FK));
685 TEST(TargetParserTest, ARMExtensionFeatures) {
686 std::map<uint64_t, std::vector<StringRef>> Extensions;
688 for (auto &Ext : ARM::ARCHExtNames) {
689 if (Ext.Feature && Ext.NegFeature)
690 Extensions[Ext.ID] = { StringRef(Ext.Feature),
691 StringRef(Ext.NegFeature) };
694 Extensions[ARM::AEK_HWDIVARM] = { "+hwdiv-arm", "-hwdiv-arm" };
695 Extensions[ARM::AEK_HWDIVTHUMB] = { "+hwdiv", "-hwdiv" };
697 std::vector<StringRef> Features;
699 EXPECT_FALSE(ARM::getExtensionFeatures(ARM::AEK_INVALID, Features));
701 for (auto &E : Extensions) {
702 // test +extension
703 Features.clear();
704 ARM::getExtensionFeatures(E.first, Features);
705 EXPECT_TRUE(llvm::is_contained(Features, E.second.at(0)));
706 EXPECT_EQ(Extensions.size(), Features.size());
708 // test -extension
709 Features.clear();
710 ARM::getExtensionFeatures(~E.first, Features);
711 EXPECT_TRUE(llvm::is_contained(Features, E.second.at(1)));
712 EXPECT_EQ(Extensions.size(), Features.size());
716 TEST(TargetParserTest, ARMFPUFeatures) {
717 std::vector<StringRef> Features;
718 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
719 FK <= ARM::FPUKind::FK_LAST;
720 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) {
721 if (FK == ARM::FK_INVALID || FK >= ARM::FK_LAST)
722 EXPECT_FALSE(ARM::getFPUFeatures(FK, Features));
723 else
724 EXPECT_TRUE(ARM::getFPUFeatures(FK, Features));
728 TEST(TargetParserTest, ARMArchExtFeature) {
729 const char *ArchExt[][4] = {{"crc", "nocrc", "+crc", "-crc"},
730 {"crypto", "nocrypto", "+crypto", "-crypto"},
731 {"dsp", "nodsp", "+dsp", "-dsp"},
732 {"fp", "nofp", nullptr, nullptr},
733 {"idiv", "noidiv", nullptr, nullptr},
734 {"mp", "nomp", nullptr, nullptr},
735 {"simd", "nosimd", nullptr, nullptr},
736 {"sec", "nosec", nullptr, nullptr},
737 {"virt", "novirt", nullptr, nullptr},
738 {"fp16", "nofp16", "+fullfp16", "-fullfp16"},
739 {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"},
740 {"ras", "noras", "+ras", "-ras"},
741 {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
742 {"os", "noos", nullptr, nullptr},
743 {"iwmmxt", "noiwmmxt", nullptr, nullptr},
744 {"iwmmxt2", "noiwmmxt2", nullptr, nullptr},
745 {"maverick", "maverick", nullptr, nullptr},
746 {"xscale", "noxscale", nullptr, nullptr},
747 {"sb", "nosb", "+sb", "-sb"},
748 {"i8mm", "noi8mm", "+i8mm", "-i8mm"},
749 {"mve", "nomve", "+mve", "-mve"},
750 {"mve.fp", "nomve.fp", "+mve.fp", "-mve.fp"}};
752 for (unsigned i = 0; i < array_lengthof(ArchExt); i++) {
753 EXPECT_EQ(StringRef(ArchExt[i][2]), ARM::getArchExtFeature(ArchExt[i][0]));
754 EXPECT_EQ(StringRef(ArchExt[i][3]), ARM::getArchExtFeature(ArchExt[i][1]));
758 static bool
759 testArchExtDependency(const char *ArchExt,
760 const std::initializer_list<const char *> &Expected) {
761 std::vector<StringRef> Features;
762 unsigned FPUID;
764 if (!ARM::appendArchExtFeatures("", ARM::ArchKind::ARMV8_1MMainline, ArchExt,
765 Features, FPUID))
766 return false;
768 return llvm::all_of(Expected, [&](StringRef Ext) {
769 return llvm::is_contained(Features, Ext);
773 TEST(TargetParserTest, ARMArchExtDependencies) {
774 EXPECT_TRUE(testArchExtDependency("mve", {"+mve", "+dsp"}));
775 EXPECT_TRUE(testArchExtDependency("mve.fp", {"+mve.fp", "+mve", "+dsp"}));
776 EXPECT_TRUE(testArchExtDependency("nodsp", {"-dsp", "-mve", "-mve.fp"}));
777 EXPECT_TRUE(testArchExtDependency("nomve", {"-mve", "-mve.fp"}));
780 TEST(TargetParserTest, ARMparseHWDiv) {
781 const char *hwdiv[] = {"thumb", "arm", "arm,thumb", "thumb,arm"};
783 for (unsigned i = 0; i < array_lengthof(hwdiv); i++)
784 EXPECT_NE(ARM::AEK_INVALID, ARM::parseHWDiv((StringRef)hwdiv[i]));
787 TEST(TargetParserTest, ARMparseArchEndianAndISA) {
788 const char *Arch[] = {
789 "v2", "v2a", "v3", "v3m", "v4", "v4t",
790 "v5", "v5t", "v5e", "v5te", "v5tej", "v6",
791 "v6j", "v6k", "v6hl", "v6t2", "v6kz", "v6z",
792 "v6zk", "v6-m", "v6m", "v6sm", "v6s-m", "v7-a",
793 "v7", "v7a", "v7ve", "v7hl", "v7l", "v7-r",
794 "v7r", "v7-m", "v7m", "v7k", "v7s", "v7e-m",
795 "v7em", "v8-a", "v8", "v8a", "v8l", "v8.1-a",
796 "v8.1a", "v8.2-a", "v8.2a", "v8.3-a", "v8.3a", "v8.4-a",
797 "v8.4a", "v8.5-a", "v8.5a", "v8.6-a", "v8.6a", "v8.7-a",
798 "v8.7a", "v8.8-a", "v8.8a", "v8-r", "v8m.base", "v8m.main",
799 "v8.1m.main"};
801 for (unsigned i = 0; i < array_lengthof(Arch); i++) {
802 std::string arm_1 = "armeb" + (std::string)(Arch[i]);
803 std::string arm_2 = "arm" + (std::string)(Arch[i]) + "eb";
804 std::string arm_3 = "arm" + (std::string)(Arch[i]);
805 std::string thumb_1 = "thumbeb" + (std::string)(Arch[i]);
806 std::string thumb_2 = "thumb" + (std::string)(Arch[i]) + "eb";
807 std::string thumb_3 = "thumb" + (std::string)(Arch[i]);
809 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_1));
810 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_2));
811 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(arm_3));
813 EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_1));
814 EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_2));
815 EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_3));
816 if (i >= 4) {
817 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_1));
818 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_2));
819 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(thumb_3));
821 EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_1));
822 EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_2));
823 EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_3));
827 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("aarch64"));
828 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("arm64_32"));
829 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian("aarch64_be"));
831 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64"));
832 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_be"));
833 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64"));
834 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_be"));
835 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_32"));
836 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_32"));
839 TEST(TargetParserTest, ARMparseArchProfile) {
840 for (unsigned i = 0; i < array_lengthof(ARMArch); i++) {
841 switch (ARM::parseArch(ARMArch[i])) {
842 case ARM::ArchKind::ARMV6M:
843 case ARM::ArchKind::ARMV7M:
844 case ARM::ArchKind::ARMV7EM:
845 case ARM::ArchKind::ARMV8MMainline:
846 case ARM::ArchKind::ARMV8MBaseline:
847 case ARM::ArchKind::ARMV8_1MMainline:
848 EXPECT_EQ(ARM::ProfileKind::M, ARM::parseArchProfile(ARMArch[i]));
849 break;
850 case ARM::ArchKind::ARMV7R:
851 case ARM::ArchKind::ARMV8R:
852 EXPECT_EQ(ARM::ProfileKind::R, ARM::parseArchProfile(ARMArch[i]));
853 break;
854 case ARM::ArchKind::ARMV7A:
855 case ARM::ArchKind::ARMV7VE:
856 case ARM::ArchKind::ARMV7K:
857 case ARM::ArchKind::ARMV8A:
858 case ARM::ArchKind::ARMV8_1A:
859 case ARM::ArchKind::ARMV8_2A:
860 case ARM::ArchKind::ARMV8_3A:
861 case ARM::ArchKind::ARMV8_4A:
862 case ARM::ArchKind::ARMV8_5A:
863 case ARM::ArchKind::ARMV8_6A:
864 case ARM::ArchKind::ARMV8_7A:
865 case ARM::ArchKind::ARMV8_8A:
866 case ARM::ArchKind::ARMV9A:
867 case ARM::ArchKind::ARMV9_1A:
868 case ARM::ArchKind::ARMV9_2A:
869 case ARM::ArchKind::ARMV9_3A:
870 EXPECT_EQ(ARM::ProfileKind::A, ARM::parseArchProfile(ARMArch[i]));
871 break;
872 default:
873 EXPECT_EQ(ARM::ProfileKind::INVALID, ARM::parseArchProfile(ARMArch[i]));
874 break;
879 TEST(TargetParserTest, ARMparseArchVersion) {
880 for (unsigned i = 0; i < array_lengthof(ARMArch); i++)
881 if (((std::string)ARMArch[i]).substr(0, 4) == "armv")
882 EXPECT_EQ((ARMArch[i][4] - 48u), ARM::parseArchVersion(ARMArch[i]));
883 else
884 EXPECT_EQ(5u, ARM::parseArchVersion(ARMArch[i]));
887 class AArch64CPUTestFixture
888 : public ::testing::TestWithParam<ARMCPUTestParams> {};
890 TEST_P(AArch64CPUTestFixture, testAArch64CPU) {
891 ARMCPUTestParams params = GetParam();
893 AArch64::ArchKind AK = AArch64::parseCPUArch(params.CPUName);
894 EXPECT_EQ(params.ExpectedArch, AArch64::getArchName(AK));
896 uint64_t default_extensions =
897 AArch64::getDefaultExtensions(params.CPUName, AK);
898 EXPECT_PRED_FORMAT2(AssertSameExtensionFlags<ARM::ISAKind::AARCH64>,
899 params.ExpectedFlags, default_extensions);
901 unsigned FPUKind = AArch64::getDefaultFPU(params.CPUName, AK);
902 EXPECT_EQ(params.ExpectedFPU, ARM::getFPUName(FPUKind));
904 EXPECT_EQ(params.CPUAttr, AArch64::getCPUAttr(AK));
907 INSTANTIATE_TEST_SUITE_P(
908 AArch64CPUTests, AArch64CPUTestFixture,
909 ::testing::Values(
910 ARMCPUTestParams("invalid", "invalid", "invalid", AArch64::AEK_NONE,
911 ""),
912 ARMCPUTestParams("generic", "invalid", "none", AArch64::AEK_NONE, ""),
914 ARMCPUTestParams("cortex-a34", "armv8-a", "crypto-neon-fp-armv8",
915 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
916 AArch64::AEK_FP | AArch64::AEK_SIMD,
917 "8-A"),
918 ARMCPUTestParams("cortex-a35", "armv8-a", "crypto-neon-fp-armv8",
919 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
920 AArch64::AEK_FP | AArch64::AEK_SIMD,
921 "8-A"),
922 ARMCPUTestParams("cortex-a53", "armv8-a", "crypto-neon-fp-armv8",
923 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
924 AArch64::AEK_FP | AArch64::AEK_SIMD,
925 "8-A"),
926 ARMCPUTestParams("cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",
927 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
928 AArch64::AEK_FP | AArch64::AEK_SIMD |
929 AArch64::AEK_RAS | AArch64::AEK_LSE |
930 AArch64::AEK_RDM | AArch64::AEK_FP16 |
931 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC,
932 "8.2-A"),
933 ARMCPUTestParams("cortex-a510", "armv9-a", "neon-fp-armv8",
934 AArch64::AEK_CRC | AArch64::AEK_FP |
935 AArch64::AEK_SIMD | AArch64::AEK_RAS |
936 AArch64::AEK_LSE | AArch64::AEK_RDM |
937 AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
938 AArch64::AEK_BF16 | AArch64::AEK_I8MM |
939 AArch64::AEK_SVE | AArch64::AEK_SVE2 |
940 AArch64::AEK_SVE2BITPERM | AArch64::AEK_PAUTH |
941 AArch64::AEK_MTE | AArch64::AEK_SSBS |
942 AArch64::AEK_FP16FML | AArch64::AEK_SB,
943 "9-A"),
944 ARMCPUTestParams("cortex-a57", "armv8-a", "crypto-neon-fp-armv8",
945 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
946 AArch64::AEK_FP | AArch64::AEK_SIMD,
947 "8-A"),
948 ARMCPUTestParams("cortex-a65", "armv8.2-a", "crypto-neon-fp-armv8",
949 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
950 AArch64::AEK_DOTPROD | AArch64::AEK_FP |
951 AArch64::AEK_FP16 | AArch64::AEK_LSE |
952 AArch64::AEK_RAS | AArch64::AEK_RCPC |
953 AArch64::AEK_RDM | AArch64::AEK_SIMD |
954 AArch64::AEK_SSBS,
955 "8.2-A"),
956 ARMCPUTestParams("cortex-a65ae", "armv8.2-a", "crypto-neon-fp-armv8",
957 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
958 AArch64::AEK_DOTPROD | AArch64::AEK_FP |
959 AArch64::AEK_FP16 | AArch64::AEK_LSE |
960 AArch64::AEK_RAS | AArch64::AEK_RCPC |
961 AArch64::AEK_RDM | AArch64::AEK_SIMD |
962 AArch64::AEK_SSBS,
963 "8.2-A"),
964 ARMCPUTestParams("cortex-a72", "armv8-a", "crypto-neon-fp-armv8",
965 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
966 AArch64::AEK_FP | AArch64::AEK_SIMD,
967 "8-A"),
968 ARMCPUTestParams("cortex-a73", "armv8-a", "crypto-neon-fp-armv8",
969 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
970 AArch64::AEK_FP | AArch64::AEK_SIMD,
971 "8-A"),
972 ARMCPUTestParams("cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",
973 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
974 AArch64::AEK_FP | AArch64::AEK_SIMD |
975 AArch64::AEK_RAS | AArch64::AEK_LSE |
976 AArch64::AEK_RDM | AArch64::AEK_FP16 |
977 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC,
978 "8.2-A"),
979 ARMCPUTestParams("cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8",
980 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
981 AArch64::AEK_FP | AArch64::AEK_RDM |
982 AArch64::AEK_SIMD | AArch64::AEK_RAS |
983 AArch64::AEK_LSE | AArch64::AEK_FP16 |
984 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
985 AArch64::AEK_SSBS,
986 "8.2-A"),
987 ARMCPUTestParams("cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8",
988 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
989 AArch64::AEK_FP | AArch64::AEK_RDM |
990 AArch64::AEK_SIMD | AArch64::AEK_RAS |
991 AArch64::AEK_LSE | AArch64::AEK_FP16 |
992 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
993 AArch64::AEK_SSBS,
994 "8.2-A"),
995 ARMCPUTestParams("cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8",
996 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
997 AArch64::AEK_FP | AArch64::AEK_RDM |
998 AArch64::AEK_SIMD | AArch64::AEK_RAS |
999 AArch64::AEK_LSE | AArch64::AEK_FP16 |
1000 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
1001 AArch64::AEK_SSBS,
1002 "8.2-A"),
1003 ARMCPUTestParams("cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8",
1004 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1005 AArch64::AEK_FP | AArch64::AEK_RDM |
1006 AArch64::AEK_SIMD | AArch64::AEK_RAS |
1007 AArch64::AEK_LSE | AArch64::AEK_FP16 |
1008 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
1009 AArch64::AEK_SSBS | AArch64::AEK_PROFILE,
1010 "8.2-A"),
1011 ARMCPUTestParams("cortex-a78c", "armv8.2-a", "crypto-neon-fp-armv8",
1012 AArch64::AEK_RAS | AArch64::AEK_CRC |
1013 AArch64::AEK_CRYPTO | AArch64::AEK_FP |
1014 AArch64::AEK_SIMD | AArch64::AEK_RAS |
1015 AArch64::AEK_LSE | AArch64::AEK_RDM |
1016 AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
1017 AArch64::AEK_RCPC | AArch64::AEK_SSBS |
1018 AArch64::AEK_PROFILE | AArch64::AEK_FLAGM |
1019 AArch64::AEK_PAUTH | AArch64::AEK_FP16FML,
1020 "8.2-A"),
1021 ARMCPUTestParams("cortex-a710", "armv9-a", "neon-fp-armv8",
1022 AArch64::AEK_CRC | AArch64::AEK_FP |
1023 AArch64::AEK_SIMD | AArch64::AEK_RAS |
1024 AArch64::AEK_LSE | AArch64::AEK_RDM |
1025 AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
1026 AArch64::AEK_MTE | AArch64::AEK_FP16FML |
1027 AArch64::AEK_SVE | AArch64::AEK_SVE2 |
1028 AArch64::AEK_SVE2BITPERM | AArch64::AEK_PAUTH |
1029 AArch64::AEK_FLAGM | AArch64::AEK_SB |
1030 AArch64::AEK_I8MM | AArch64::AEK_BF16,
1031 "9-A"),
1032 ARMCPUTestParams(
1033 "neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8",
1034 AArch64::AEK_RAS | AArch64::AEK_SVE | AArch64::AEK_SSBS |
1035 AArch64::AEK_RCPC | AArch64::AEK_CRC | AArch64::AEK_FP |
1036 AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
1037 AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
1038 AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_BF16 |
1039 AArch64::AEK_PROFILE | AArch64::AEK_RAND |
1040 AArch64::AEK_FP16FML | AArch64::AEK_I8MM,
1041 "8.4-A"),
1042 ARMCPUTestParams("cortex-r82", "armv8-r", "crypto-neon-fp-armv8",
1043 AArch64::AEK_CRC | AArch64::AEK_RDM |
1044 AArch64::AEK_SSBS | AArch64::AEK_DOTPROD |
1045 AArch64::AEK_FP | AArch64::AEK_SIMD |
1046 AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
1047 AArch64::AEK_RAS | AArch64::AEK_RCPC |
1048 AArch64::AEK_LSE | AArch64::AEK_SB,
1049 "8-R"),
1050 ARMCPUTestParams("cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8",
1051 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1052 AArch64::AEK_FP | AArch64::AEK_RDM |
1053 AArch64::AEK_SIMD | AArch64::AEK_RAS |
1054 AArch64::AEK_LSE | AArch64::AEK_FP16 |
1055 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
1056 AArch64::AEK_SSBS | AArch64::AEK_PROFILE,
1057 "8.2-A"),
1058 ARMCPUTestParams("cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8",
1059 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1060 AArch64::AEK_FP | AArch64::AEK_RDM |
1061 AArch64::AEK_SIMD | AArch64::AEK_RAS |
1062 AArch64::AEK_LSE | AArch64::AEK_FP16 |
1063 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
1064 AArch64::AEK_SSBS | AArch64::AEK_PAUTH |
1065 AArch64::AEK_PROFILE,
1066 "8.2-A"),
1067 ARMCPUTestParams("cortex-x2", "armv9-a", "neon-fp-armv8",
1068 AArch64::AEK_CRC | AArch64::AEK_FP |
1069 AArch64::AEK_SIMD | AArch64::AEK_RAS |
1070 AArch64::AEK_LSE | AArch64::AEK_RDM |
1071 AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
1072 AArch64::AEK_MTE | AArch64::AEK_PAUTH |
1073 AArch64::AEK_I8MM | AArch64::AEK_BF16 |
1074 AArch64::AEK_SVE | AArch64::AEK_SVE2 |
1075 AArch64::AEK_SVE2BITPERM | AArch64::AEK_SSBS |
1076 AArch64::AEK_SB | AArch64::AEK_FP16FML,
1077 "9-A"),
1078 ARMCPUTestParams("cyclone", "armv8-a", "crypto-neon-fp-armv8",
1079 AArch64::AEK_NONE | AArch64::AEK_CRYPTO |
1080 AArch64::AEK_FP | AArch64::AEK_SIMD,
1081 "8-A"),
1082 ARMCPUTestParams("apple-a7", "armv8-a", "crypto-neon-fp-armv8",
1083 AArch64::AEK_NONE | AArch64::AEK_CRYPTO |
1084 AArch64::AEK_FP | AArch64::AEK_SIMD,
1085 "8-A"),
1086 ARMCPUTestParams("apple-a8", "armv8-a", "crypto-neon-fp-armv8",
1087 AArch64::AEK_NONE | AArch64::AEK_CRYPTO |
1088 AArch64::AEK_FP | AArch64::AEK_SIMD,
1089 "8-A"),
1090 ARMCPUTestParams("apple-a9", "armv8-a", "crypto-neon-fp-armv8",
1091 AArch64::AEK_NONE | AArch64::AEK_CRYPTO |
1092 AArch64::AEK_FP | AArch64::AEK_SIMD,
1093 "8-A"),
1094 ARMCPUTestParams("apple-a10", "armv8-a", "crypto-neon-fp-armv8",
1095 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1096 AArch64::AEK_FP | AArch64::AEK_RDM |
1097 AArch64::AEK_SIMD,
1098 "8-A"),
1099 ARMCPUTestParams("apple-a11", "armv8.2-a", "crypto-neon-fp-armv8",
1100 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1101 AArch64::AEK_FP | AArch64::AEK_LSE |
1102 AArch64::AEK_RAS | AArch64::AEK_RDM |
1103 AArch64::AEK_SIMD | AArch64::AEK_FP16,
1104 "8.2-A"),
1105 ARMCPUTestParams("apple-a12", "armv8.3-a", "crypto-neon-fp-armv8",
1106 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1107 AArch64::AEK_FP | AArch64::AEK_SIMD |
1108 AArch64::AEK_LSE | AArch64::AEK_RAS |
1109 AArch64::AEK_RDM | AArch64::AEK_RCPC |
1110 AArch64::AEK_FP16,
1111 "8.3-A"),
1112 ARMCPUTestParams("apple-a13", "armv8.4-a", "crypto-neon-fp-armv8",
1113 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1114 AArch64::AEK_FP | AArch64::AEK_SIMD |
1115 AArch64::AEK_LSE | AArch64::AEK_RAS |
1116 AArch64::AEK_RDM | AArch64::AEK_RCPC |
1117 AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
1118 AArch64::AEK_FP16FML | AArch64::AEK_SHA3,
1119 "8.4-A"),
1120 ARMCPUTestParams("apple-a14", "armv8.5-a", "crypto-neon-fp-armv8",
1121 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1122 AArch64::AEK_FP | AArch64::AEK_SIMD |
1123 AArch64::AEK_LSE | AArch64::AEK_RAS |
1124 AArch64::AEK_RDM | AArch64::AEK_RCPC |
1125 AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
1126 AArch64::AEK_FP16FML | AArch64::AEK_SHA3,
1127 "8.5-A"),
1128 ARMCPUTestParams("apple-m1", "armv8.5-a", "crypto-neon-fp-armv8",
1129 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1130 AArch64::AEK_FP | AArch64::AEK_SIMD |
1131 AArch64::AEK_LSE | AArch64::AEK_RAS |
1132 AArch64::AEK_RDM | AArch64::AEK_RCPC |
1133 AArch64::AEK_DOTPROD | AArch64::AEK_FP16 |
1134 AArch64::AEK_FP16FML | AArch64::AEK_SHA3,
1135 "8.5-A"),
1136 ARMCPUTestParams("apple-s4", "armv8.3-a", "crypto-neon-fp-armv8",
1137 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1138 AArch64::AEK_FP | AArch64::AEK_SIMD |
1139 AArch64::AEK_LSE | AArch64::AEK_RAS |
1140 AArch64::AEK_RDM | AArch64::AEK_RCPC |
1141 AArch64::AEK_FP16,
1142 "8.3-A"),
1143 ARMCPUTestParams("apple-s5", "armv8.3-a", "crypto-neon-fp-armv8",
1144 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1145 AArch64::AEK_FP | AArch64::AEK_SIMD |
1146 AArch64::AEK_LSE | AArch64::AEK_RAS |
1147 AArch64::AEK_RDM | AArch64::AEK_RCPC |
1148 AArch64::AEK_FP16,
1149 "8.3-A"),
1150 ARMCPUTestParams("exynos-m3", "armv8-a", "crypto-neon-fp-armv8",
1151 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1152 AArch64::AEK_FP | AArch64::AEK_SIMD,
1153 "8-A"),
1154 ARMCPUTestParams("exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8",
1155 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1156 AArch64::AEK_DOTPROD | AArch64::AEK_FP |
1157 AArch64::AEK_FP16 | AArch64::AEK_LSE |
1158 AArch64::AEK_RAS | AArch64::AEK_RDM |
1159 AArch64::AEK_SIMD,
1160 "8.2-A"),
1161 ARMCPUTestParams("exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8",
1162 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1163 AArch64::AEK_DOTPROD | AArch64::AEK_FP |
1164 AArch64::AEK_FP16 | AArch64::AEK_LSE |
1165 AArch64::AEK_RAS | AArch64::AEK_RDM |
1166 AArch64::AEK_SIMD,
1167 "8.2-A"),
1168 ARMCPUTestParams("falkor", "armv8-a", "crypto-neon-fp-armv8",
1169 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1170 AArch64::AEK_FP | AArch64::AEK_SIMD |
1171 AArch64::AEK_RDM,
1172 "8-A"),
1173 ARMCPUTestParams("kryo", "armv8-a", "crypto-neon-fp-armv8",
1174 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1175 AArch64::AEK_FP | AArch64::AEK_SIMD,
1176 "8-A"),
1177 ARMCPUTestParams("neoverse-e1", "armv8.2-a", "crypto-neon-fp-armv8",
1178 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1179 AArch64::AEK_DOTPROD | AArch64::AEK_FP |
1180 AArch64::AEK_FP16 | AArch64::AEK_LSE |
1181 AArch64::AEK_RAS | AArch64::AEK_RCPC |
1182 AArch64::AEK_RDM | AArch64::AEK_SIMD |
1183 AArch64::AEK_SSBS,
1184 "8.2-A"),
1185 ARMCPUTestParams("neoverse-n1", "armv8.2-a", "crypto-neon-fp-armv8",
1186 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1187 AArch64::AEK_DOTPROD | AArch64::AEK_FP |
1188 AArch64::AEK_FP16 | AArch64::AEK_LSE |
1189 AArch64::AEK_PROFILE | AArch64::AEK_RAS |
1190 AArch64::AEK_RCPC | AArch64::AEK_RDM |
1191 AArch64::AEK_SIMD | AArch64::AEK_SSBS,
1192 "8.2-A"),
1193 ARMCPUTestParams("neoverse-n2", "armv8.5-a", "crypto-neon-fp-armv8",
1194 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1195 AArch64::AEK_FP | AArch64::AEK_SIMD |
1196 AArch64::AEK_FP16 | AArch64::AEK_RAS |
1197 AArch64::AEK_LSE | AArch64::AEK_SVE |
1198 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
1199 AArch64::AEK_RDM | AArch64::AEK_MTE |
1200 AArch64::AEK_SSBS | AArch64::AEK_SB |
1201 AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM |
1202 AArch64::AEK_BF16 | AArch64::AEK_I8MM,
1203 "8.5-A"),
1204 ARMCPUTestParams("ampere1", "armv8.6-a", "crypto-neon-fp-armv8",
1205 AArch64::AEK_CRC | AArch64::AEK_FP | AArch64::AEK_FP16 |
1206 AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
1207 AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
1208 AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 |
1209 AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM |
1210 AArch64::AEK_SSBS | AArch64::AEK_SB,
1211 "8.6-A"),
1212 ARMCPUTestParams(
1213 "neoverse-512tvb", "armv8.4-a", "crypto-neon-fp-armv8",
1214 AArch64::AEK_RAS | AArch64::AEK_SVE | AArch64::AEK_SSBS |
1215 AArch64::AEK_RCPC | AArch64::AEK_CRC | AArch64::AEK_FP |
1216 AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
1217 AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
1218 AArch64::AEK_CRYPTO | AArch64::AEK_FP16 | AArch64::AEK_BF16 |
1219 AArch64::AEK_PROFILE | AArch64::AEK_RAND |
1220 AArch64::AEK_FP16FML | AArch64::AEK_I8MM,
1221 "8.4-A"),
1222 ARMCPUTestParams("thunderx2t99", "armv8.1-a", "crypto-neon-fp-armv8",
1223 AArch64::AEK_NONE | AArch64::AEK_CRC |
1224 AArch64::AEK_CRYPTO | AArch64::AEK_LSE |
1225 AArch64::AEK_RDM | AArch64::AEK_FP |
1226 AArch64::AEK_SIMD,
1227 "8.1-A"),
1228 ARMCPUTestParams("thunderx3t110", "armv8.3-a", "crypto-neon-fp-armv8",
1229 AArch64::AEK_NONE | AArch64::AEK_CRC |
1230 AArch64::AEK_CRYPTO | AArch64::AEK_LSE |
1231 AArch64::AEK_RDM | AArch64::AEK_FP |
1232 AArch64::AEK_SIMD | AArch64::AEK_RAS |
1233 AArch64::AEK_RCPC,
1234 "8.3-A"),
1235 ARMCPUTestParams("thunderx", "armv8-a", "crypto-neon-fp-armv8",
1236 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1237 AArch64::AEK_SIMD | AArch64::AEK_FP,
1238 "8-A"),
1239 ARMCPUTestParams("thunderxt81", "armv8-a", "crypto-neon-fp-armv8",
1240 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1241 AArch64::AEK_SIMD | AArch64::AEK_FP,
1242 "8-A"),
1243 ARMCPUTestParams("thunderxt83", "armv8-a", "crypto-neon-fp-armv8",
1244 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1245 AArch64::AEK_SIMD | AArch64::AEK_FP,
1246 "8-A"),
1247 ARMCPUTestParams("thunderxt88", "armv8-a", "crypto-neon-fp-armv8",
1248 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1249 AArch64::AEK_SIMD | AArch64::AEK_FP,
1250 "8-A"),
1251 ARMCPUTestParams("tsv110", "armv8.2-a", "crypto-neon-fp-armv8",
1252 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1253 AArch64::AEK_FP | AArch64::AEK_SIMD |
1254 AArch64::AEK_RAS | AArch64::AEK_LSE |
1255 AArch64::AEK_RDM | AArch64::AEK_PROFILE |
1256 AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
1257 AArch64::AEK_DOTPROD,
1258 "8.2-A"),
1259 ARMCPUTestParams("a64fx", "armv8.2-a", "crypto-neon-fp-armv8",
1260 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1261 AArch64::AEK_FP | AArch64::AEK_SIMD |
1262 AArch64::AEK_FP16 | AArch64::AEK_RAS |
1263 AArch64::AEK_LSE | AArch64::AEK_SVE |
1264 AArch64::AEK_RDM,
1265 "8.2-A"),
1266 ARMCPUTestParams("carmel", "armv8.2-a", "crypto-neon-fp-armv8",
1267 AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
1268 AArch64::AEK_FP | AArch64::AEK_SIMD |
1269 AArch64::AEK_FP16 | AArch64::AEK_RAS |
1270 AArch64::AEK_LSE | AArch64::AEK_RDM,
1271 "8.2-A")));
1273 static constexpr unsigned NumAArch64CPUArchs = 54;
1275 TEST(TargetParserTest, testAArch64CPUArchList) {
1276 SmallVector<StringRef, NumAArch64CPUArchs> List;
1277 AArch64::fillValidCPUArchList(List);
1279 // No list exists for these in this test suite, so ensure all are
1280 // valid, and match the expected 'magic' count.
1281 EXPECT_EQ(List.size(), NumAArch64CPUArchs);
1282 for(StringRef CPU : List) {
1283 EXPECT_NE(AArch64::parseCPUArch(CPU), AArch64::ArchKind::INVALID);
1287 bool testAArch64Arch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch,
1288 unsigned ArchAttr) {
1289 AArch64::ArchKind AK = AArch64::parseArch(Arch);
1290 return (AK != AArch64::ArchKind::INVALID) &&
1291 AArch64::getDefaultCPU(Arch).equals(DefaultCPU) &&
1292 AArch64::getSubArch(AK).equals(SubArch) &&
1293 (AArch64::getArchAttr(AK) == ArchAttr);
1296 TEST(TargetParserTest, testAArch64Arch) {
1297 EXPECT_TRUE(testAArch64Arch("armv8-a", "cortex-a53", "v8",
1298 ARMBuildAttrs::CPUArch::v8_A));
1299 EXPECT_TRUE(testAArch64Arch("armv8.1-a", "generic", "v8.1a",
1300 ARMBuildAttrs::CPUArch::v8_A));
1301 EXPECT_TRUE(testAArch64Arch("armv8.2-a", "generic", "v8.2a",
1302 ARMBuildAttrs::CPUArch::v8_A));
1303 EXPECT_TRUE(testAArch64Arch("armv8.3-a", "generic", "v8.3a",
1304 ARMBuildAttrs::CPUArch::v8_A));
1305 EXPECT_TRUE(testAArch64Arch("armv8.4-a", "generic", "v8.4a",
1306 ARMBuildAttrs::CPUArch::v8_A));
1307 EXPECT_TRUE(testAArch64Arch("armv8.5-a", "generic", "v8.5a",
1308 ARMBuildAttrs::CPUArch::v8_A));
1309 EXPECT_TRUE(testAArch64Arch("armv8.6-a", "generic", "v8.6a",
1310 ARMBuildAttrs::CPUArch::v8_A));
1311 EXPECT_TRUE(testAArch64Arch("armv8.7-a", "generic", "v8.7a",
1312 ARMBuildAttrs::CPUArch::v8_A));
1313 EXPECT_TRUE(testAArch64Arch("armv8.8-a", "generic", "v8.8a",
1314 ARMBuildAttrs::CPUArch::v8_A));
1315 EXPECT_TRUE(testAArch64Arch("armv9-a", "generic", "v9a",
1316 ARMBuildAttrs::CPUArch::v8_A));
1317 EXPECT_TRUE(testAArch64Arch("armv9.1-a", "generic", "v9.1a",
1318 ARMBuildAttrs::CPUArch::v8_A));
1319 EXPECT_TRUE(testAArch64Arch("armv9.2-a", "generic", "v9.2a",
1320 ARMBuildAttrs::CPUArch::v8_A));
1323 bool testAArch64Extension(StringRef CPUName, AArch64::ArchKind AK,
1324 StringRef ArchExt) {
1325 return AArch64::getDefaultExtensions(CPUName, AK) &
1326 AArch64::parseArchExt(ArchExt);
1329 TEST(TargetParserTest, testAArch64Extension) {
1330 EXPECT_FALSE(testAArch64Extension("cortex-a34",
1331 AArch64::ArchKind::INVALID, "ras"));
1332 EXPECT_FALSE(testAArch64Extension("cortex-a35",
1333 AArch64::ArchKind::INVALID, "ras"));
1334 EXPECT_FALSE(testAArch64Extension("cortex-a53",
1335 AArch64::ArchKind::INVALID, "ras"));
1336 EXPECT_TRUE(testAArch64Extension("cortex-a55",
1337 AArch64::ArchKind::INVALID, "ras"));
1338 EXPECT_TRUE(testAArch64Extension("cortex-a55",
1339 AArch64::ArchKind::INVALID, "fp16"));
1340 EXPECT_FALSE(testAArch64Extension("cortex-a55",
1341 AArch64::ArchKind::INVALID, "fp16fml"));
1342 EXPECT_TRUE(testAArch64Extension("cortex-a55",
1343 AArch64::ArchKind::INVALID, "dotprod"));
1344 EXPECT_FALSE(testAArch64Extension("cortex-a57",
1345 AArch64::ArchKind::INVALID, "ras"));
1346 EXPECT_FALSE(testAArch64Extension("cortex-a72",
1347 AArch64::ArchKind::INVALID, "ras"));
1348 EXPECT_FALSE(testAArch64Extension("cortex-a73",
1349 AArch64::ArchKind::INVALID, "ras"));
1350 EXPECT_TRUE(testAArch64Extension("cortex-a75",
1351 AArch64::ArchKind::INVALID, "ras"));
1352 EXPECT_TRUE(testAArch64Extension("cortex-a75",
1353 AArch64::ArchKind::INVALID, "fp16"));
1354 EXPECT_FALSE(testAArch64Extension("cortex-a75",
1355 AArch64::ArchKind::INVALID, "fp16fml"));
1356 EXPECT_TRUE(testAArch64Extension("cortex-a75",
1357 AArch64::ArchKind::INVALID, "dotprod"));
1358 EXPECT_TRUE(testAArch64Extension("cortex-r82",
1359 AArch64::ArchKind::INVALID, "ras"));
1360 EXPECT_TRUE(testAArch64Extension("cortex-r82",
1361 AArch64::ArchKind::INVALID, "fp16"));
1362 EXPECT_TRUE(testAArch64Extension("cortex-r82",
1363 AArch64::ArchKind::INVALID, "fp16fml"));
1364 EXPECT_TRUE(testAArch64Extension("cortex-r82",
1365 AArch64::ArchKind::INVALID, "dotprod"));
1366 EXPECT_TRUE(testAArch64Extension("cortex-r82",
1367 AArch64::ArchKind::INVALID, "lse"));
1368 EXPECT_FALSE(testAArch64Extension("cyclone",
1369 AArch64::ArchKind::INVALID, "ras"));
1370 EXPECT_FALSE(testAArch64Extension("exynos-m3",
1371 AArch64::ArchKind::INVALID, "ras"));
1372 EXPECT_TRUE(testAArch64Extension("exynos-m4",
1373 AArch64::ArchKind::INVALID, "dotprod"));
1374 EXPECT_TRUE(testAArch64Extension("exynos-m4",
1375 AArch64::ArchKind::INVALID, "fp16"));
1376 EXPECT_TRUE(testAArch64Extension("exynos-m4",
1377 AArch64::ArchKind::INVALID, "lse"));
1378 EXPECT_TRUE(testAArch64Extension("exynos-m4",
1379 AArch64::ArchKind::INVALID, "ras"));
1380 EXPECT_TRUE(testAArch64Extension("exynos-m4",
1381 AArch64::ArchKind::INVALID, "rdm"));
1382 EXPECT_TRUE(testAArch64Extension("exynos-m5",
1383 AArch64::ArchKind::INVALID, "dotprod"));
1384 EXPECT_TRUE(testAArch64Extension("exynos-m5",
1385 AArch64::ArchKind::INVALID, "fp16"));
1386 EXPECT_TRUE(testAArch64Extension("exynos-m5",
1387 AArch64::ArchKind::INVALID, "lse"));
1388 EXPECT_TRUE(testAArch64Extension("exynos-m5",
1389 AArch64::ArchKind::INVALID, "ras"));
1390 EXPECT_TRUE(testAArch64Extension("exynos-m5",
1391 AArch64::ArchKind::INVALID, "rdm"));
1392 EXPECT_TRUE(testAArch64Extension("falkor",
1393 AArch64::ArchKind::INVALID, "rdm"));
1394 EXPECT_FALSE(testAArch64Extension("kryo",
1395 AArch64::ArchKind::INVALID, "ras"));
1396 EXPECT_TRUE(testAArch64Extension("saphira",
1397 AArch64::ArchKind::INVALID, "crc"));
1398 EXPECT_TRUE(testAArch64Extension("saphira",
1399 AArch64::ArchKind::INVALID, "lse"));
1400 EXPECT_TRUE(testAArch64Extension("saphira",
1401 AArch64::ArchKind::INVALID, "rdm"));
1402 EXPECT_TRUE(testAArch64Extension("saphira",
1403 AArch64::ArchKind::INVALID, "ras"));
1404 EXPECT_TRUE(testAArch64Extension("saphira",
1405 AArch64::ArchKind::INVALID, "rcpc"));
1406 EXPECT_TRUE(testAArch64Extension("saphira",
1407 AArch64::ArchKind::INVALID, "profile"));
1408 EXPECT_FALSE(testAArch64Extension("saphira",
1409 AArch64::ArchKind::INVALID, "fp16"));
1410 EXPECT_FALSE(testAArch64Extension("thunderx2t99",
1411 AArch64::ArchKind::INVALID, "ras"));
1412 EXPECT_FALSE(testAArch64Extension("thunderx",
1413 AArch64::ArchKind::INVALID, "lse"));
1414 EXPECT_FALSE(testAArch64Extension("thunderxt81",
1415 AArch64::ArchKind::INVALID, "lse"));
1416 EXPECT_FALSE(testAArch64Extension("thunderxt83",
1417 AArch64::ArchKind::INVALID, "lse"));
1418 EXPECT_FALSE(testAArch64Extension("thunderxt88",
1419 AArch64::ArchKind::INVALID, "lse"));
1420 EXPECT_TRUE(testAArch64Extension("tsv110",
1421 AArch64::ArchKind::INVALID, "crypto"));
1422 EXPECT_FALSE(testAArch64Extension("tsv110",
1423 AArch64::ArchKind::INVALID, "sha3"));
1424 EXPECT_FALSE(testAArch64Extension("tsv110",
1425 AArch64::ArchKind::INVALID, "sm4"));
1426 EXPECT_TRUE(testAArch64Extension("tsv110",
1427 AArch64::ArchKind::INVALID, "ras"));
1428 EXPECT_TRUE(testAArch64Extension("tsv110",
1429 AArch64::ArchKind::INVALID, "profile"));
1430 EXPECT_TRUE(testAArch64Extension("tsv110",
1431 AArch64::ArchKind::INVALID, "fp16"));
1432 EXPECT_TRUE(testAArch64Extension("tsv110",
1433 AArch64::ArchKind::INVALID, "fp16fml"));
1434 EXPECT_TRUE(testAArch64Extension("tsv110",
1435 AArch64::ArchKind::INVALID, "dotprod"));
1436 EXPECT_TRUE(testAArch64Extension("a64fx",
1437 AArch64::ArchKind::INVALID, "fp16"));
1438 EXPECT_TRUE(testAArch64Extension("a64fx",
1439 AArch64::ArchKind::INVALID, "sve"));
1440 EXPECT_FALSE(testAArch64Extension("a64fx",
1441 AArch64::ArchKind::INVALID, "sve2"));
1442 EXPECT_TRUE(
1443 testAArch64Extension("carmel", AArch64::ArchKind::INVALID, "crypto"));
1444 EXPECT_TRUE(
1445 testAArch64Extension("carmel", AArch64::ArchKind::INVALID, "fp16"));
1447 EXPECT_FALSE(testAArch64Extension(
1448 "generic", AArch64::ArchKind::ARMV8A, "ras"));
1449 EXPECT_FALSE(testAArch64Extension(
1450 "generic", AArch64::ArchKind::ARMV8_1A, "ras"));
1451 EXPECT_FALSE(testAArch64Extension(
1452 "generic", AArch64::ArchKind::ARMV8_2A, "profile"));
1453 EXPECT_FALSE(testAArch64Extension(
1454 "generic", AArch64::ArchKind::ARMV8_2A, "fp16"));
1455 EXPECT_FALSE(testAArch64Extension(
1456 "generic", AArch64::ArchKind::ARMV8_2A, "fp16fml"));
1457 EXPECT_FALSE(testAArch64Extension(
1458 "generic", AArch64::ArchKind::ARMV8_3A, "fp16"));
1459 EXPECT_FALSE(testAArch64Extension(
1460 "generic", AArch64::ArchKind::ARMV8_3A, "fp16fml"));
1461 EXPECT_FALSE(testAArch64Extension(
1462 "generic", AArch64::ArchKind::ARMV8_4A, "fp16"));
1463 EXPECT_FALSE(testAArch64Extension(
1464 "generic", AArch64::ArchKind::ARMV8_4A, "fp16fml"));
1467 TEST(TargetParserTest, AArch64ExtensionFeatures) {
1468 std::vector<uint64_t> Extensions = {
1469 AArch64::AEK_CRC, AArch64::AEK_LSE, AArch64::AEK_RDM,
1470 AArch64::AEK_CRYPTO, AArch64::AEK_SM4, AArch64::AEK_SHA3,
1471 AArch64::AEK_SHA2, AArch64::AEK_AES, AArch64::AEK_DOTPROD,
1472 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_FP16,
1473 AArch64::AEK_FP16FML, AArch64::AEK_PROFILE, AArch64::AEK_RAS,
1474 AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SVE2AES,
1475 AArch64::AEK_SVE2SM4, AArch64::AEK_SVE2SHA3, AArch64::AEK_SVE2BITPERM,
1476 AArch64::AEK_RCPC, AArch64::AEK_RAND, AArch64::AEK_MTE,
1477 AArch64::AEK_SSBS, AArch64::AEK_SB, AArch64::AEK_PREDRES,
1478 AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_F32MM,
1479 AArch64::AEK_F64MM, AArch64::AEK_TME, AArch64::AEK_LS64,
1480 AArch64::AEK_BRBE, AArch64::AEK_PAUTH, AArch64::AEK_FLAGM,
1481 AArch64::AEK_SME, AArch64::AEK_SMEF64, AArch64::AEK_SMEI64,
1482 AArch64::AEK_HBC, AArch64::AEK_MOPS, AArch64::AEK_PERFMON};
1484 std::vector<StringRef> Features;
1486 uint64_t ExtVal = 0;
1487 for (auto Ext : Extensions)
1488 ExtVal |= Ext;
1490 // INVALID and NONE have no feature names.
1491 EXPECT_FALSE(AArch64::getExtensionFeatures(AArch64::AEK_INVALID, Features));
1492 EXPECT_TRUE(!Features.size());
1493 // We return True here because NONE is a valid choice.
1494 EXPECT_TRUE(AArch64::getExtensionFeatures(AArch64::AEK_NONE, Features));
1495 EXPECT_TRUE(!Features.size());
1497 AArch64::getExtensionFeatures(ExtVal, Features);
1498 EXPECT_EQ(Extensions.size(), Features.size());
1500 EXPECT_TRUE(llvm::is_contained(Features, "+crc"));
1501 EXPECT_TRUE(llvm::is_contained(Features, "+lse"));
1502 EXPECT_TRUE(llvm::is_contained(Features, "+rdm"));
1503 EXPECT_TRUE(llvm::is_contained(Features, "+crypto"));
1504 EXPECT_TRUE(llvm::is_contained(Features, "+sm4"));
1505 EXPECT_TRUE(llvm::is_contained(Features, "+sha3"));
1506 EXPECT_TRUE(llvm::is_contained(Features, "+sha2"));
1507 EXPECT_TRUE(llvm::is_contained(Features, "+aes"));
1508 EXPECT_TRUE(llvm::is_contained(Features, "+dotprod"));
1509 EXPECT_TRUE(llvm::is_contained(Features, "+fp-armv8"));
1510 EXPECT_TRUE(llvm::is_contained(Features, "+neon"));
1511 EXPECT_TRUE(llvm::is_contained(Features, "+fullfp16"));
1512 EXPECT_TRUE(llvm::is_contained(Features, "+fp16fml"));
1513 EXPECT_TRUE(llvm::is_contained(Features, "+spe"));
1514 EXPECT_TRUE(llvm::is_contained(Features, "+ras"));
1515 EXPECT_TRUE(llvm::is_contained(Features, "+sve"));
1516 EXPECT_TRUE(llvm::is_contained(Features, "+sve2"));
1517 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-aes"));
1518 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sm4"));
1519 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sha3"));
1520 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-bitperm"));
1521 EXPECT_TRUE(llvm::is_contained(Features, "+rcpc"));
1522 EXPECT_TRUE(llvm::is_contained(Features, "+rand"));
1523 EXPECT_TRUE(llvm::is_contained(Features, "+mte"));
1524 EXPECT_TRUE(llvm::is_contained(Features, "+ssbs"));
1525 EXPECT_TRUE(llvm::is_contained(Features, "+sb"));
1526 EXPECT_TRUE(llvm::is_contained(Features, "+predres"));
1527 EXPECT_TRUE(llvm::is_contained(Features, "+bf16"));
1528 EXPECT_TRUE(llvm::is_contained(Features, "+i8mm"));
1529 EXPECT_TRUE(llvm::is_contained(Features, "+f32mm"));
1530 EXPECT_TRUE(llvm::is_contained(Features, "+f64mm"));
1531 EXPECT_TRUE(llvm::is_contained(Features, "+tme"));
1532 EXPECT_TRUE(llvm::is_contained(Features, "+ls64"));
1533 EXPECT_TRUE(llvm::is_contained(Features, "+brbe"));
1534 EXPECT_TRUE(llvm::is_contained(Features, "+pauth"));
1535 EXPECT_TRUE(llvm::is_contained(Features, "+flagm"));
1536 EXPECT_TRUE(llvm::is_contained(Features, "+sme"));
1537 EXPECT_TRUE(llvm::is_contained(Features, "+sme-f64"));
1538 EXPECT_TRUE(llvm::is_contained(Features, "+sme-i64"));
1539 EXPECT_TRUE(llvm::is_contained(Features, "+hbc"));
1540 EXPECT_TRUE(llvm::is_contained(Features, "+mops"));
1541 EXPECT_TRUE(llvm::is_contained(Features, "+perfmon"));
1543 // Assuming we listed every extension above, this should produce the same
1544 // result. (note that AEK_NONE doesn't have a name so it won't be in the
1545 // result despite its bit being set)
1546 std::vector<StringRef> AllFeatures;
1547 EXPECT_TRUE(AArch64::getExtensionFeatures(-1, AllFeatures));
1548 EXPECT_THAT(Features, ::testing::ContainerEq(AllFeatures));
1551 TEST(TargetParserTest, AArch64ArchFeatures) {
1552 std::vector<StringRef> Features;
1554 for (auto AK : AArch64::ArchKinds) {
1555 if (AK == AArch64::ArchKind::INVALID)
1556 EXPECT_FALSE(AArch64::getArchFeatures(AK, Features));
1557 else
1558 EXPECT_TRUE(AArch64::getArchFeatures(AK, Features));
1562 TEST(TargetParserTest, AArch64ArchExtFeature) {
1563 const char *ArchExt[][4] = {
1564 {"crc", "nocrc", "+crc", "-crc"},
1565 {"crypto", "nocrypto", "+crypto", "-crypto"},
1566 {"flagm", "noflagm", "+flagm", "-flagm"},
1567 {"fp", "nofp", "+fp-armv8", "-fp-armv8"},
1568 {"simd", "nosimd", "+neon", "-neon"},
1569 {"fp16", "nofp16", "+fullfp16", "-fullfp16"},
1570 {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"},
1571 {"profile", "noprofile", "+spe", "-spe"},
1572 {"ras", "noras", "+ras", "-ras"},
1573 {"lse", "nolse", "+lse", "-lse"},
1574 {"rdm", "nordm", "+rdm", "-rdm"},
1575 {"sve", "nosve", "+sve", "-sve"},
1576 {"sve2", "nosve2", "+sve2", "-sve2"},
1577 {"sve2-aes", "nosve2-aes", "+sve2-aes", "-sve2-aes"},
1578 {"sve2-sm4", "nosve2-sm4", "+sve2-sm4", "-sve2-sm4"},
1579 {"sve2-sha3", "nosve2-sha3", "+sve2-sha3", "-sve2-sha3"},
1580 {"sve2-bitperm", "nosve2-bitperm", "+sve2-bitperm", "-sve2-bitperm"},
1581 {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
1582 {"rcpc", "norcpc", "+rcpc", "-rcpc"},
1583 {"rng", "norng", "+rand", "-rand"},
1584 {"memtag", "nomemtag", "+mte", "-mte"},
1585 {"tme", "notme", "+tme", "-tme"},
1586 {"pauth", "nopauth", "+pauth", "-pauth"},
1587 {"ssbs", "nossbs", "+ssbs", "-ssbs"},
1588 {"sb", "nosb", "+sb", "-sb"},
1589 {"predres", "nopredres", "+predres", "-predres"},
1590 {"i8mm", "noi8mm", "+i8mm", "-i8mm"},
1591 {"f32mm", "nof32mm", "+f32mm", "-f32mm"},
1592 {"f64mm", "nof64mm", "+f64mm", "-f64mm"},
1593 {"sme", "nosme", "+sme", "-sme"},
1594 {"sme-f64", "nosme-f64", "+sme-f64", "-sme-f64"},
1595 {"sme-i64", "nosme-i64", "+sme-i64", "-sme-i64"},
1596 {"hbc", "nohbc", "+hbc", "-hbc"},
1597 {"mops", "nomops", "+mops", "-mops"},
1598 {"pmuv3", "nopmuv3", "+perfmon", "-perfmon"},
1601 for (unsigned i = 0; i < array_lengthof(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 } // namespace