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 //===----------------------------------------------------------------------===// 8 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> 25 26 using namespace llvm; 27 28 using ::testing::Contains; 29 using ::testing::StrEq; 30 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", 49 }; 50 51 std::string FormatExtensionFlags(int64_t Flags) { 52 std::vector<StringRef> Features; 53 54 if (Flags & ARM::AEK_NONE) 55 Features.push_back("none"); 56 ARM::getExtensionFeatures(Flags, Features); 57 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()); 65 66 return llvm::join(Features, ", "); 67 } 68 69 std::string FormatExtensionFlags(AArch64::ExtensionBitset Flags) { 70 std::vector<StringRef> Features; 71 72 // AEK_NONE is not meant to be shown to the user so the target parser 73 // does not recognise it. It is relevant here though. 74 if (Flags.test(AArch64::AEK_NONE)) 75 Features.push_back("none"); 76 AArch64::getExtensionFeatures(Flags, Features); 77 78 // The target parser also includes every extension you don't have. 79 // E.g. if AEK_CRC is not set then it adds "-crc". Not useful here. 80 Features.erase(std::remove_if(Features.begin(), Features.end(), 81 [](StringRef extension) { 82 return extension.starts_with("-"); 83 }), 84 Features.end()); 85 86 return llvm::join(Features, ", "); 87 } 88 89 std::string SerializeExtensionFlags(AArch64::ExtensionBitset Flags) { 90 std::string SerializedFlags; 91 std::ostringstream ss; 92 int HexValue = 0; 93 for (unsigned int i = 0; i < AArch64::AEK_NUM_EXTENSIONS; i++) { 94 HexValue <<= 1; 95 HexValue |= (int)Flags[i]; 96 if ((i + 1) % 4 == 0) { 97 ss << std::hex << HexValue; 98 HexValue = 0; 99 } 100 } 101 // check if there are remainig unhandled bits 102 if ((AArch64::AEK_NUM_EXTENSIONS % 4) != 0) 103 ss << std::hex << HexValue; 104 105 SerializedFlags = ss.str(); 106 return SerializedFlags; 107 } 108 109 template <ARM::ISAKind ISAKind> struct AssertSameExtensionFlags { 110 AssertSameExtensionFlags(StringRef CPUName) : CPUName(CPUName) {} 111 112 testing::AssertionResult operator()(const char *m_expr, const char *n_expr, 113 uint64_t ExpectedFlags, 114 uint64_t GotFlags) { 115 if (ExpectedFlags == GotFlags) 116 return testing::AssertionSuccess(); 117 118 return testing::AssertionFailure() << llvm::formatv( 119 "CPU: {4}\n" 120 "Expected extension flags: {0} ({1:x})\n" 121 " Got extension flags: {2} ({3:x})\n", 122 FormatExtensionFlags(ExpectedFlags), 123 ExpectedFlags, FormatExtensionFlags(GotFlags), 124 ExpectedFlags, CPUName); 125 } 126 127 testing::AssertionResult 128 operator()(const char *m_expr, const char *n_expr, 129 AArch64::ExtensionBitset ExpectedFlags, 130 AArch64::ExtensionBitset GotFlags) { 131 if (ExpectedFlags == GotFlags) 132 return testing::AssertionSuccess(); 133 134 return testing::AssertionFailure() << llvm::formatv( 135 "CPU: {4}\n" 136 "Expected extension flags: {0} ({1})\n" 137 " Got extension flags: {2} ({3})\n", 138 FormatExtensionFlags(ExpectedFlags), 139 SerializeExtensionFlags(ExpectedFlags), 140 FormatExtensionFlags(GotFlags), 141 SerializeExtensionFlags(ExpectedFlags), CPUName); 142 } 143 144 private: 145 StringRef CPUName; 146 }; 147 148 template <typename T> struct ARMCPUTestParams { 149 ARMCPUTestParams(StringRef CPUName, StringRef ExpectedArch, 150 StringRef ExpectedFPU, T ExpectedFlags, StringRef CPUAttr) 151 : CPUName(CPUName), ExpectedArch(ExpectedArch), ExpectedFPU(ExpectedFPU), 152 ExpectedFlags(ExpectedFlags), CPUAttr(CPUAttr) {} 153 154 friend std::ostream &operator<<(std::ostream &os, 155 const ARMCPUTestParams<T> ¶ms) { 156 os << "\"" << params.CPUName.str() << "\", \"" << params.ExpectedArch.str() 157 << "\", \"" << params.ExpectedFPU.str() << "\", 0x"; 158 if constexpr (std::is_same<T, uint64_t>::value) 159 os << std::hex << params.ExpectedFlags; 160 else 161 os << SerializeExtensionFlags(params.ExpectedFlags); 162 os << ", \"" << params.CPUAttr.str() << "\""; 163 return os; 164 } 165 166 /// Print a gtest-compatible facsimile of the CPUName, to make the test's name 167 /// human-readable. 168 /// 169 /// https://github.com/google/googletest/blob/main/docs/advanced.md#specifying-names-for-value-parameterized-test-parameters 170 static std::string 171 PrintToStringParamName(const testing::TestParamInfo<ARMCPUTestParams<T>>& Info) { 172 std::string Name = Info.param.CPUName.str(); 173 for (char &C : Name) 174 if (!std::isalnum(C)) 175 C = '_'; 176 return Name; 177 } 178 179 StringRef CPUName; 180 StringRef ExpectedArch; 181 StringRef ExpectedFPU; 182 T ExpectedFlags; 183 StringRef CPUAttr; 184 }; 185 186 class ARMCPUTestFixture 187 : public ::testing::TestWithParam<ARMCPUTestParams<uint64_t>> {}; 188 189 TEST_P(ARMCPUTestFixture, ARMCPUTests) { 190 auto params = GetParam(); 191 192 ARM::ArchKind AK = ARM::parseCPUArch(params.CPUName); 193 EXPECT_EQ(params.ExpectedArch, ARM::getArchName(AK)); 194 195 ARM::FPUKind FPUKind = ARM::getDefaultFPU(params.CPUName, AK); 196 EXPECT_EQ(params.ExpectedFPU, ARM::getFPUName(FPUKind)); 197 198 uint64_t default_extensions = ARM::getDefaultExtensions(params.CPUName, AK); 199 EXPECT_PRED_FORMAT2( 200 AssertSameExtensionFlags<ARM::ISAKind::ARM>(params.CPUName), 201 params.ExpectedFlags, default_extensions); 202 203 EXPECT_EQ(params.CPUAttr, ARM::getCPUAttr(AK)); 204 } 205 206 // Note that we include ARM::AEK_NONE even when there are other extensions 207 // we expect. This is because the default extensions for a CPU are the sum 208 // of the default extensions for its architecture and for the CPU. 209 // So if a CPU has no extra extensions, it adds AEK_NONE. 210 INSTANTIATE_TEST_SUITE_P( 211 ARMCPUTestsPart1, ARMCPUTestFixture, 212 ::testing::Values( 213 ARMCPUTestParams<uint64_t>("invalid", "invalid", "invalid", ARM::AEK_NONE, ""), 214 ARMCPUTestParams<uint64_t>("generic", "invalid", "none", ARM::AEK_NONE, ""), 215 216 ARMCPUTestParams<uint64_t>("arm8", "armv4", "none", ARM::AEK_NONE, "4"), 217 ARMCPUTestParams<uint64_t>("arm810", "armv4", "none", ARM::AEK_NONE, "4"), 218 ARMCPUTestParams<uint64_t>("strongarm", "armv4", "none", ARM::AEK_NONE, "4"), 219 ARMCPUTestParams<uint64_t>("strongarm110", "armv4", "none", ARM::AEK_NONE, "4"), 220 ARMCPUTestParams<uint64_t>("strongarm1100", "armv4", "none", ARM::AEK_NONE, "4"), 221 ARMCPUTestParams<uint64_t>("strongarm1110", "armv4", "none", ARM::AEK_NONE, "4"), 222 ARMCPUTestParams<uint64_t>("arm7tdmi", "armv4t", "none", ARM::AEK_NONE, "4T"), 223 ARMCPUTestParams<uint64_t>("arm7tdmi-s", "armv4t", "none", ARM::AEK_NONE, "4T"), 224 ARMCPUTestParams<uint64_t>("arm710t", "armv4t", "none", ARM::AEK_NONE, "4T"), 225 ARMCPUTestParams<uint64_t>("arm720t", "armv4t", "none", ARM::AEK_NONE, "4T"), 226 ARMCPUTestParams<uint64_t>("arm9", "armv4t", "none", ARM::AEK_NONE, "4T"), 227 ARMCPUTestParams<uint64_t>("arm9tdmi", "armv4t", "none", ARM::AEK_NONE, "4T"), 228 ARMCPUTestParams<uint64_t>("arm920", "armv4t", "none", ARM::AEK_NONE, "4T"), 229 ARMCPUTestParams<uint64_t>("arm920t", "armv4t", "none", ARM::AEK_NONE, "4T"), 230 ARMCPUTestParams<uint64_t>("arm922t", "armv4t", "none", ARM::AEK_NONE, "4T"), 231 ARMCPUTestParams<uint64_t>("arm940t", "armv4t", "none", ARM::AEK_NONE, "4T"), 232 ARMCPUTestParams<uint64_t>("ep9312", "armv4t", "none", ARM::AEK_NONE, "4T"), 233 ARMCPUTestParams<uint64_t>("arm10tdmi", "armv5t", "none", ARM::AEK_NONE, "5T"), 234 ARMCPUTestParams<uint64_t>("arm1020t", "armv5t", "none", ARM::AEK_NONE, "5T"), 235 ARMCPUTestParams<uint64_t>("arm9e", "armv5te", "none", 236 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"), 237 ARMCPUTestParams<uint64_t>("arm946e-s", "armv5te", "none", 238 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"), 239 ARMCPUTestParams<uint64_t>("arm966e-s", "armv5te", "none", 240 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"), 241 ARMCPUTestParams<uint64_t>("arm968e-s", "armv5te", "none", 242 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"), 243 ARMCPUTestParams<uint64_t>("arm10e", "armv5te", "none", 244 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"), 245 ARMCPUTestParams<uint64_t>("arm1020e", "armv5te", "none", 246 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"), 247 ARMCPUTestParams<uint64_t>("arm1022e", "armv5te", "none", 248 ARM::AEK_NONE | ARM::AEK_DSP, "5TE"), 249 ARMCPUTestParams<uint64_t>("arm926ej-s", "armv5tej", "none", 250 ARM::AEK_NONE | ARM::AEK_DSP, "5TEJ"), 251 ARMCPUTestParams<uint64_t>("arm1136j-s", "armv6", "none", 252 ARM::AEK_NONE | ARM::AEK_DSP, "6"), 253 ARMCPUTestParams<uint64_t>("arm1136jf-s", "armv6", "vfpv2", 254 ARM::AEK_NONE | ARM::AEK_DSP, "6"), 255 ARMCPUTestParams<uint64_t>("arm1176jz-s", "armv6kz", "none", 256 ARM::AEK_NONE | ARM::AEK_SEC | ARM::AEK_DSP, "6KZ"), 257 ARMCPUTestParams<uint64_t>("mpcore", "armv6k", "vfpv2", 258 ARM::AEK_NONE | ARM::AEK_DSP, "6K"), 259 ARMCPUTestParams<uint64_t>("mpcorenovfp", "armv6k", "none", 260 ARM::AEK_NONE | ARM::AEK_DSP, "6K"), 261 ARMCPUTestParams<uint64_t>("arm1176jzf-s", "armv6kz", "vfpv2", 262 ARM::AEK_NONE | ARM::AEK_SEC | ARM::AEK_DSP, "6KZ"), 263 ARMCPUTestParams<uint64_t>("arm1156t2-s", "armv6t2", "none", 264 ARM::AEK_NONE | ARM::AEK_DSP, "6T2"), 265 ARMCPUTestParams<uint64_t>("arm1156t2f-s", "armv6t2", "vfpv2", 266 ARM::AEK_NONE | ARM::AEK_DSP, "6T2"), 267 ARMCPUTestParams<uint64_t>("cortex-m0", "armv6-m", "none", ARM::AEK_NONE, "6-M"), 268 ARMCPUTestParams<uint64_t>("cortex-m0plus", "armv6-m", "none", ARM::AEK_NONE, 269 "6-M"), 270 ARMCPUTestParams<uint64_t>("cortex-m1", "armv6-m", "none", ARM::AEK_NONE, "6-M"), 271 ARMCPUTestParams<uint64_t>("sc000", "armv6-m", "none", ARM::AEK_NONE, "6-M"), 272 ARMCPUTestParams<uint64_t>("cortex-a5", "armv7-a", "neon-vfpv4", 273 ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP, "7-A"), 274 ARMCPUTestParams<uint64_t>("cortex-a7", "armv7-a", "neon-vfpv4", 275 ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM | ARM::AEK_MP | 276 ARM::AEK_SEC | ARM::AEK_VIRT | ARM::AEK_DSP, 277 "7-A"), 278 ARMCPUTestParams<uint64_t>("cortex-a8", "armv7-a", "neon", 279 ARM::AEK_SEC | ARM::AEK_DSP, "7-A")), 280 ARMCPUTestParams<uint64_t>::PrintToStringParamName); 281 282 // gtest in llvm has a limit of 50 test cases when using ::Values so we split 283 // them into 2 blocks 284 INSTANTIATE_TEST_SUITE_P( 285 ARMCPUTestsPart2, ARMCPUTestFixture, 286 ::testing::Values( 287 ARMCPUTestParams<uint64_t>("cortex-a9", "armv7-a", "neon-fp16", 288 ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP, "7-A"), 289 ARMCPUTestParams<uint64_t>("cortex-a12", "armv7-a", "neon-vfpv4", 290 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 291 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 292 ARM::AEK_DSP, 293 "7-A"), 294 ARMCPUTestParams<uint64_t>("cortex-a15", "armv7-a", "neon-vfpv4", 295 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 296 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 297 ARM::AEK_DSP, 298 "7-A"), 299 ARMCPUTestParams<uint64_t>("cortex-a17", "armv7-a", "neon-vfpv4", 300 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 301 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 302 ARM::AEK_DSP, 303 "7-A"), 304 ARMCPUTestParams<uint64_t>("krait", "armv7-a", "neon-vfpv4", 305 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 306 "7-A"), 307 ARMCPUTestParams<uint64_t>("cortex-r4", "armv7-r", "none", 308 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 309 "7-R"), 310 ARMCPUTestParams<uint64_t>("cortex-r4f", "armv7-r", "vfpv3-d16", 311 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 312 "7-R"), 313 ARMCPUTestParams<uint64_t>("cortex-r5", "armv7-r", "vfpv3-d16", 314 ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 315 ARM::AEK_DSP, 316 "7-R"), 317 ARMCPUTestParams<uint64_t>("cortex-r7", "armv7-r", "vfpv3-d16-fp16", 318 ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 319 ARM::AEK_DSP, 320 "7-R"), 321 ARMCPUTestParams<uint64_t>("cortex-r8", "armv7-r", "vfpv3-d16-fp16", 322 ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 323 ARM::AEK_DSP, 324 "7-R"), 325 ARMCPUTestParams<uint64_t>("cortex-r52", "armv8-r", "neon-fp-armv8", 326 ARM::AEK_NONE | ARM::AEK_CRC | ARM::AEK_MP | 327 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 328 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 329 "8-R"), 330 ARMCPUTestParams<uint64_t>("sc300", "armv7-m", "none", 331 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "7-M"), 332 ARMCPUTestParams<uint64_t>("cortex-m3", "armv7-m", "none", 333 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "7-M"), 334 ARMCPUTestParams<uint64_t>("cortex-m4", "armv7e-m", "fpv4-sp-d16", 335 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 336 "7E-M"), 337 ARMCPUTestParams<uint64_t>("cortex-m7", "armv7e-m", "fpv5-d16", 338 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 339 "7E-M"), 340 ARMCPUTestParams<uint64_t>("cortex-a32", "armv8-a", "crypto-neon-fp-armv8", 341 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 342 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 343 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 344 "8-A"), 345 ARMCPUTestParams<uint64_t>("cortex-a35", "armv8-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 "8-A"), 350 ARMCPUTestParams<uint64_t>("cortex-a53", "armv8-a", "crypto-neon-fp-armv8", 351 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 352 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 353 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 354 "8-A"), 355 ARMCPUTestParams<uint64_t>("cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8", 356 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 357 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 358 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | 359 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD, 360 "8.2-A"), 361 ARMCPUTestParams<uint64_t>("cortex-a57", "armv8-a", "crypto-neon-fp-armv8", 362 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 363 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 364 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 365 "8-A"), 366 ARMCPUTestParams<uint64_t>("cortex-a72", "armv8-a", "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-a73", "armv8-a", "crypto-neon-fp-armv8", 372 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 373 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 374 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 375 "8-A"), 376 ARMCPUTestParams<uint64_t>("cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8", 377 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 378 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 379 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | 380 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD, 381 "8.2-A"), 382 ARMCPUTestParams<uint64_t>("cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8", 383 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 384 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 385 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | 386 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD, 387 "8.2-A"), 388 ARMCPUTestParams<uint64_t>("cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8", 389 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 390 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 391 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | 392 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD, 393 "8.2-A"), 394 ARMCPUTestParams<uint64_t>("cortex-a78c", "armv8.2-a", "crypto-neon-fp-armv8", 395 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 396 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 397 ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS | 398 ARM::AEK_FP16 | ARM::AEK_DOTPROD, 399 "8.2-A"), 400 ARMCPUTestParams<uint64_t>("cortex-a710", "armv9-a", "neon-fp-armv8", 401 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 402 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 403 ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS | 404 ARM::AEK_DOTPROD | ARM::AEK_FP16FML | 405 ARM::AEK_BF16 | ARM::AEK_I8MM | ARM::AEK_SB, 406 "9-A"), 407 ARMCPUTestParams<uint64_t>("cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8", 408 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 409 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 410 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | 411 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD, 412 "8.2-A"), 413 ARMCPUTestParams<uint64_t>("cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8", 414 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_SEC | 415 ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 416 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC | 417 ARM::AEK_RAS, 418 "8.2-A"), 419 ARMCPUTestParams<uint64_t>("cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8", 420 ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD | 421 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 422 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 423 ARM::AEK_DSP | ARM::AEK_CRC, 424 "8.2-A"), 425 ARMCPUTestParams<uint64_t>("cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8", 426 ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD | 427 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 428 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 429 ARM::AEK_DSP | ARM::AEK_CRC, 430 "8.2-A"), 431 ARMCPUTestParams<uint64_t>("neoverse-n1", "armv8.2-a", "crypto-neon-fp-armv8", 432 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 433 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 434 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | 435 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD, 436 "8.2-A"), 437 ARMCPUTestParams<uint64_t>("neoverse-n2", "armv9-a", "neon-fp-armv8", 438 ARM::AEK_CRC | ARM::AEK_HWDIVTHUMB | 439 ARM::AEK_HWDIVARM | ARM::AEK_MP | ARM::AEK_SEC | 440 ARM::AEK_VIRT | ARM::AEK_DSP | ARM::AEK_BF16 | 441 ARM::AEK_DOTPROD | ARM::AEK_RAS | ARM::AEK_I8MM | 442 ARM::AEK_SB, 443 "9-A"), 444 ARMCPUTestParams<uint64_t>("neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8", 445 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 446 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 447 ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS | 448 ARM::AEK_FP16 | ARM::AEK_BF16 | ARM::AEK_DOTPROD, 449 "8.4-A"), 450 ARMCPUTestParams<uint64_t>("cyclone", "armv8-a", "crypto-neon-fp-armv8", 451 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 452 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 453 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 454 "8-A"), 455 ARMCPUTestParams<uint64_t>("exynos-m3", "armv8-a", "crypto-neon-fp-armv8", 456 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 457 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 458 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 459 "8-A"), 460 ARMCPUTestParams<uint64_t>("exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8", 461 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 462 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 463 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | 464 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS, 465 "8.2-A"), 466 ARMCPUTestParams<uint64_t>("exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8", 467 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 468 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 469 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | 470 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS, 471 "8.2-A"), 472 ARMCPUTestParams<uint64_t>("cortex-m23", "armv8-m.base", "none", 473 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, "8-M.Baseline"), 474 ARMCPUTestParams<uint64_t>("cortex-m33", "armv8-m.main", "fpv5-sp-d16", 475 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "8-M.Mainline"), 476 ARMCPUTestParams<uint64_t>("cortex-m35p", "armv8-m.main", "fpv5-sp-d16", 477 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "8-M.Mainline"), 478 ARMCPUTestParams<uint64_t>("cortex-m55", "armv8.1-m.main", 479 "fp-armv8-fullfp16-d16", 480 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | 481 ARM::AEK_FP | ARM::AEK_RAS | ARM::AEK_LOB | 482 ARM::AEK_FP16, 483 "8.1-M.Mainline"), 484 ARMCPUTestParams<uint64_t>("cortex-m85", "armv8.1-m.main", 485 "fp-armv8-fullfp16-d16", 486 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | 487 ARM::AEK_FP | ARM::AEK_RAS | ARM::AEK_LOB | 488 ARM::AEK_FP16 | ARM::AEK_PACBTI, 489 "8.1-M.Mainline"), 490 ARMCPUTestParams<uint64_t>("cortex-m52", "armv8.1-m.main", 491 "fp-armv8-fullfp16-d16", 492 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | 493 ARM::AEK_FP | ARM::AEK_RAS | ARM::AEK_LOB | 494 ARM::AEK_FP16 | ARM::AEK_PACBTI, 495 "8.1-M.Mainline"), 496 ARMCPUTestParams<uint64_t>("iwmmxt", "iwmmxt", "none", ARM::AEK_NONE, "iwmmxt"), 497 ARMCPUTestParams<uint64_t>("xscale", "xscale", "none", ARM::AEK_NONE, "xscale"), 498 ARMCPUTestParams<uint64_t>("swift", "armv7s", "neon-vfpv4", 499 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 500 "7-S")), 501 ARMCPUTestParams<uint64_t>::PrintToStringParamName); 502 503 static constexpr unsigned NumARMCPUArchs = 90; 504 505 TEST(TargetParserTest, testARMCPUArchList) { 506 SmallVector<StringRef, NumARMCPUArchs> List; 507 ARM::fillValidCPUArchList(List); 508 509 // No list exists for these in this test suite, so ensure all are 510 // valid, and match the expected 'magic' count. 511 EXPECT_EQ(List.size(), NumARMCPUArchs); 512 for(StringRef CPU : List) { 513 EXPECT_NE(ARM::parseCPUArch(CPU), ARM::ArchKind::INVALID); 514 } 515 } 516 517 TEST(TargetParserTest, testInvalidARMArch) { 518 auto InvalidArchStrings = {"armv", "armv99", "noarm"}; 519 for (const char* InvalidArch : InvalidArchStrings) 520 EXPECT_EQ(ARM::parseArch(InvalidArch), ARM::ArchKind::INVALID); 521 } 522 523 bool testARMArch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch, 524 unsigned ArchAttr) { 525 ARM::ArchKind AK = ARM::parseArch(Arch); 526 bool Result = (AK != ARM::ArchKind::INVALID); 527 Result &= ARM::getDefaultCPU(Arch).equals(DefaultCPU); 528 Result &= ARM::getSubArch(AK).equals(SubArch); 529 Result &= (ARM::getArchAttr(AK) == ArchAttr); 530 return Result; 531 } 532 533 TEST(TargetParserTest, testARMArch) { 534 EXPECT_TRUE( 535 testARMArch("armv4", "strongarm", "v4", 536 ARMBuildAttrs::CPUArch::v4)); 537 EXPECT_TRUE( 538 testARMArch("armv4t", "arm7tdmi", "v4t", 539 ARMBuildAttrs::CPUArch::v4T)); 540 EXPECT_TRUE( 541 testARMArch("armv5t", "arm10tdmi", "v5", 542 ARMBuildAttrs::CPUArch::v5T)); 543 EXPECT_TRUE( 544 testARMArch("armv5te", "arm1022e", "v5e", 545 ARMBuildAttrs::CPUArch::v5TE)); 546 EXPECT_TRUE( 547 testARMArch("armv5tej", "arm926ej-s", "v5e", 548 ARMBuildAttrs::CPUArch::v5TEJ)); 549 EXPECT_TRUE( 550 testARMArch("armv6", "arm1136jf-s", "v6", 551 ARMBuildAttrs::CPUArch::v6)); 552 EXPECT_TRUE( 553 testARMArch("armv6k", "mpcore", "v6k", 554 ARMBuildAttrs::CPUArch::v6K)); 555 EXPECT_TRUE( 556 testARMArch("armv6t2", "arm1156t2-s", "v6t2", 557 ARMBuildAttrs::CPUArch::v6T2)); 558 EXPECT_TRUE( 559 testARMArch("armv6kz", "arm1176jzf-s", "v6kz", 560 ARMBuildAttrs::CPUArch::v6KZ)); 561 EXPECT_TRUE( 562 testARMArch("armv6-m", "cortex-m0", "v6m", 563 ARMBuildAttrs::CPUArch::v6_M)); 564 EXPECT_TRUE( 565 testARMArch("armv7-a", "generic", "v7", 566 ARMBuildAttrs::CPUArch::v7)); 567 EXPECT_TRUE( 568 testARMArch("armv7ve", "generic", "v7ve", 569 ARMBuildAttrs::CPUArch::v7)); 570 EXPECT_TRUE( 571 testARMArch("armv7-r", "cortex-r4", "v7r", 572 ARMBuildAttrs::CPUArch::v7)); 573 EXPECT_TRUE( 574 testARMArch("armv7-m", "cortex-m3", "v7m", 575 ARMBuildAttrs::CPUArch::v7)); 576 EXPECT_TRUE( 577 testARMArch("armv7e-m", "cortex-m4", "v7em", 578 ARMBuildAttrs::CPUArch::v7E_M)); 579 EXPECT_TRUE( 580 testARMArch("armv8-a", "generic", "v8a", 581 ARMBuildAttrs::CPUArch::v8_A)); 582 EXPECT_TRUE( 583 testARMArch("armv8.1-a", "generic", "v8.1a", 584 ARMBuildAttrs::CPUArch::v8_A)); 585 EXPECT_TRUE( 586 testARMArch("armv8.2-a", "generic", "v8.2a", 587 ARMBuildAttrs::CPUArch::v8_A)); 588 EXPECT_TRUE( 589 testARMArch("armv8.3-a", "generic", "v8.3a", 590 ARMBuildAttrs::CPUArch::v8_A)); 591 EXPECT_TRUE( 592 testARMArch("armv8.4-a", "generic", "v8.4a", 593 ARMBuildAttrs::CPUArch::v8_A)); 594 EXPECT_TRUE( 595 testARMArch("armv8.5-a", "generic", "v8.5a", 596 ARMBuildAttrs::CPUArch::v8_A)); 597 EXPECT_TRUE( 598 testARMArch("armv8.6-a", "generic", "v8.6a", 599 ARMBuildAttrs::CPUArch::v8_A)); 600 EXPECT_TRUE( 601 testARMArch("armv8.7-a", "generic", "v8.7a", 602 ARMBuildAttrs::CPUArch::v8_A)); 603 EXPECT_TRUE(testARMArch("armv8.8-a", "generic", "v8.8a", 604 ARMBuildAttrs::CPUArch::v8_A)); 605 EXPECT_TRUE( 606 testARMArch("armv8.9-a", "generic", "v8.9a", 607 ARMBuildAttrs::CPUArch::v8_A)); 608 EXPECT_TRUE( 609 testARMArch("armv9-a", "generic", "v9a", 610 ARMBuildAttrs::CPUArch::v9_A)); 611 EXPECT_TRUE( 612 testARMArch("armv9.1-a", "generic", "v9.1a", 613 ARMBuildAttrs::CPUArch::v9_A)); 614 EXPECT_TRUE( 615 testARMArch("armv9.2-a", "generic", "v9.2a", 616 ARMBuildAttrs::CPUArch::v9_A)); 617 EXPECT_TRUE( 618 testARMArch("armv9.3-a", "generic", "v9.3a", 619 ARMBuildAttrs::CPUArch::v9_A)); 620 EXPECT_TRUE( 621 testARMArch("armv9.4-a", "generic", "v9.4a", 622 ARMBuildAttrs::CPUArch::v9_A)); 623 EXPECT_TRUE( 624 testARMArch("armv9.5-a", "generic", "v9.5a", 625 ARMBuildAttrs::CPUArch::v9_A)); 626 EXPECT_TRUE( 627 testARMArch("armv8-r", "cortex-r52", "v8r", 628 ARMBuildAttrs::CPUArch::v8_R)); 629 EXPECT_TRUE( 630 testARMArch("armv8-m.base", "generic", "v8m.base", 631 ARMBuildAttrs::CPUArch::v8_M_Base)); 632 EXPECT_TRUE( 633 testARMArch("armv8-m.main", "generic", "v8m.main", 634 ARMBuildAttrs::CPUArch::v8_M_Main)); 635 EXPECT_TRUE( 636 testARMArch("armv8.1-m.main", "generic", "v8.1m.main", 637 ARMBuildAttrs::CPUArch::v8_1_M_Main)); 638 EXPECT_TRUE( 639 testARMArch("iwmmxt", "iwmmxt", "", 640 ARMBuildAttrs::CPUArch::v5TE)); 641 EXPECT_TRUE( 642 testARMArch("iwmmxt2", "generic", "", 643 ARMBuildAttrs::CPUArch::v5TE)); 644 EXPECT_TRUE( 645 testARMArch("xscale", "xscale", "v5e", 646 ARMBuildAttrs::CPUArch::v5TE)); 647 EXPECT_TRUE( 648 testARMArch("armv7s", "swift", "v7s", 649 ARMBuildAttrs::CPUArch::v7)); 650 EXPECT_TRUE( 651 testARMArch("armv7k", "generic", "v7k", 652 ARMBuildAttrs::CPUArch::v7)); 653 } 654 655 bool testARMExtension(StringRef CPUName,ARM::ArchKind ArchKind, StringRef ArchExt) { 656 return ARM::getDefaultExtensions(CPUName, ArchKind) & 657 ARM::parseArchExt(ArchExt); 658 } 659 660 TEST(TargetParserTest, testARMExtension) { 661 EXPECT_FALSE(testARMExtension("strongarm", ARM::ArchKind::INVALID, "dsp")); 662 EXPECT_FALSE(testARMExtension("arm7tdmi", ARM::ArchKind::INVALID, "dsp")); 663 EXPECT_FALSE(testARMExtension("arm10tdmi", 664 ARM::ArchKind::INVALID, "simd")); 665 EXPECT_FALSE(testARMExtension("arm1022e", ARM::ArchKind::INVALID, "simd")); 666 EXPECT_FALSE(testARMExtension("arm926ej-s", 667 ARM::ArchKind::INVALID, "simd")); 668 EXPECT_FALSE(testARMExtension("arm1136jf-s", 669 ARM::ArchKind::INVALID, "crypto")); 670 EXPECT_FALSE(testARMExtension("arm1156t2-s", 671 ARM::ArchKind::INVALID, "crypto")); 672 EXPECT_FALSE(testARMExtension("arm1176jzf-s", 673 ARM::ArchKind::INVALID, "crypto")); 674 EXPECT_FALSE(testARMExtension("cortex-m0", 675 ARM::ArchKind::INVALID, "crypto")); 676 EXPECT_FALSE(testARMExtension("cortex-a8", 677 ARM::ArchKind::INVALID, "crypto")); 678 EXPECT_FALSE(testARMExtension("cortex-r4", 679 ARM::ArchKind::INVALID, "crypto")); 680 EXPECT_FALSE(testARMExtension("cortex-m3", 681 ARM::ArchKind::INVALID, "crypto")); 682 EXPECT_FALSE(testARMExtension("cortex-a53", 683 ARM::ArchKind::INVALID, "ras")); 684 EXPECT_FALSE(testARMExtension("cortex-a53", 685 ARM::ArchKind::INVALID, "fp16")); 686 EXPECT_TRUE(testARMExtension("cortex-a55", 687 ARM::ArchKind::INVALID, "fp16")); 688 EXPECT_FALSE(testARMExtension("cortex-a55", 689 ARM::ArchKind::INVALID, "fp16fml")); 690 EXPECT_TRUE(testARMExtension("cortex-a75", 691 ARM::ArchKind::INVALID, "fp16")); 692 EXPECT_FALSE(testARMExtension("cortex-a75", 693 ARM::ArchKind::INVALID, "fp16fml")); 694 EXPECT_FALSE(testARMExtension("cortex-r52", 695 ARM::ArchKind::INVALID, "ras")); 696 EXPECT_FALSE(testARMExtension("iwmmxt", ARM::ArchKind::INVALID, "crc")); 697 EXPECT_FALSE(testARMExtension("xscale", ARM::ArchKind::INVALID, "crc")); 698 EXPECT_FALSE(testARMExtension("swift", ARM::ArchKind::INVALID, "crc")); 699 700 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4, "dsp")); 701 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4T, "dsp")); 702 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5T, "simd")); 703 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TE, "simd")); 704 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TEJ, "simd")); 705 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6, "crypto")); 706 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6K, "crypto")); 707 EXPECT_FALSE(testARMExtension("generic", 708 ARM::ArchKind::ARMV6T2, "crypto")); 709 EXPECT_FALSE(testARMExtension("generic", 710 ARM::ArchKind::ARMV6KZ, "crypto")); 711 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6M, "crypto")); 712 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7A, "crypto")); 713 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7R, "crypto")); 714 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7M, "crypto")); 715 EXPECT_FALSE(testARMExtension("generic", 716 ARM::ArchKind::ARMV7EM, "crypto")); 717 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8A, "ras")); 718 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_1A, "ras")); 719 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "profile")); 720 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16")); 721 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16fml")); 722 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A, "fp16")); 723 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A, "fp16fml")); 724 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A, "fp16")); 725 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A, "fp16fml")); 726 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8R, "ras")); 727 EXPECT_FALSE(testARMExtension("generic", 728 ARM::ArchKind::ARMV8MBaseline, "crc")); 729 EXPECT_FALSE(testARMExtension("generic", 730 ARM::ArchKind::ARMV8MMainline, "crc")); 731 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT, "crc")); 732 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT2, "crc")); 733 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::XSCALE, "crc")); 734 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7S, "crypto")); 735 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7K, "crypto")); 736 } 737 738 TEST(TargetParserTest, ARMFPUVersion) { 739 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0); 740 FK <= ARM::FPUKind::FK_LAST; 741 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) 742 if (FK == ARM::FK_LAST || ARM::getFPUName(FK) == "invalid" || 743 ARM::getFPUName(FK) == "none" || ARM::getFPUName(FK) == "softvfp") 744 EXPECT_EQ(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK)); 745 else 746 EXPECT_NE(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK)); 747 } 748 749 TEST(TargetParserTest, ARMFPUNeonSupportLevel) { 750 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0); 751 FK <= ARM::FPUKind::FK_LAST; 752 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) 753 if (FK == ARM::FK_LAST || 754 ARM::getFPUName(FK).find("neon") == std::string::npos) 755 EXPECT_EQ(ARM::NeonSupportLevel::None, 756 ARM::getFPUNeonSupportLevel(FK)); 757 else 758 EXPECT_NE(ARM::NeonSupportLevel::None, 759 ARM::getFPUNeonSupportLevel(FK)); 760 } 761 762 TEST(TargetParserTest, ARMFPURestriction) { 763 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0); 764 FK <= ARM::FPUKind::FK_LAST; 765 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) { 766 if (FK == ARM::FK_LAST || 767 (ARM::getFPUName(FK).find("d16") == std::string::npos && 768 ARM::getFPUName(FK).find("vfpv3xd") == std::string::npos)) 769 EXPECT_EQ(ARM::FPURestriction::None, ARM::getFPURestriction(FK)); 770 else 771 EXPECT_NE(ARM::FPURestriction::None, ARM::getFPURestriction(FK)); 772 } 773 } 774 775 TEST(TargetParserTest, ARMExtensionFeatures) { 776 std::map<uint64_t, std::vector<StringRef>> Extensions; 777 778 for (auto &Ext : ARM::ARCHExtNames) { 779 if (!Ext.Feature.empty() && !Ext.NegFeature.empty()) 780 Extensions[Ext.ID] = {Ext.Feature, Ext.NegFeature}; 781 } 782 783 Extensions[ARM::AEK_HWDIVARM] = { "+hwdiv-arm", "-hwdiv-arm" }; 784 Extensions[ARM::AEK_HWDIVTHUMB] = { "+hwdiv", "-hwdiv" }; 785 786 std::vector<StringRef> Features; 787 788 EXPECT_FALSE(ARM::getExtensionFeatures(ARM::AEK_INVALID, Features)); 789 790 for (auto &E : Extensions) { 791 // test +extension 792 Features.clear(); 793 ARM::getExtensionFeatures(E.first, Features); 794 EXPECT_TRUE(llvm::is_contained(Features, E.second.at(0))); 795 EXPECT_EQ(Extensions.size(), Features.size()); 796 797 // test -extension 798 Features.clear(); 799 ARM::getExtensionFeatures(~E.first, Features); 800 EXPECT_TRUE(llvm::is_contained(Features, E.second.at(1))); 801 EXPECT_EQ(Extensions.size(), Features.size()); 802 } 803 } 804 805 TEST(TargetParserTest, ARMFPUFeatures) { 806 std::vector<StringRef> Features; 807 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0); 808 FK <= ARM::FPUKind::FK_LAST; 809 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) { 810 if (FK == ARM::FK_INVALID || FK >= ARM::FK_LAST) 811 EXPECT_FALSE(ARM::getFPUFeatures(FK, Features)); 812 else 813 EXPECT_TRUE(ARM::getFPUFeatures(FK, Features)); 814 } 815 } 816 817 TEST(TargetParserTest, ARMArchExtFeature) { 818 const char *ArchExt[][4] = {{"crc", "nocrc", "+crc", "-crc"}, 819 {"crypto", "nocrypto", "+crypto", "-crypto"}, 820 {"dsp", "nodsp", "+dsp", "-dsp"}, 821 {"fp", "nofp", nullptr, nullptr}, 822 {"idiv", "noidiv", nullptr, nullptr}, 823 {"mp", "nomp", nullptr, nullptr}, 824 {"simd", "nosimd", nullptr, nullptr}, 825 {"sec", "nosec", nullptr, nullptr}, 826 {"virt", "novirt", nullptr, nullptr}, 827 {"fp16", "nofp16", "+fullfp16", "-fullfp16"}, 828 {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"}, 829 {"ras", "noras", "+ras", "-ras"}, 830 {"dotprod", "nodotprod", "+dotprod", "-dotprod"}, 831 {"os", "noos", nullptr, nullptr}, 832 {"iwmmxt", "noiwmmxt", nullptr, nullptr}, 833 {"iwmmxt2", "noiwmmxt2", nullptr, nullptr}, 834 {"maverick", "maverick", nullptr, nullptr}, 835 {"xscale", "noxscale", nullptr, nullptr}, 836 {"sb", "nosb", "+sb", "-sb"}, 837 {"i8mm", "noi8mm", "+i8mm", "-i8mm"}, 838 {"mve", "nomve", "+mve", "-mve"}, 839 {"mve.fp", "nomve.fp", "+mve.fp", "-mve.fp"}}; 840 841 for (unsigned i = 0; i < std::size(ArchExt); i++) { 842 EXPECT_EQ(StringRef(ArchExt[i][2]), ARM::getArchExtFeature(ArchExt[i][0])); 843 EXPECT_EQ(StringRef(ArchExt[i][3]), ARM::getArchExtFeature(ArchExt[i][1])); 844 } 845 } 846 847 static bool 848 testArchExtDependency(const char *ArchExt, 849 const std::initializer_list<const char *> &Expected) { 850 std::vector<StringRef> Features; 851 ARM::FPUKind FPUKind; 852 853 if (!ARM::appendArchExtFeatures("", ARM::ArchKind::ARMV8_1MMainline, ArchExt, 854 Features, FPUKind)) 855 return false; 856 857 return llvm::all_of(Expected, [&](StringRef Ext) { 858 return llvm::is_contained(Features, Ext); 859 }); 860 } 861 862 TEST(TargetParserTest, ARMArchExtDependencies) { 863 EXPECT_TRUE(testArchExtDependency("mve", {"+mve", "+dsp"})); 864 EXPECT_TRUE(testArchExtDependency("mve.fp", {"+mve.fp", "+mve", "+dsp"})); 865 EXPECT_TRUE(testArchExtDependency("nodsp", {"-dsp", "-mve", "-mve.fp"})); 866 EXPECT_TRUE(testArchExtDependency("nomve", {"-mve", "-mve.fp"})); 867 } 868 869 TEST(TargetParserTest, ARMparseHWDiv) { 870 const char *hwdiv[] = {"thumb", "arm", "arm,thumb", "thumb,arm"}; 871 872 for (unsigned i = 0; i < std::size(hwdiv); i++) 873 EXPECT_NE(ARM::AEK_INVALID, ARM::parseHWDiv((StringRef)hwdiv[i])); 874 } 875 876 TEST(TargetParserTest, ARMparseArchEndianAndISA) { 877 const char *Arch[] = { 878 "v2", "v2a", "v3", "v3m", "v4", "v4t", 879 "v5", "v5t", "v5e", "v5te", "v5tej", "v6", 880 "v6j", "v6k", "v6hl", "v6t2", "v6kz", "v6z", 881 "v6zk", "v6-m", "v6m", "v6sm", "v6s-m", "v7-a", 882 "v7", "v7a", "v7ve", "v7hl", "v7l", "v7-r", 883 "v7r", "v7-m", "v7m", "v7k", "v7s", "v7e-m", 884 "v7em", "v8-a", "v8", "v8a", "v8l", "v8.1-a", 885 "v8.1a", "v8.2-a", "v8.2a", "v8.3-a", "v8.3a", "v8.4-a", 886 "v8.4a", "v8.5-a", "v8.5a", "v8.6-a", "v8.6a", "v8.7-a", 887 "v8.7a", "v8.8-a", "v8.8a", "v8-r", "v8m.base", "v8m.main", 888 "v8.1m.main"}; 889 890 for (unsigned i = 0; i < std::size(Arch); i++) { 891 std::string arm_1 = "armeb" + (std::string)(Arch[i]); 892 std::string arm_2 = "arm" + (std::string)(Arch[i]) + "eb"; 893 std::string arm_3 = "arm" + (std::string)(Arch[i]); 894 std::string thumb_1 = "thumbeb" + (std::string)(Arch[i]); 895 std::string thumb_2 = "thumb" + (std::string)(Arch[i]) + "eb"; 896 std::string thumb_3 = "thumb" + (std::string)(Arch[i]); 897 898 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_1)); 899 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_2)); 900 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(arm_3)); 901 902 EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_1)); 903 EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_2)); 904 EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_3)); 905 if (i >= 4) { 906 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_1)); 907 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_2)); 908 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(thumb_3)); 909 910 EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_1)); 911 EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_2)); 912 EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_3)); 913 } 914 } 915 916 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("aarch64")); 917 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("arm64_32")); 918 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian("aarch64_be")); 919 920 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64")); 921 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_be")); 922 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64")); 923 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_be")); 924 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_32")); 925 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_32")); 926 } 927 928 TEST(TargetParserTest, ARMparseArchProfile) { 929 for (unsigned i = 0; i < std::size(ARMArch); i++) { 930 switch (ARM::parseArch(ARMArch[i])) { 931 case ARM::ArchKind::ARMV6M: 932 case ARM::ArchKind::ARMV7M: 933 case ARM::ArchKind::ARMV7EM: 934 case ARM::ArchKind::ARMV8MMainline: 935 case ARM::ArchKind::ARMV8MBaseline: 936 case ARM::ArchKind::ARMV8_1MMainline: 937 EXPECT_EQ(ARM::ProfileKind::M, ARM::parseArchProfile(ARMArch[i])); 938 break; 939 case ARM::ArchKind::ARMV7R: 940 case ARM::ArchKind::ARMV8R: 941 EXPECT_EQ(ARM::ProfileKind::R, ARM::parseArchProfile(ARMArch[i])); 942 break; 943 case ARM::ArchKind::ARMV7A: 944 case ARM::ArchKind::ARMV7VE: 945 case ARM::ArchKind::ARMV7K: 946 case ARM::ArchKind::ARMV8A: 947 case ARM::ArchKind::ARMV8_1A: 948 case ARM::ArchKind::ARMV8_2A: 949 case ARM::ArchKind::ARMV8_3A: 950 case ARM::ArchKind::ARMV8_4A: 951 case ARM::ArchKind::ARMV8_5A: 952 case ARM::ArchKind::ARMV8_6A: 953 case ARM::ArchKind::ARMV8_7A: 954 case ARM::ArchKind::ARMV8_8A: 955 case ARM::ArchKind::ARMV8_9A: 956 case ARM::ArchKind::ARMV9A: 957 case ARM::ArchKind::ARMV9_1A: 958 case ARM::ArchKind::ARMV9_2A: 959 case ARM::ArchKind::ARMV9_3A: 960 case ARM::ArchKind::ARMV9_4A: 961 case ARM::ArchKind::ARMV9_5A: 962 EXPECT_EQ(ARM::ProfileKind::A, ARM::parseArchProfile(ARMArch[i])); 963 break; 964 default: 965 EXPECT_EQ(ARM::ProfileKind::INVALID, ARM::parseArchProfile(ARMArch[i])); 966 break; 967 } 968 } 969 } 970 971 TEST(TargetParserTest, ARMparseArchVersion) { 972 for (unsigned i = 0; i < std::size(ARMArch); i++) 973 if (((std::string)ARMArch[i]).substr(0, 4) == "armv") 974 EXPECT_EQ((ARMArch[i][4] - 48u), ARM::parseArchVersion(ARMArch[i])); 975 else 976 EXPECT_EQ(5u, ARM::parseArchVersion(ARMArch[i])); 977 } 978 979 TEST(TargetParserTest, ARMparseArchMinorVersion) { 980 for (unsigned i = 0; i < std::size(ARMArch); i++) 981 if (((std::string)ARMArch[i]).find(".") == 5) 982 EXPECT_EQ((ARMArch[i][6] - 48u), ARM::parseArchMinorVersion(ARMArch[i])); 983 else 984 EXPECT_EQ(0u, ARM::parseArchMinorVersion(ARMArch[i])); 985 } 986 987 TEST(TargetParserTest, getARMCPUForArch) { 988 // Platform specific defaults. 989 { 990 llvm::Triple Triple("arm--nacl"); 991 EXPECT_EQ("cortex-a8", ARM::getARMCPUForArch(Triple)); 992 } 993 { 994 llvm::Triple Triple("arm--openbsd"); 995 EXPECT_EQ("cortex-a8", ARM::getARMCPUForArch(Triple)); 996 } 997 { 998 llvm::Triple Triple("armv6-unknown-freebsd"); 999 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple)); 1000 } 1001 { 1002 llvm::Triple Triple("thumbv6-unknown-freebsd"); 1003 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple)); 1004 } 1005 { 1006 llvm::Triple Triple("armebv6-unknown-freebsd"); 1007 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple)); 1008 } 1009 { 1010 llvm::Triple Triple("arm--win32"); 1011 EXPECT_EQ("cortex-a9", ARM::getARMCPUForArch(Triple)); 1012 EXPECT_EQ("generic", ARM::getARMCPUForArch(Triple, "armv8-a")); 1013 } 1014 // Some alternative architectures 1015 { 1016 llvm::Triple Triple("armv7k-apple-ios9"); 1017 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple)); 1018 } 1019 { 1020 llvm::Triple Triple("armv7k-apple-watchos3"); 1021 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple)); 1022 } 1023 { 1024 llvm::Triple Triple("armv7k-apple-tvos9"); 1025 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple)); 1026 } 1027 // armeb is permitted, but armebeb is not 1028 { 1029 llvm::Triple Triple("armeb-none-eabi"); 1030 EXPECT_EQ("arm7tdmi", ARM::getARMCPUForArch(Triple)); 1031 } 1032 { 1033 llvm::Triple Triple("armebeb-none-eabi"); 1034 EXPECT_EQ("", ARM::getARMCPUForArch(Triple)); 1035 } 1036 { 1037 llvm::Triple Triple("armebv6eb-none-eabi"); 1038 EXPECT_EQ("", ARM::getARMCPUForArch(Triple)); 1039 } 1040 // xscaleeb is permitted, but armebxscale is not 1041 { 1042 llvm::Triple Triple("xscaleeb-none-eabi"); 1043 EXPECT_EQ("xscale", ARM::getARMCPUForArch(Triple)); 1044 } 1045 { 1046 llvm::Triple Triple("armebxscale-none-eabi"); 1047 EXPECT_EQ("", ARM::getARMCPUForArch(Triple)); 1048 } 1049 } 1050 1051 TEST(TargetParserTest, ARMPrintSupportedExtensions) { 1052 std::string expected = "All available -march extensions for ARM\n\n" 1053 " Name Description\n" 1054 " crc This is a long dummy description\n" 1055 " crypto\n" 1056 " sha2\n"; 1057 1058 StringMap<StringRef> DummyMap; 1059 DummyMap["crc"] = "This is a long dummy description"; 1060 1061 outs().flush(); 1062 testing::internal::CaptureStdout(); 1063 ARM::PrintSupportedExtensions(DummyMap); 1064 outs().flush(); 1065 std::string captured = testing::internal::GetCapturedStdout(); 1066 1067 // Check that the start of the output is as expected. 1068 EXPECT_EQ(0ULL, captured.find(expected)); 1069 1070 // Should not include "none" or "invalid". 1071 EXPECT_EQ(std::string::npos, captured.find("none")); 1072 EXPECT_EQ(std::string::npos, captured.find("invalid")); 1073 // Should not include anything that lacks a feature name. Checking a few here 1074 // but not all as if one is hidden correctly the rest should be. 1075 EXPECT_EQ(std::string::npos, captured.find("simd")); 1076 EXPECT_EQ(std::string::npos, captured.find("maverick")); 1077 EXPECT_EQ(std::string::npos, captured.find("xscale")); 1078 } 1079 1080 class AArch64CPUTestFixture 1081 : public ::testing::TestWithParam< 1082 ARMCPUTestParams<AArch64::ExtensionBitset>> {}; 1083 1084 TEST_P(AArch64CPUTestFixture, testAArch64CPU) { 1085 auto params = GetParam(); 1086 1087 const std::optional<AArch64::CpuInfo> Cpu = AArch64::parseCpu(params.CPUName); 1088 EXPECT_TRUE(Cpu); 1089 EXPECT_EQ(params.ExpectedArch, Cpu->Arch.Name); 1090 1091 EXPECT_PRED_FORMAT2( 1092 AssertSameExtensionFlags<ARM::ISAKind::AARCH64>(params.CPUName), 1093 params.ExpectedFlags, Cpu->getImpliedExtensions()); 1094 } 1095 1096 INSTANTIATE_TEST_SUITE_P( 1097 AArch64CPUTests, AArch64CPUTestFixture, 1098 ::testing::Values( 1099 ARMCPUTestParams<AArch64::ExtensionBitset>( 1100 "cortex-a34", "armv8-a", "crypto-neon-fp-armv8", 1101 (AArch64::ExtensionBitset( 1102 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1103 AArch64::AEK_FP, AArch64::AEK_SIMD})), 1104 "8-A"), 1105 ARMCPUTestParams<AArch64::ExtensionBitset>( 1106 "cortex-a35", "armv8-a", "crypto-neon-fp-armv8", 1107 (AArch64::ExtensionBitset( 1108 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1109 AArch64::AEK_FP, AArch64::AEK_SIMD})), 1110 "8-A"), 1111 ARMCPUTestParams<AArch64::ExtensionBitset>( 1112 "cortex-a53", "armv8-a", "crypto-neon-fp-armv8", 1113 (AArch64::ExtensionBitset( 1114 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1115 AArch64::AEK_FP, AArch64::AEK_SIMD})), 1116 "8-A"), 1117 ARMCPUTestParams<AArch64::ExtensionBitset>( 1118 "cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8", 1119 (AArch64::ExtensionBitset( 1120 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1121 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_RAS, 1122 AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_FP16, 1123 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC})), 1124 "8.2-A"), 1125 ARMCPUTestParams<AArch64::ExtensionBitset>( 1126 "cortex-a510", "armv9-a", "neon-fp-armv8", 1127 (AArch64::ExtensionBitset( 1128 {AArch64::AEK_CRC, AArch64::AEK_FP, AArch64::AEK_SIMD, 1129 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_RDM, 1130 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_BF16, 1131 AArch64::AEK_I8MM, AArch64::AEK_SVE, AArch64::AEK_SVE2, 1132 AArch64::AEK_SVE2BITPERM, AArch64::AEK_PAUTH, AArch64::AEK_MTE, 1133 AArch64::AEK_SSBS, AArch64::AEK_FP16, AArch64::AEK_FP16FML, 1134 AArch64::AEK_SB, AArch64::AEK_JSCVT, AArch64::AEK_FCMA})), 1135 "9-A"), 1136 ARMCPUTestParams<AArch64::ExtensionBitset>( 1137 "cortex-a520", "armv9.2-a", "crypto-neon-fp-armv8", 1138 (AArch64::ExtensionBitset( 1139 {AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_SVE, 1140 AArch64::AEK_SVE2, AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 1141 AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_SIMD, 1142 AArch64::AEK_RCPC, AArch64::AEK_RAS, AArch64::AEK_CRC, 1143 AArch64::AEK_FP, AArch64::AEK_SB, AArch64::AEK_SSBS, 1144 AArch64::AEK_MTE, AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, 1145 AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM, 1146 AArch64::AEK_PERFMON, AArch64::AEK_PREDRES, AArch64::AEK_JSCVT, 1147 AArch64::AEK_FCMA})), 1148 "9.2-A"), 1149 ARMCPUTestParams<AArch64::ExtensionBitset>( 1150 "cortex-a57", "armv8-a", "crypto-neon-fp-armv8", 1151 (AArch64::ExtensionBitset( 1152 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1153 AArch64::AEK_FP, AArch64::AEK_SIMD})), 1154 "8-A"), 1155 ARMCPUTestParams<AArch64::ExtensionBitset>( 1156 "cortex-a65", "armv8.2-a", "crypto-neon-fp-armv8", 1157 (AArch64::ExtensionBitset( 1158 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1159 AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16, 1160 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RCPC, 1161 AArch64::AEK_RDM, AArch64::AEK_SIMD, AArch64::AEK_SSBS})), 1162 "8.2-A"), 1163 ARMCPUTestParams<AArch64::ExtensionBitset>( 1164 "cortex-a65ae", "armv8.2-a", "crypto-neon-fp-armv8", 1165 (AArch64::ExtensionBitset( 1166 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1167 AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16, 1168 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RCPC, 1169 AArch64::AEK_RDM, AArch64::AEK_SIMD, AArch64::AEK_SSBS})), 1170 "8.2-A"), 1171 ARMCPUTestParams<AArch64::ExtensionBitset>( 1172 "cortex-a72", "armv8-a", "crypto-neon-fp-armv8", 1173 (AArch64::ExtensionBitset( 1174 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1175 AArch64::AEK_FP, AArch64::AEK_SIMD})), 1176 "8-A"), 1177 ARMCPUTestParams<AArch64::ExtensionBitset>( 1178 "cortex-a73", "armv8-a", "crypto-neon-fp-armv8", 1179 (AArch64::ExtensionBitset( 1180 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1181 AArch64::AEK_FP, AArch64::AEK_SIMD})), 1182 "8-A"), 1183 ARMCPUTestParams<AArch64::ExtensionBitset>( 1184 "cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8", 1185 (AArch64::ExtensionBitset( 1186 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1187 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_RAS, 1188 AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_FP16, 1189 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC})), 1190 "8.2-A"), 1191 ARMCPUTestParams<AArch64::ExtensionBitset>( 1192 "cortex-a76", "armv8.2-a", "crypto-neon-fp-armv8", 1193 (AArch64::ExtensionBitset( 1194 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1195 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD, 1196 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16, 1197 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS})), 1198 "8.2-A"), 1199 ARMCPUTestParams<AArch64::ExtensionBitset>( 1200 "cortex-a76ae", "armv8.2-a", "crypto-neon-fp-armv8", 1201 (AArch64::ExtensionBitset( 1202 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1203 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD, 1204 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16, 1205 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS})), 1206 "8.2-A"), 1207 ARMCPUTestParams<AArch64::ExtensionBitset>( 1208 "cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8", 1209 (AArch64::ExtensionBitset( 1210 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1211 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD, 1212 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16, 1213 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS})), 1214 "8.2-A"), 1215 ARMCPUTestParams<AArch64::ExtensionBitset>( 1216 "cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8", 1217 (AArch64::ExtensionBitset( 1218 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1219 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD, 1220 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16, 1221 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS, 1222 AArch64::AEK_PROFILE})), 1223 "8.2-A"), 1224 ARMCPUTestParams<AArch64::ExtensionBitset>( 1225 "cortex-a78c", "armv8.2-a", "crypto-neon-fp-armv8", 1226 (AArch64::ExtensionBitset( 1227 {AArch64::AEK_RAS, AArch64::AEK_CRC, AArch64::AEK_AES, 1228 AArch64::AEK_SHA2, AArch64::AEK_FP, AArch64::AEK_SIMD, 1229 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_RDM, 1230 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, 1231 AArch64::AEK_SSBS, AArch64::AEK_PROFILE, AArch64::AEK_FLAGM, 1232 AArch64::AEK_PAUTH})), 1233 "8.2-A"), 1234 ARMCPUTestParams<AArch64::ExtensionBitset>( 1235 "cortex-a710", "armv9-a", "neon-fp-armv8", 1236 (AArch64::ExtensionBitset( 1237 {AArch64::AEK_CRC, AArch64::AEK_FP, AArch64::AEK_SIMD, 1238 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_RDM, 1239 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_MTE, 1240 AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_SVE, 1241 AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM, 1242 AArch64::AEK_PAUTH, AArch64::AEK_FLAGM, AArch64::AEK_SB, 1243 AArch64::AEK_I8MM, AArch64::AEK_BF16, AArch64::AEK_JSCVT, 1244 AArch64::AEK_FCMA})), 1245 "9-A"), 1246 ARMCPUTestParams<AArch64::ExtensionBitset>( 1247 "cortex-a715", "armv9-a", "neon-fp-armv8", 1248 (AArch64::ExtensionBitset( 1249 {AArch64::AEK_CRC, AArch64::AEK_FP, 1250 AArch64::AEK_BF16, AArch64::AEK_SIMD, 1251 AArch64::AEK_RAS, AArch64::AEK_LSE, 1252 AArch64::AEK_RDM, AArch64::AEK_RCPC, 1253 AArch64::AEK_DOTPROD, AArch64::AEK_MTE, 1254 AArch64::AEK_PAUTH, AArch64::AEK_SVE, 1255 AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM, 1256 AArch64::AEK_SSBS, AArch64::AEK_SB, 1257 AArch64::AEK_I8MM, AArch64::AEK_PERFMON, 1258 AArch64::AEK_PREDRES, AArch64::AEK_PROFILE, 1259 AArch64::AEK_FP16FML, AArch64::AEK_FP16, 1260 AArch64::AEK_FLAGM, AArch64::AEK_JSCVT, 1261 AArch64::AEK_FCMA})), 1262 "9-A"), 1263 ARMCPUTestParams<AArch64::ExtensionBitset>( 1264 "cortex-a720", "armv9.2-a", "crypto-neon-fp-armv8", 1265 (AArch64::ExtensionBitset( 1266 {AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_SVE, 1267 AArch64::AEK_SVE2, AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 1268 AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_SIMD, 1269 AArch64::AEK_RCPC, AArch64::AEK_RAS, AArch64::AEK_CRC, 1270 AArch64::AEK_FP, AArch64::AEK_SB, AArch64::AEK_SSBS, 1271 AArch64::AEK_MTE, AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, 1272 AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM, 1273 AArch64::AEK_PERFMON, AArch64::AEK_PREDRES, 1274 AArch64::AEK_PROFILE, AArch64::AEK_JSCVT, AArch64::AEK_FCMA})), 1275 "9.2-A"), 1276 ARMCPUTestParams<AArch64::ExtensionBitset>( 1277 "neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8", 1278 (AArch64::ExtensionBitset( 1279 {AArch64::AEK_RAS, AArch64::AEK_SVE, AArch64::AEK_SSBS, 1280 AArch64::AEK_RCPC, AArch64::AEK_CRC, AArch64::AEK_FP, 1281 AArch64::AEK_SIMD, AArch64::AEK_RAS, AArch64::AEK_LSE, 1282 AArch64::AEK_RDM, AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, 1283 AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, 1284 AArch64::AEK_SM4, AArch64::AEK_FP16, AArch64::AEK_BF16, 1285 AArch64::AEK_PROFILE, AArch64::AEK_RAND, AArch64::AEK_FP16FML, 1286 AArch64::AEK_I8MM, AArch64::AEK_JSCVT, AArch64::AEK_FCMA, 1287 AArch64::AEK_PAUTH})), 1288 "8.4-A"), 1289 ARMCPUTestParams<AArch64::ExtensionBitset>( 1290 "neoverse-v2", "armv9-a", "neon-fp-armv8", 1291 (AArch64::ExtensionBitset( 1292 {AArch64::AEK_RAS, AArch64::AEK_SVE, 1293 AArch64::AEK_SSBS, AArch64::AEK_RCPC, 1294 AArch64::AEK_CRC, AArch64::AEK_FP, 1295 AArch64::AEK_SIMD, AArch64::AEK_MTE, 1296 AArch64::AEK_LSE, AArch64::AEK_RDM, 1297 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, 1298 AArch64::AEK_FP16, AArch64::AEK_BF16, 1299 AArch64::AEK_SVE2, AArch64::AEK_PROFILE, 1300 AArch64::AEK_FP16FML, AArch64::AEK_I8MM, 1301 AArch64::AEK_SVE2BITPERM, AArch64::AEK_RAND, 1302 AArch64::AEK_JSCVT, AArch64::AEK_FCMA, 1303 AArch64::AEK_PAUTH})), 1304 "9-A"), 1305 ARMCPUTestParams<AArch64::ExtensionBitset>( 1306 "cortex-r82", "armv8-r", "crypto-neon-fp-armv8", 1307 (AArch64::ExtensionBitset( 1308 {AArch64::AEK_CRC, AArch64::AEK_RDM, AArch64::AEK_SSBS, 1309 AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_SIMD, 1310 AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_RAS, 1311 AArch64::AEK_RCPC, AArch64::AEK_LSE, AArch64::AEK_SB, 1312 AArch64::AEK_JSCVT, AArch64::AEK_FCMA, AArch64::AEK_PAUTH})), 1313 "8-R"), 1314 ARMCPUTestParams<AArch64::ExtensionBitset>( 1315 "cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8", 1316 (AArch64::ExtensionBitset( 1317 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1318 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD, 1319 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16, 1320 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS, 1321 AArch64::AEK_PROFILE})), 1322 "8.2-A"), 1323 ARMCPUTestParams<AArch64::ExtensionBitset>( 1324 "cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8", 1325 (AArch64::ExtensionBitset( 1326 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1327 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD, 1328 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_FP16, 1329 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS, 1330 AArch64::AEK_PAUTH, AArch64::AEK_PROFILE, AArch64::AEK_FLAGM})), 1331 "8.2-A"), 1332 ARMCPUTestParams<AArch64::ExtensionBitset>( 1333 "cortex-x2", "armv9-a", "neon-fp-armv8", 1334 (AArch64::ExtensionBitset( 1335 {AArch64::AEK_CRC, AArch64::AEK_FP, AArch64::AEK_SIMD, 1336 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_RDM, 1337 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_MTE, 1338 AArch64::AEK_PAUTH, AArch64::AEK_I8MM, AArch64::AEK_BF16, 1339 AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM, 1340 AArch64::AEK_SSBS, AArch64::AEK_SB, AArch64::AEK_FP16, 1341 AArch64::AEK_FP16FML, AArch64::AEK_FLAGM, AArch64::AEK_JSCVT, 1342 AArch64::AEK_FCMA})), 1343 "9-A"), 1344 ARMCPUTestParams<AArch64::ExtensionBitset>( 1345 "cortex-x3", "armv9-a", "neon-fp-armv8", 1346 (AArch64::ExtensionBitset( 1347 {AArch64::AEK_CRC, AArch64::AEK_FP, 1348 AArch64::AEK_BF16, AArch64::AEK_SIMD, 1349 AArch64::AEK_RAS, AArch64::AEK_LSE, 1350 AArch64::AEK_RDM, AArch64::AEK_RCPC, 1351 AArch64::AEK_DOTPROD, AArch64::AEK_MTE, 1352 AArch64::AEK_PAUTH, AArch64::AEK_SVE, 1353 AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM, 1354 AArch64::AEK_SB, AArch64::AEK_PROFILE, 1355 AArch64::AEK_PERFMON, AArch64::AEK_I8MM, 1356 AArch64::AEK_FP16, AArch64::AEK_FP16FML, 1357 AArch64::AEK_PREDRES, AArch64::AEK_FLAGM, 1358 AArch64::AEK_SSBS, AArch64::AEK_JSCVT, 1359 AArch64::AEK_FCMA})), 1360 "9-A"), 1361 ARMCPUTestParams<AArch64::ExtensionBitset>( 1362 "cortex-x4", "armv9.2-a", "crypto-neon-fp-armv8", 1363 (AArch64::ExtensionBitset( 1364 {AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_SVE, 1365 AArch64::AEK_SVE2, AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 1366 AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_SIMD, 1367 AArch64::AEK_RCPC, AArch64::AEK_RAS, AArch64::AEK_CRC, 1368 AArch64::AEK_FP, AArch64::AEK_SB, AArch64::AEK_SSBS, 1369 AArch64::AEK_MTE, AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, 1370 AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM, 1371 AArch64::AEK_PERFMON, AArch64::AEK_PREDRES, 1372 AArch64::AEK_PROFILE, AArch64::AEK_JSCVT, AArch64::AEK_FCMA})), 1373 "9.2-A"), 1374 ARMCPUTestParams<AArch64::ExtensionBitset>( 1375 "cyclone", "armv8-a", "crypto-neon-fp-armv8", 1376 (AArch64::ExtensionBitset( 1377 {AArch64::AEK_NONE, AArch64::AEK_AES, AArch64::AEK_SHA2, 1378 AArch64::AEK_FP, AArch64::AEK_SIMD})), 1379 "8-A"), 1380 ARMCPUTestParams<AArch64::ExtensionBitset>( 1381 "apple-a7", "armv8-a", "crypto-neon-fp-armv8", 1382 (AArch64::ExtensionBitset( 1383 {AArch64::AEK_NONE, AArch64::AEK_AES, AArch64::AEK_SHA2, 1384 AArch64::AEK_FP, AArch64::AEK_SIMD})), 1385 "8-A"), 1386 ARMCPUTestParams<AArch64::ExtensionBitset>( 1387 "apple-a8", "armv8-a", "crypto-neon-fp-armv8", 1388 (AArch64::ExtensionBitset( 1389 {AArch64::AEK_NONE, AArch64::AEK_AES, AArch64::AEK_SHA2, 1390 AArch64::AEK_FP, AArch64::AEK_SIMD})), 1391 "8-A"), 1392 ARMCPUTestParams<AArch64::ExtensionBitset>( 1393 "apple-a9", "armv8-a", "crypto-neon-fp-armv8", 1394 (AArch64::ExtensionBitset( 1395 {AArch64::AEK_NONE, AArch64::AEK_AES, AArch64::AEK_SHA2, 1396 AArch64::AEK_FP, AArch64::AEK_SIMD})), 1397 "8-A"), 1398 ARMCPUTestParams<AArch64::ExtensionBitset>( 1399 "apple-a10", "armv8-a", "crypto-neon-fp-armv8", 1400 (AArch64::ExtensionBitset( 1401 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1402 AArch64::AEK_FP, AArch64::AEK_RDM, AArch64::AEK_SIMD})), 1403 "8-A"), 1404 ARMCPUTestParams<AArch64::ExtensionBitset>( 1405 "apple-a11", "armv8.2-a", "crypto-neon-fp-armv8", 1406 (AArch64::ExtensionBitset( 1407 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1408 AArch64::AEK_FP, AArch64::AEK_LSE, AArch64::AEK_RAS, 1409 AArch64::AEK_RDM, AArch64::AEK_SIMD, AArch64::AEK_FP16})), 1410 "8.2-A"), 1411 ARMCPUTestParams<AArch64::ExtensionBitset>( 1412 "apple-a12", "armv8.3-a", "crypto-neon-fp-armv8", 1413 (AArch64::ExtensionBitset( 1414 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1415 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_LSE, 1416 AArch64::AEK_RAS, AArch64::AEK_RDM, AArch64::AEK_RCPC, 1417 AArch64::AEK_FP16, AArch64::AEK_JSCVT, AArch64::AEK_FCMA, 1418 AArch64::AEK_PAUTH})), 1419 "8.3-A"), 1420 ARMCPUTestParams<AArch64::ExtensionBitset>( 1421 "apple-a13", "armv8.4-a", "crypto-neon-fp-armv8", 1422 (AArch64::ExtensionBitset( 1423 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1424 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD, 1425 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM, 1426 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 1427 AArch64::AEK_FP16FML, AArch64::AEK_SHA3, AArch64::AEK_JSCVT, 1428 AArch64::AEK_FCMA, AArch64::AEK_PAUTH})), 1429 "8.4-A"), 1430 ARMCPUTestParams<AArch64::ExtensionBitset>( 1431 "apple-a14", "armv8.5-a", "crypto-neon-fp-armv8", 1432 (AArch64::ExtensionBitset( 1433 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1434 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD, 1435 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM, 1436 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 1437 AArch64::AEK_FP16FML, AArch64::AEK_SHA3, AArch64::AEK_JSCVT, 1438 AArch64::AEK_FCMA, AArch64::AEK_PAUTH})), 1439 "8.5-A"), 1440 ARMCPUTestParams<AArch64::ExtensionBitset>( 1441 "apple-a15", "armv8.6-a", "crypto-neon-fp-armv8", 1442 (AArch64::ExtensionBitset( 1443 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1444 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD, 1445 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM, 1446 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 1447 AArch64::AEK_FP16FML, AArch64::AEK_SHA3, AArch64::AEK_BF16, 1448 AArch64::AEK_I8MM, AArch64::AEK_JSCVT, AArch64::AEK_FCMA, 1449 AArch64::AEK_PAUTH})), 1450 "8.6-A"), 1451 ARMCPUTestParams<AArch64::ExtensionBitset>( 1452 "apple-a16", "armv8.6-a", "crypto-neon-fp-armv8", 1453 (AArch64::ExtensionBitset( 1454 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1455 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD, 1456 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM, 1457 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 1458 AArch64::AEK_FP16FML, AArch64::AEK_SHA3, AArch64::AEK_BF16, 1459 AArch64::AEK_I8MM, AArch64::AEK_JSCVT, AArch64::AEK_FCMA, 1460 AArch64::AEK_PAUTH})), 1461 "8.6-A"), 1462 ARMCPUTestParams<AArch64::ExtensionBitset>( 1463 "apple-a17", "armv8.6-a", "crypto-neon-fp-armv8", 1464 (AArch64::ExtensionBitset( 1465 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1466 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD, 1467 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM, 1468 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 1469 AArch64::AEK_FP16FML, AArch64::AEK_SHA3, AArch64::AEK_BF16, 1470 AArch64::AEK_I8MM, AArch64::AEK_JSCVT, AArch64::AEK_FCMA, 1471 AArch64::AEK_PAUTH})), 1472 "8.6-A"), 1473 ARMCPUTestParams<AArch64::ExtensionBitset>( 1474 "apple-m1", "armv8.5-a", "crypto-neon-fp-armv8", 1475 (AArch64::ExtensionBitset( 1476 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1477 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD, 1478 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM, 1479 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 1480 AArch64::AEK_FP16FML, AArch64::AEK_SHA3, AArch64::AEK_JSCVT, 1481 AArch64::AEK_FCMA, AArch64::AEK_PAUTH})), 1482 "8.5-A"), 1483 ARMCPUTestParams<AArch64::ExtensionBitset>( 1484 "apple-m2", "armv8.6-a", "crypto-neon-fp-armv8", 1485 (AArch64::ExtensionBitset( 1486 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1487 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD, 1488 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM, 1489 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 1490 AArch64::AEK_FP16FML, AArch64::AEK_SHA3, AArch64::AEK_BF16, 1491 AArch64::AEK_I8MM, AArch64::AEK_JSCVT, AArch64::AEK_FCMA, 1492 AArch64::AEK_PAUTH})), 1493 "8.6-A"), 1494 ARMCPUTestParams<AArch64::ExtensionBitset>( 1495 "apple-m3", "armv8.6-a", "crypto-neon-fp-armv8", 1496 (AArch64::ExtensionBitset( 1497 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1498 AArch64::AEK_SHA3, AArch64::AEK_FP, AArch64::AEK_SIMD, 1499 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM, 1500 AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 1501 AArch64::AEK_FP16FML, AArch64::AEK_SHA3, AArch64::AEK_BF16, 1502 AArch64::AEK_I8MM, AArch64::AEK_JSCVT, AArch64::AEK_FCMA, 1503 AArch64::AEK_PAUTH})), 1504 "8.6-A"), 1505 ARMCPUTestParams<AArch64::ExtensionBitset>( 1506 "apple-s4", "armv8.3-a", "crypto-neon-fp-armv8", 1507 (AArch64::ExtensionBitset( 1508 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1509 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_LSE, 1510 AArch64::AEK_RAS, AArch64::AEK_RDM, AArch64::AEK_RCPC, 1511 AArch64::AEK_FP16, AArch64::AEK_JSCVT, AArch64::AEK_FCMA, 1512 AArch64::AEK_PAUTH})), 1513 "8.3-A"), 1514 ARMCPUTestParams<AArch64::ExtensionBitset>( 1515 "apple-s5", "armv8.3-a", "crypto-neon-fp-armv8", 1516 (AArch64::ExtensionBitset( 1517 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1518 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_LSE, 1519 AArch64::AEK_RAS, AArch64::AEK_RDM, AArch64::AEK_RCPC, 1520 AArch64::AEK_FP16, AArch64::AEK_JSCVT, AArch64::AEK_FCMA, 1521 AArch64::AEK_PAUTH})), 1522 "8.3-A"), 1523 ARMCPUTestParams<AArch64::ExtensionBitset>( 1524 "exynos-m3", "armv8-a", "crypto-neon-fp-armv8", 1525 (AArch64::ExtensionBitset( 1526 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1527 AArch64::AEK_FP, AArch64::AEK_SIMD})), 1528 "8-A"), 1529 ARMCPUTestParams<AArch64::ExtensionBitset>( 1530 "exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8", 1531 (AArch64::ExtensionBitset( 1532 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1533 AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16, 1534 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM, 1535 AArch64::AEK_SIMD})), 1536 "8.2-A"), 1537 ARMCPUTestParams<AArch64::ExtensionBitset>( 1538 "exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8", 1539 (AArch64::ExtensionBitset( 1540 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1541 AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16, 1542 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RDM, 1543 AArch64::AEK_SIMD})), 1544 "8.2-A"), 1545 ARMCPUTestParams<AArch64::ExtensionBitset>( 1546 "falkor", "armv8-a", "crypto-neon-fp-armv8", 1547 (AArch64::ExtensionBitset( 1548 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1549 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_RDM})), 1550 "8-A"), 1551 ARMCPUTestParams<AArch64::ExtensionBitset>( 1552 "kryo", "armv8-a", "crypto-neon-fp-armv8", 1553 (AArch64::ExtensionBitset( 1554 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1555 AArch64::AEK_FP, AArch64::AEK_SIMD})), 1556 "8-A"), 1557 ARMCPUTestParams<AArch64::ExtensionBitset>( 1558 "neoverse-e1", "armv8.2-a", "crypto-neon-fp-armv8", 1559 (AArch64::ExtensionBitset( 1560 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1561 AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16, 1562 AArch64::AEK_LSE, AArch64::AEK_RAS, AArch64::AEK_RCPC, 1563 AArch64::AEK_RDM, AArch64::AEK_SIMD, AArch64::AEK_SSBS})), 1564 "8.2-A"), 1565 ARMCPUTestParams<AArch64::ExtensionBitset>( 1566 "neoverse-n1", "armv8.2-a", "crypto-neon-fp-armv8", 1567 (AArch64::ExtensionBitset( 1568 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1569 AArch64::AEK_DOTPROD, AArch64::AEK_FP, AArch64::AEK_FP16, 1570 AArch64::AEK_LSE, AArch64::AEK_PROFILE, AArch64::AEK_RAS, 1571 AArch64::AEK_RCPC, AArch64::AEK_RDM, AArch64::AEK_SIMD, 1572 AArch64::AEK_SSBS})), 1573 "8.2-A"), 1574 ARMCPUTestParams<AArch64::ExtensionBitset>( 1575 "neoverse-n2", "armv9-a", "crypto-neon-fp-armv8", 1576 (AArch64::ExtensionBitset( 1577 {AArch64::AEK_CRC, AArch64::AEK_FP, 1578 AArch64::AEK_SIMD, AArch64::AEK_FP16, 1579 AArch64::AEK_RAS, AArch64::AEK_LSE, 1580 AArch64::AEK_SVE, AArch64::AEK_DOTPROD, 1581 AArch64::AEK_RCPC, AArch64::AEK_RDM, 1582 AArch64::AEK_MTE, AArch64::AEK_SSBS, 1583 AArch64::AEK_SB, AArch64::AEK_SVE2, 1584 AArch64::AEK_SVE2BITPERM, AArch64::AEK_BF16, 1585 AArch64::AEK_I8MM, AArch64::AEK_JSCVT, 1586 AArch64::AEK_FCMA, AArch64::AEK_PAUTH})), 1587 "8.5-A"), 1588 ARMCPUTestParams<AArch64::ExtensionBitset>( 1589 "ampere1", "armv8.6-a", "crypto-neon-fp-armv8", 1590 (AArch64::ExtensionBitset( 1591 {AArch64::AEK_CRC, AArch64::AEK_FP, AArch64::AEK_FP16, 1592 AArch64::AEK_SIMD, AArch64::AEK_RAS, AArch64::AEK_LSE, 1593 AArch64::AEK_RDM, AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, 1594 AArch64::AEK_SHA3, AArch64::AEK_BF16, AArch64::AEK_SHA2, 1595 AArch64::AEK_AES, AArch64::AEK_I8MM, AArch64::AEK_SSBS, 1596 AArch64::AEK_SB, AArch64::AEK_RAND, AArch64::AEK_JSCVT, 1597 AArch64::AEK_FCMA, AArch64::AEK_PAUTH})), 1598 "8.6-A"), 1599 ARMCPUTestParams<AArch64::ExtensionBitset>( 1600 "ampere1a", "armv8.6-a", "crypto-neon-fp-armv8", 1601 (AArch64::ExtensionBitset( 1602 {AArch64::AEK_CRC, AArch64::AEK_FP, AArch64::AEK_FP16, 1603 AArch64::AEK_SIMD, AArch64::AEK_RAS, AArch64::AEK_LSE, 1604 AArch64::AEK_RDM, AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, 1605 AArch64::AEK_SM4, AArch64::AEK_SHA3, AArch64::AEK_BF16, 1606 AArch64::AEK_SHA2, AArch64::AEK_AES, AArch64::AEK_I8MM, 1607 AArch64::AEK_SSBS, AArch64::AEK_SB, AArch64::AEK_RAND, 1608 AArch64::AEK_MTE, AArch64::AEK_JSCVT, AArch64::AEK_FCMA, 1609 AArch64::AEK_PAUTH})), 1610 "8.6-A"), 1611 ARMCPUTestParams<AArch64::ExtensionBitset>( 1612 "ampere1b", "armv8.7-a", "crypto-neon-fp-armv8", 1613 (AArch64::ExtensionBitset( 1614 {AArch64::AEK_CRC, AArch64::AEK_FP, AArch64::AEK_FP16, 1615 AArch64::AEK_SIMD, AArch64::AEK_RAS, AArch64::AEK_LSE, 1616 AArch64::AEK_RDM, AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, 1617 AArch64::AEK_SM4, AArch64::AEK_SHA3, AArch64::AEK_BF16, 1618 AArch64::AEK_SHA2, AArch64::AEK_AES, AArch64::AEK_I8MM, 1619 AArch64::AEK_SSBS, AArch64::AEK_SB, AArch64::AEK_RAND, 1620 AArch64::AEK_MTE, AArch64::AEK_JSCVT, AArch64::AEK_FCMA, 1621 AArch64::AEK_PAUTH, AArch64::AEK_CSSC})), 1622 "8.7-A"), 1623 ARMCPUTestParams<AArch64::ExtensionBitset>( 1624 "neoverse-512tvb", "armv8.4-a", "crypto-neon-fp-armv8", 1625 (AArch64::ExtensionBitset( 1626 {AArch64::AEK_RAS, AArch64::AEK_SVE, AArch64::AEK_SSBS, 1627 AArch64::AEK_RCPC, AArch64::AEK_CRC, AArch64::AEK_FP, 1628 AArch64::AEK_SIMD, AArch64::AEK_RAS, AArch64::AEK_LSE, 1629 AArch64::AEK_RDM, AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, 1630 AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, 1631 AArch64::AEK_SM4, AArch64::AEK_FP16, AArch64::AEK_BF16, 1632 AArch64::AEK_PROFILE, AArch64::AEK_RAND, AArch64::AEK_FP16FML, 1633 AArch64::AEK_I8MM, AArch64::AEK_JSCVT, AArch64::AEK_FCMA, 1634 AArch64::AEK_PAUTH})), 1635 "8.4-A"), 1636 ARMCPUTestParams<AArch64::ExtensionBitset>( 1637 "thunderx2t99", "armv8.1-a", "crypto-neon-fp-armv8", 1638 (AArch64::ExtensionBitset( 1639 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1640 AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_FP, 1641 AArch64::AEK_SIMD})), 1642 "8.1-A"), 1643 ARMCPUTestParams<AArch64::ExtensionBitset>( 1644 "thunderx3t110", "armv8.3-a", "crypto-neon-fp-armv8", 1645 (AArch64::ExtensionBitset( 1646 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1647 AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_FP, 1648 AArch64::AEK_SIMD, AArch64::AEK_RAS, AArch64::AEK_RCPC, 1649 AArch64::AEK_JSCVT, AArch64::AEK_FCMA, AArch64::AEK_PAUTH})), 1650 "8.3-A"), 1651 ARMCPUTestParams<AArch64::ExtensionBitset>( 1652 "thunderx", "armv8-a", "crypto-neon-fp-armv8", 1653 (AArch64::ExtensionBitset( 1654 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1655 AArch64::AEK_SIMD, AArch64::AEK_FP})), 1656 "8-A"), 1657 ARMCPUTestParams<AArch64::ExtensionBitset>( 1658 "thunderxt81", "armv8-a", "crypto-neon-fp-armv8", 1659 (AArch64::ExtensionBitset( 1660 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1661 AArch64::AEK_SIMD, AArch64::AEK_FP})), 1662 "8-A"), 1663 ARMCPUTestParams<AArch64::ExtensionBitset>( 1664 "thunderxt83", "armv8-a", "crypto-neon-fp-armv8", 1665 (AArch64::ExtensionBitset( 1666 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1667 AArch64::AEK_SIMD, AArch64::AEK_FP})), 1668 "8-A"), 1669 ARMCPUTestParams<AArch64::ExtensionBitset>( 1670 "thunderxt88", "armv8-a", "crypto-neon-fp-armv8", 1671 (AArch64::ExtensionBitset( 1672 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1673 AArch64::AEK_SIMD, AArch64::AEK_FP})), 1674 "8-A"), 1675 ARMCPUTestParams<AArch64::ExtensionBitset>( 1676 "tsv110", "armv8.2-a", "crypto-neon-fp-armv8", 1677 (AArch64::ExtensionBitset( 1678 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1679 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_RAS, 1680 AArch64::AEK_LSE, AArch64::AEK_RDM, AArch64::AEK_PROFILE, 1681 AArch64::AEK_JSCVT, AArch64::AEK_FCMA, AArch64::AEK_FP16, 1682 AArch64::AEK_FP16FML, AArch64::AEK_DOTPROD})), 1683 "8.2-A"), 1684 ARMCPUTestParams<AArch64::ExtensionBitset>( 1685 "a64fx", "armv8.2-a", "crypto-neon-fp-armv8", 1686 (AArch64::ExtensionBitset( 1687 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1688 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_FP16, 1689 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_SVE, 1690 AArch64::AEK_RDM})), 1691 "8.2-A"), 1692 ARMCPUTestParams<AArch64::ExtensionBitset>( 1693 "carmel", "armv8.2-a", "crypto-neon-fp-armv8", 1694 (AArch64::ExtensionBitset( 1695 {AArch64::AEK_CRC, AArch64::AEK_AES, AArch64::AEK_SHA2, 1696 AArch64::AEK_FP, AArch64::AEK_SIMD, AArch64::AEK_FP16, 1697 AArch64::AEK_RAS, AArch64::AEK_LSE, AArch64::AEK_RDM})), 1698 "8.2-A")), 1699 ARMCPUTestParams<AArch64::ExtensionBitset>::PrintToStringParamName); 1700 1701 // Note: number of CPUs includes aliases. 1702 static constexpr unsigned NumAArch64CPUArchs = 69; 1703 1704 TEST(TargetParserTest, testAArch64CPUArchList) { 1705 SmallVector<StringRef, NumAArch64CPUArchs> List; 1706 AArch64::fillValidCPUArchList(List); 1707 1708 // No list exists for these in this test suite, so ensure all are 1709 // valid, and match the expected 'magic' count. 1710 EXPECT_EQ(List.size(), NumAArch64CPUArchs); 1711 for (StringRef CPU : List) { 1712 EXPECT_TRUE(AArch64::parseCpu(CPU)); 1713 } 1714 } 1715 1716 bool testAArch64Arch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch, 1717 unsigned ArchAttr) { 1718 const AArch64::ArchInfo *AI = AArch64::parseArch(Arch); 1719 return AI != nullptr; 1720 } 1721 1722 TEST(TargetParserTest, testAArch64Arch) { 1723 EXPECT_TRUE(testAArch64Arch("armv8-a", "cortex-a53", "v8a", 1724 ARMBuildAttrs::CPUArch::v8_A)); 1725 EXPECT_TRUE(testAArch64Arch("armv8.1-a", "generic", "v8.1a", 1726 ARMBuildAttrs::CPUArch::v8_A)); 1727 EXPECT_TRUE(testAArch64Arch("armv8.2-a", "generic", "v8.2a", 1728 ARMBuildAttrs::CPUArch::v8_A)); 1729 EXPECT_TRUE(testAArch64Arch("armv8.3-a", "generic", "v8.3a", 1730 ARMBuildAttrs::CPUArch::v8_A)); 1731 EXPECT_TRUE(testAArch64Arch("armv8.4-a", "generic", "v8.4a", 1732 ARMBuildAttrs::CPUArch::v8_A)); 1733 EXPECT_TRUE(testAArch64Arch("armv8.5-a", "generic", "v8.5a", 1734 ARMBuildAttrs::CPUArch::v8_A)); 1735 EXPECT_TRUE(testAArch64Arch("armv8.6-a", "generic", "v8.6a", 1736 ARMBuildAttrs::CPUArch::v8_A)); 1737 EXPECT_TRUE(testAArch64Arch("armv8.7-a", "generic", "v8.7a", 1738 ARMBuildAttrs::CPUArch::v8_A)); 1739 EXPECT_TRUE(testAArch64Arch("armv8.8-a", "generic", "v8.8a", 1740 ARMBuildAttrs::CPUArch::v8_A)); 1741 EXPECT_TRUE(testAArch64Arch("armv8.9-a", "generic", "v8.9a", 1742 ARMBuildAttrs::CPUArch::v8_A)); 1743 EXPECT_TRUE(testAArch64Arch("armv9-a", "generic", "v9a", 1744 ARMBuildAttrs::CPUArch::v8_A)); 1745 EXPECT_TRUE(testAArch64Arch("armv9.1-a", "generic", "v9.1a", 1746 ARMBuildAttrs::CPUArch::v8_A)); 1747 EXPECT_TRUE(testAArch64Arch("armv9.2-a", "generic", "v9.2a", 1748 ARMBuildAttrs::CPUArch::v8_A)); 1749 EXPECT_TRUE(testAArch64Arch("armv9.3-a", "generic", "v9.3a", 1750 ARMBuildAttrs::CPUArch::v8_A)); 1751 EXPECT_TRUE(testAArch64Arch("armv9.4-a", "generic", "v9.4a", 1752 ARMBuildAttrs::CPUArch::v8_A)); 1753 EXPECT_TRUE(testAArch64Arch("armv9.5-a", "generic", "v9.5a", 1754 ARMBuildAttrs::CPUArch::v8_A)); 1755 } 1756 1757 bool testAArch64Extension(StringRef CPUName, StringRef ArchExt) { 1758 std::optional<AArch64::ExtensionInfo> Extension = 1759 AArch64::parseArchExtension(ArchExt); 1760 if (!Extension) 1761 return false; 1762 std::optional<AArch64::CpuInfo> CpuInfo = AArch64::parseCpu(CPUName); 1763 return CpuInfo->getImpliedExtensions().test(Extension->ID); 1764 } 1765 1766 bool testAArch64Extension(const AArch64::ArchInfo &AI, StringRef ArchExt) { 1767 std::optional<AArch64::ExtensionInfo> Extension = 1768 AArch64::parseArchExtension(ArchExt); 1769 if (!Extension) 1770 return false; 1771 return AI.DefaultExts.test(Extension->ID); 1772 } 1773 1774 TEST(TargetParserTest, testAArch64Extension) { 1775 EXPECT_FALSE(testAArch64Extension("cortex-a34", "ras")); 1776 EXPECT_FALSE(testAArch64Extension("cortex-a35", "ras")); 1777 EXPECT_FALSE(testAArch64Extension("cortex-a53", "ras")); 1778 EXPECT_TRUE(testAArch64Extension("cortex-a55", "ras")); 1779 EXPECT_TRUE(testAArch64Extension("cortex-a55", "fp16")); 1780 EXPECT_FALSE(testAArch64Extension("cortex-a55", "fp16fml")); 1781 EXPECT_TRUE(testAArch64Extension("cortex-a55", "dotprod")); 1782 EXPECT_FALSE(testAArch64Extension("cortex-a57", "ras")); 1783 EXPECT_FALSE(testAArch64Extension("cortex-a72", "ras")); 1784 EXPECT_FALSE(testAArch64Extension("cortex-a73", "ras")); 1785 EXPECT_TRUE(testAArch64Extension("cortex-a75", "ras")); 1786 EXPECT_TRUE(testAArch64Extension("cortex-a75", "fp16")); 1787 EXPECT_FALSE(testAArch64Extension("cortex-a75", "fp16fml")); 1788 EXPECT_TRUE(testAArch64Extension("cortex-a75", "dotprod")); 1789 EXPECT_TRUE(testAArch64Extension("cortex-r82", "ras")); 1790 EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16")); 1791 EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16fml")); 1792 EXPECT_TRUE(testAArch64Extension("cortex-r82", "dotprod")); 1793 EXPECT_TRUE(testAArch64Extension("cortex-r82", "lse")); 1794 EXPECT_FALSE(testAArch64Extension("cyclone", "ras")); 1795 EXPECT_FALSE(testAArch64Extension("exynos-m3", "ras")); 1796 EXPECT_TRUE(testAArch64Extension("exynos-m4", "dotprod")); 1797 EXPECT_TRUE(testAArch64Extension("exynos-m4", "fp16")); 1798 EXPECT_TRUE(testAArch64Extension("exynos-m4", "lse")); 1799 EXPECT_TRUE(testAArch64Extension("exynos-m4", "ras")); 1800 EXPECT_TRUE(testAArch64Extension("exynos-m4", "rdm")); 1801 EXPECT_TRUE(testAArch64Extension("exynos-m5", "dotprod")); 1802 EXPECT_TRUE(testAArch64Extension("exynos-m5", "fp16")); 1803 EXPECT_TRUE(testAArch64Extension("exynos-m5", "lse")); 1804 EXPECT_TRUE(testAArch64Extension("exynos-m5", "ras")); 1805 EXPECT_TRUE(testAArch64Extension("exynos-m5", "rdm")); 1806 EXPECT_TRUE(testAArch64Extension("falkor", "rdm")); 1807 EXPECT_FALSE(testAArch64Extension("kryo", "ras")); 1808 EXPECT_TRUE(testAArch64Extension("saphira", "crc")); 1809 EXPECT_TRUE(testAArch64Extension("saphira", "lse")); 1810 EXPECT_TRUE(testAArch64Extension("saphira", "rdm")); 1811 EXPECT_TRUE(testAArch64Extension("saphira", "ras")); 1812 EXPECT_TRUE(testAArch64Extension("saphira", "rcpc")); 1813 EXPECT_TRUE(testAArch64Extension("saphira", "profile")); 1814 EXPECT_FALSE(testAArch64Extension("saphira", "fp16")); 1815 EXPECT_FALSE(testAArch64Extension("thunderx2t99", "ras")); 1816 EXPECT_FALSE(testAArch64Extension("thunderx", "lse")); 1817 EXPECT_FALSE(testAArch64Extension("thunderxt81", "lse")); 1818 EXPECT_FALSE(testAArch64Extension("thunderxt83", "lse")); 1819 EXPECT_FALSE(testAArch64Extension("thunderxt88", "lse")); 1820 EXPECT_TRUE(testAArch64Extension("tsv110", "aes")); 1821 EXPECT_TRUE(testAArch64Extension("tsv110", "sha2")); 1822 EXPECT_FALSE(testAArch64Extension("tsv110", "sha3")); 1823 EXPECT_FALSE(testAArch64Extension("tsv110", "sm4")); 1824 EXPECT_TRUE(testAArch64Extension("tsv110", "ras")); 1825 EXPECT_TRUE(testAArch64Extension("tsv110", "profile")); 1826 EXPECT_TRUE(testAArch64Extension("tsv110", "fp16")); 1827 EXPECT_TRUE(testAArch64Extension("tsv110", "fp16fml")); 1828 EXPECT_TRUE(testAArch64Extension("tsv110", "dotprod")); 1829 EXPECT_TRUE(testAArch64Extension("tsv110", "jscvt")); 1830 EXPECT_TRUE(testAArch64Extension("tsv110", "fcma")); 1831 EXPECT_TRUE(testAArch64Extension("a64fx", "fp16")); 1832 EXPECT_TRUE(testAArch64Extension("a64fx", "sve")); 1833 EXPECT_FALSE(testAArch64Extension("a64fx", "sve2")); 1834 EXPECT_TRUE(testAArch64Extension("carmel", "aes")); 1835 EXPECT_TRUE(testAArch64Extension("carmel", "sha2")); 1836 EXPECT_TRUE(testAArch64Extension("carmel", "fp16")); 1837 1838 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8A, "ras")); 1839 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_1A, "ras")); 1840 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "profile")); 1841 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "fp16")); 1842 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "fp16fml")); 1843 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A, "fp16")); 1844 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A, "fp16fml")); 1845 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A, "fp16")); 1846 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A, "fp16fml")); 1847 } 1848 1849 TEST(TargetParserTest, AArch64ExtensionFeatures) { 1850 std::vector<uint64_t> Extensions = { 1851 AArch64::AEK_CRC, AArch64::AEK_LSE, 1852 AArch64::AEK_RDM, AArch64::AEK_CRYPTO, 1853 AArch64::AEK_SM4, AArch64::AEK_SHA3, 1854 AArch64::AEK_SHA2, AArch64::AEK_AES, 1855 AArch64::AEK_DOTPROD, AArch64::AEK_FP, 1856 AArch64::AEK_SIMD, AArch64::AEK_FP16, 1857 AArch64::AEK_FP16FML, AArch64::AEK_PROFILE, 1858 AArch64::AEK_RAS, AArch64::AEK_SVE, 1859 AArch64::AEK_SVE2, AArch64::AEK_SVE2AES, 1860 AArch64::AEK_SVE2SM4, AArch64::AEK_SVE2SHA3, 1861 AArch64::AEK_SVE2BITPERM, AArch64::AEK_RCPC, 1862 AArch64::AEK_RAND, AArch64::AEK_MTE, 1863 AArch64::AEK_SSBS, AArch64::AEK_SB, 1864 AArch64::AEK_PREDRES, AArch64::AEK_BF16, 1865 AArch64::AEK_I8MM, AArch64::AEK_F32MM, 1866 AArch64::AEK_F64MM, AArch64::AEK_TME, 1867 AArch64::AEK_LS64, AArch64::AEK_BRBE, 1868 AArch64::AEK_PAUTH, AArch64::AEK_FLAGM, 1869 AArch64::AEK_SME, AArch64::AEK_SMEF64F64, 1870 AArch64::AEK_SMEI16I64, AArch64::AEK_SME2, 1871 AArch64::AEK_HBC, AArch64::AEK_MOPS, 1872 AArch64::AEK_PERFMON, AArch64::AEK_SVE2p1, 1873 AArch64::AEK_SME2p1, AArch64::AEK_B16B16, 1874 AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC, 1875 AArch64::AEK_RCPC3, AArch64::AEK_THE, 1876 AArch64::AEK_D128, AArch64::AEK_LSE128, 1877 AArch64::AEK_SPECRES2, AArch64::AEK_RASv2, 1878 AArch64::AEK_ITE, AArch64::AEK_GCS, 1879 AArch64::AEK_FPMR, AArch64::AEK_FP8, 1880 AArch64::AEK_FAMINMAX, AArch64::AEK_FP8FMA, 1881 AArch64::AEK_SSVE_FP8FMA, AArch64::AEK_FP8DOT2, 1882 AArch64::AEK_SSVE_FP8DOT2, AArch64::AEK_FP8DOT4, 1883 AArch64::AEK_SSVE_FP8DOT4, AArch64::AEK_LUT, 1884 AArch64::AEK_SME_LUTv2, AArch64::AEK_SMEF8F16, 1885 AArch64::AEK_SMEF8F32, AArch64::AEK_SMEFA64, 1886 AArch64::AEK_CPA, AArch64::AEK_PAUTHLR, 1887 AArch64::AEK_TLBIW, AArch64::AEK_JSCVT, 1888 AArch64::AEK_FCMA, 1889 }; 1890 1891 std::vector<StringRef> Features; 1892 1893 AArch64::ExtensionBitset ExtVal; 1894 for (auto Ext : Extensions) 1895 ExtVal.set(Ext); 1896 1897 // NONE has no feature names. 1898 // We return True here because NONE is a valid choice. 1899 EXPECT_TRUE(AArch64::getExtensionFeatures( 1900 AArch64::ExtensionBitset({AArch64::AEK_NONE}), Features)); 1901 EXPECT_TRUE(!Features.size()); 1902 1903 AArch64::getExtensionFeatures(ExtVal, Features); 1904 EXPECT_EQ(Extensions.size(), Features.size()); 1905 1906 EXPECT_TRUE(llvm::is_contained(Features, "+crc")); 1907 EXPECT_TRUE(llvm::is_contained(Features, "+lse")); 1908 EXPECT_TRUE(llvm::is_contained(Features, "+rdm")); 1909 EXPECT_TRUE(llvm::is_contained(Features, "+crypto")); 1910 EXPECT_TRUE(llvm::is_contained(Features, "+sm4")); 1911 EXPECT_TRUE(llvm::is_contained(Features, "+sha3")); 1912 EXPECT_TRUE(llvm::is_contained(Features, "+sha2")); 1913 EXPECT_TRUE(llvm::is_contained(Features, "+aes")); 1914 EXPECT_TRUE(llvm::is_contained(Features, "+dotprod")); 1915 EXPECT_TRUE(llvm::is_contained(Features, "+fp-armv8")); 1916 EXPECT_TRUE(llvm::is_contained(Features, "+neon")); 1917 EXPECT_TRUE(llvm::is_contained(Features, "+fullfp16")); 1918 EXPECT_TRUE(llvm::is_contained(Features, "+fp16fml")); 1919 EXPECT_TRUE(llvm::is_contained(Features, "+spe")); 1920 EXPECT_TRUE(llvm::is_contained(Features, "+ras")); 1921 EXPECT_TRUE(llvm::is_contained(Features, "+sve")); 1922 EXPECT_TRUE(llvm::is_contained(Features, "+sve2")); 1923 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-aes")); 1924 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sm4")); 1925 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sha3")); 1926 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-bitperm")); 1927 EXPECT_TRUE(llvm::is_contained(Features, "+sve2p1")); 1928 EXPECT_TRUE(llvm::is_contained(Features, "+b16b16")); 1929 EXPECT_TRUE(llvm::is_contained(Features, "+rcpc")); 1930 EXPECT_TRUE(llvm::is_contained(Features, "+rand")); 1931 EXPECT_TRUE(llvm::is_contained(Features, "+mte")); 1932 EXPECT_TRUE(llvm::is_contained(Features, "+ssbs")); 1933 EXPECT_TRUE(llvm::is_contained(Features, "+sb")); 1934 EXPECT_TRUE(llvm::is_contained(Features, "+predres")); 1935 EXPECT_TRUE(llvm::is_contained(Features, "+bf16")); 1936 EXPECT_TRUE(llvm::is_contained(Features, "+i8mm")); 1937 EXPECT_TRUE(llvm::is_contained(Features, "+f32mm")); 1938 EXPECT_TRUE(llvm::is_contained(Features, "+f64mm")); 1939 EXPECT_TRUE(llvm::is_contained(Features, "+tme")); 1940 EXPECT_TRUE(llvm::is_contained(Features, "+ls64")); 1941 EXPECT_TRUE(llvm::is_contained(Features, "+brbe")); 1942 EXPECT_TRUE(llvm::is_contained(Features, "+pauth")); 1943 EXPECT_TRUE(llvm::is_contained(Features, "+flagm")); 1944 EXPECT_TRUE(llvm::is_contained(Features, "+sme")); 1945 EXPECT_TRUE(llvm::is_contained(Features, "+sme-f64f64")); 1946 EXPECT_TRUE(llvm::is_contained(Features, "+sme-i16i64")); 1947 EXPECT_TRUE(llvm::is_contained(Features, "+sme-f16f16")); 1948 EXPECT_TRUE(llvm::is_contained(Features, "+sme2")); 1949 EXPECT_TRUE(llvm::is_contained(Features, "+sme2p1")); 1950 EXPECT_TRUE(llvm::is_contained(Features, "+hbc")); 1951 EXPECT_TRUE(llvm::is_contained(Features, "+mops")); 1952 EXPECT_TRUE(llvm::is_contained(Features, "+perfmon")); 1953 EXPECT_TRUE(llvm::is_contained(Features, "+cssc")); 1954 EXPECT_TRUE(llvm::is_contained(Features, "+rcpc3")); 1955 EXPECT_TRUE(llvm::is_contained(Features, "+the")); 1956 EXPECT_TRUE(llvm::is_contained(Features, "+d128")); 1957 EXPECT_TRUE(llvm::is_contained(Features, "+lse128")); 1958 EXPECT_TRUE(llvm::is_contained(Features, "+specres2")); 1959 EXPECT_TRUE(llvm::is_contained(Features, "+ite")); 1960 EXPECT_TRUE(llvm::is_contained(Features, "+gcs")); 1961 EXPECT_TRUE(llvm::is_contained(Features, "+fpmr")); 1962 EXPECT_TRUE(llvm::is_contained(Features, "+fp8")); 1963 EXPECT_TRUE(llvm::is_contained(Features, "+faminmax")); 1964 EXPECT_TRUE(llvm::is_contained(Features, "+fp8fma")); 1965 EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8fma")); 1966 EXPECT_TRUE(llvm::is_contained(Features, "+fp8dot2")); 1967 EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8dot2")); 1968 EXPECT_TRUE(llvm::is_contained(Features, "+fp8dot4")); 1969 EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8dot4")); 1970 EXPECT_TRUE(llvm::is_contained(Features, "+lut")); 1971 EXPECT_TRUE(llvm::is_contained(Features, "+sme-lutv2")); 1972 EXPECT_TRUE(llvm::is_contained(Features, "+sme-f8f16")); 1973 EXPECT_TRUE(llvm::is_contained(Features, "+sme-f8f32")); 1974 EXPECT_TRUE(llvm::is_contained(Features, "+sme-fa64")); 1975 EXPECT_TRUE(llvm::is_contained(Features, "+cpa")); 1976 EXPECT_TRUE(llvm::is_contained(Features, "+pauth-lr")); 1977 EXPECT_TRUE(llvm::is_contained(Features, "+tlbiw")); 1978 EXPECT_TRUE(llvm::is_contained(Features, "+jsconv")); 1979 EXPECT_TRUE(llvm::is_contained(Features, "+complxnum")); 1980 1981 // Assuming we listed every extension above, this should produce the same 1982 // result. (note that AEK_NONE doesn't have a name so it won't be in the 1983 // result despite its bit being set) 1984 std::vector<StringRef> AllFeatures; 1985 EXPECT_TRUE(AArch64::getExtensionFeatures(ExtVal, AllFeatures)); 1986 EXPECT_THAT(Features, ::testing::ContainerEq(AllFeatures)); 1987 } 1988 1989 TEST(TargetParserTest, AArch64ArchFeatures) { 1990 EXPECT_EQ(AArch64::ARMV8A.ArchFeature, "+v8a"); 1991 EXPECT_EQ(AArch64::ARMV8_1A.ArchFeature, "+v8.1a"); 1992 EXPECT_EQ(AArch64::ARMV8_2A.ArchFeature, "+v8.2a"); 1993 EXPECT_EQ(AArch64::ARMV8_3A.ArchFeature, "+v8.3a"); 1994 EXPECT_EQ(AArch64::ARMV8_4A.ArchFeature, "+v8.4a"); 1995 EXPECT_EQ(AArch64::ARMV8_5A.ArchFeature, "+v8.5a"); 1996 EXPECT_EQ(AArch64::ARMV8_6A.ArchFeature, "+v8.6a"); 1997 EXPECT_EQ(AArch64::ARMV8_7A.ArchFeature, "+v8.7a"); 1998 EXPECT_EQ(AArch64::ARMV8_8A.ArchFeature, "+v8.8a"); 1999 EXPECT_EQ(AArch64::ARMV8_9A.ArchFeature, "+v8.9a"); 2000 EXPECT_EQ(AArch64::ARMV9A.ArchFeature, "+v9a"); 2001 EXPECT_EQ(AArch64::ARMV9_1A.ArchFeature, "+v9.1a"); 2002 EXPECT_EQ(AArch64::ARMV9_2A.ArchFeature, "+v9.2a"); 2003 EXPECT_EQ(AArch64::ARMV9_3A.ArchFeature, "+v9.3a"); 2004 EXPECT_EQ(AArch64::ARMV9_4A.ArchFeature, "+v9.4a"); 2005 EXPECT_EQ(AArch64::ARMV9_5A.ArchFeature, "+v9.5a"); 2006 EXPECT_EQ(AArch64::ARMV8R.ArchFeature, "+v8r"); 2007 } 2008 2009 TEST(TargetParserTest, AArch64ArchPartialOrder) { 2010 for (const auto *A : AArch64::ArchInfos) { 2011 EXPECT_EQ(*A, *A); 2012 2013 // v8r has no relation to other valid architectures 2014 if (*A != AArch64::ARMV8R) { 2015 EXPECT_FALSE(A->implies(AArch64::ARMV8R)); 2016 EXPECT_FALSE(AArch64::ARMV8R.implies(*A)); 2017 } 2018 } 2019 2020 for (const auto *A : { 2021 &AArch64::ARMV8_1A, 2022 &AArch64::ARMV8_2A, 2023 &AArch64::ARMV8_3A, 2024 &AArch64::ARMV8_4A, 2025 &AArch64::ARMV8_5A, 2026 &AArch64::ARMV8_6A, 2027 &AArch64::ARMV8_7A, 2028 &AArch64::ARMV8_8A, 2029 &AArch64::ARMV8_9A, 2030 }) 2031 EXPECT_TRUE(A->implies(AArch64::ARMV8A)); 2032 2033 for (const auto *A : 2034 {&AArch64::ARMV9_1A, &AArch64::ARMV9_2A, &AArch64::ARMV9_3A, 2035 &AArch64::ARMV9_4A, &AArch64::ARMV9_5A}) 2036 EXPECT_TRUE(A->implies(AArch64::ARMV9A)); 2037 2038 EXPECT_TRUE(AArch64::ARMV8_1A.implies(AArch64::ARMV8A)); 2039 EXPECT_TRUE(AArch64::ARMV8_2A.implies(AArch64::ARMV8_1A)); 2040 EXPECT_TRUE(AArch64::ARMV8_3A.implies(AArch64::ARMV8_2A)); 2041 EXPECT_TRUE(AArch64::ARMV8_4A.implies(AArch64::ARMV8_3A)); 2042 EXPECT_TRUE(AArch64::ARMV8_5A.implies(AArch64::ARMV8_4A)); 2043 EXPECT_TRUE(AArch64::ARMV8_6A.implies(AArch64::ARMV8_5A)); 2044 EXPECT_TRUE(AArch64::ARMV8_7A.implies(AArch64::ARMV8_6A)); 2045 EXPECT_TRUE(AArch64::ARMV8_8A.implies(AArch64::ARMV8_7A)); 2046 EXPECT_TRUE(AArch64::ARMV8_9A.implies(AArch64::ARMV8_8A)); 2047 2048 EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV9A)); 2049 EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV9_1A)); 2050 EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV9_2A)); 2051 EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV9_3A)); 2052 EXPECT_TRUE(AArch64::ARMV9_5A.implies(AArch64::ARMV9_4A)); 2053 2054 EXPECT_TRUE(AArch64::ARMV9A.implies(AArch64::ARMV8_5A)); 2055 EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV8_6A)); 2056 EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV8_7A)); 2057 EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV8_8A)); 2058 EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV8_9A)); 2059 } 2060 2061 TEST(TargetParserTest, AArch64ArchExtFeature) { 2062 const char *ArchExt[][4] = { 2063 {"crc", "nocrc", "+crc", "-crc"}, 2064 {"crypto", "nocrypto", "+crypto", "-crypto"}, 2065 {"flagm", "noflagm", "+flagm", "-flagm"}, 2066 {"fp", "nofp", "+fp-armv8", "-fp-armv8"}, 2067 {"simd", "nosimd", "+neon", "-neon"}, 2068 {"fp16", "nofp16", "+fullfp16", "-fullfp16"}, 2069 {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"}, 2070 {"profile", "noprofile", "+spe", "-spe"}, 2071 {"ras", "noras", "+ras", "-ras"}, 2072 {"lse", "nolse", "+lse", "-lse"}, 2073 {"rdm", "nordm", "+rdm", "-rdm"}, 2074 {"sve", "nosve", "+sve", "-sve"}, 2075 {"sve2", "nosve2", "+sve2", "-sve2"}, 2076 {"sve2-aes", "nosve2-aes", "+sve2-aes", "-sve2-aes"}, 2077 {"sve2-sm4", "nosve2-sm4", "+sve2-sm4", "-sve2-sm4"}, 2078 {"sve2-sha3", "nosve2-sha3", "+sve2-sha3", "-sve2-sha3"}, 2079 {"sve2p1", "nosve2p1", "+sve2p1", "-sve2p1"}, 2080 {"b16b16", "nob16b16", "+b16b16", "-b16b16"}, 2081 {"sve2-bitperm", "nosve2-bitperm", "+sve2-bitperm", "-sve2-bitperm"}, 2082 {"dotprod", "nodotprod", "+dotprod", "-dotprod"}, 2083 {"rcpc", "norcpc", "+rcpc", "-rcpc"}, 2084 {"rng", "norng", "+rand", "-rand"}, 2085 {"memtag", "nomemtag", "+mte", "-mte"}, 2086 {"tme", "notme", "+tme", "-tme"}, 2087 {"pauth", "nopauth", "+pauth", "-pauth"}, 2088 {"ssbs", "nossbs", "+ssbs", "-ssbs"}, 2089 {"sb", "nosb", "+sb", "-sb"}, 2090 {"predres", "nopredres", "+predres", "-predres"}, 2091 {"i8mm", "noi8mm", "+i8mm", "-i8mm"}, 2092 {"f32mm", "nof32mm", "+f32mm", "-f32mm"}, 2093 {"f64mm", "nof64mm", "+f64mm", "-f64mm"}, 2094 {"sme", "nosme", "+sme", "-sme"}, 2095 {"sme-fa64", "nosme-fa64", "+sme-fa64", "-sme-fa64"}, 2096 {"sme-f64f64", "nosme-f64f64", "+sme-f64f64", "-sme-f64f64"}, 2097 {"sme-i16i64", "nosme-i16i64", "+sme-i16i64", "-sme-i16i64"}, 2098 {"sme-f16f16", "nosme-f16f16", "+sme-f16f16", "-sme-f16f16"}, 2099 {"sme2", "nosme2", "+sme2", "-sme2"}, 2100 {"sme2p1", "nosme2p1", "+sme2p1", "-sme2p1"}, 2101 {"hbc", "nohbc", "+hbc", "-hbc"}, 2102 {"mops", "nomops", "+mops", "-mops"}, 2103 {"pmuv3", "nopmuv3", "+perfmon", "-perfmon"}, 2104 {"predres2", "nopredres2", "+specres2", "-specres2"}, 2105 {"rasv2", "norasv2", "+rasv2", "-rasv2"}, 2106 {"gcs", "nogcs", "+gcs", "-gcs"}, 2107 {"fpmr", "nofpmr", "+fpmr", "-fpmr"}, 2108 {"fp8", "nofp8", "+fp8", "-fp8"}, 2109 {"faminmax", "nofaminmax", "+faminmax", "-faminmax"}, 2110 {"fp8fma", "nofp8fma", "+fp8fma", "-fp8fma"}, 2111 {"ssve-fp8fma", "nossve-fp8fma", "+ssve-fp8fma", "-ssve-fp8fma"}, 2112 {"fp8dot2", "nofp8dot2", "+fp8dot2", "-fp8dot2"}, 2113 {"ssve-fp8dot2", "nossve-fp8dot2", "+ssve-fp8dot2", "-ssve-fp8dot2"}, 2114 {"fp8dot4", "nofp8dot4", "+fp8dot4", "-fp8dot4"}, 2115 {"ssve-fp8dot4", "nossve-fp8dot4", "+ssve-fp8dot4", "-ssve-fp8dot4"}, 2116 {"lut", "nolut", "+lut", "-lut"}, 2117 {"sme-lutv2", "nosme-lutv2", "+sme-lutv2", "-sme-lutv2"}, 2118 {"sme-f8f16", "nosme-f8f16", "+sme-f8f16", "-sme-f8f16"}, 2119 {"sme-f8f32", "nosme-f8f32", "+sme-f8f32", "-sme-f8f32"}, 2120 }; 2121 2122 for (unsigned i = 0; i < std::size(ArchExt); i++) { 2123 EXPECT_EQ(StringRef(ArchExt[i][2]), 2124 AArch64::getArchExtFeature(ArchExt[i][0])); 2125 EXPECT_EQ(StringRef(ArchExt[i][3]), 2126 AArch64::getArchExtFeature(ArchExt[i][1])); 2127 } 2128 } 2129 2130 TEST(TargetParserTest, AArch64PrintSupportedExtensions) { 2131 std::string expected = "All available -march extensions for AArch64\n\n" 2132 " Name Description\n" 2133 " aes This is a long dummy description\n" 2134 " b16b16\n" 2135 " bf16\n"; 2136 2137 StringMap<StringRef> DummyMap; 2138 DummyMap["aes"] = "This is a long dummy description"; 2139 2140 outs().flush(); 2141 testing::internal::CaptureStdout(); 2142 AArch64::PrintSupportedExtensions(DummyMap); 2143 outs().flush(); 2144 std::string captured = testing::internal::GetCapturedStdout(); 2145 2146 // Check that the start of the output is as expected. 2147 EXPECT_EQ(0ULL, captured.find(expected)); 2148 2149 // Should not include "none". 2150 EXPECT_EQ(std::string::npos, captured.find("none")); 2151 // Should not include anything that lacks a feature name. Checking a few here 2152 // but not all as if one is hidden correctly the rest should be. 2153 EXPECT_EQ(std::string::npos, captured.find("memtag3")); 2154 EXPECT_EQ(std::string::npos, captured.find("sha1")); 2155 EXPECT_EQ(std::string::npos, captured.find("ssbs2")); 2156 } 2157 2158 struct AArch64ExtensionDependenciesBaseArchTestParams { 2159 const llvm::AArch64::ArchInfo &Arch; 2160 std::vector<StringRef> Modifiers; 2161 std::vector<StringRef> ExpectedPos; 2162 std::vector<StringRef> ExpectedNeg; 2163 }; 2164 2165 class AArch64ExtensionDependenciesBaseArchTestFixture 2166 : public ::testing::TestWithParam< 2167 AArch64ExtensionDependenciesBaseArchTestParams> {}; 2168 2169 struct AArch64ExtensionDependenciesBaseCPUTestParams { 2170 StringRef CPUName; 2171 std::vector<StringRef> Modifiers; 2172 std::vector<StringRef> ExpectedPos; 2173 std::vector<StringRef> ExpectedNeg; 2174 }; 2175 2176 class AArch64ExtensionDependenciesBaseCPUTestFixture 2177 : public ::testing::TestWithParam< 2178 AArch64ExtensionDependenciesBaseCPUTestParams> {}; 2179 2180 TEST_P(AArch64ExtensionDependenciesBaseArchTestFixture, 2181 AArch64ExtensionDependenciesBaseArch) { 2182 auto Params = GetParam(); 2183 2184 llvm::AArch64::ExtensionSet Extensions; 2185 Extensions.addArchDefaults(Params.Arch); 2186 for (auto M : Params.Modifiers) { 2187 bool success = Extensions.parseModifier(M); 2188 EXPECT_TRUE(success); 2189 } 2190 std::vector<StringRef> Features; 2191 Extensions.toLLVMFeatureList(Features); 2192 2193 for (auto E : Params.ExpectedPos) { 2194 std::string PosString = "+"; 2195 PosString += E; 2196 std::string NegString = "-"; 2197 NegString += E; 2198 ASSERT_THAT(Features, Contains(StrEq(PosString))); 2199 ASSERT_THAT(Features, Not(Contains(StrEq(NegString)))); 2200 } 2201 2202 for (auto E : Params.ExpectedNeg) { 2203 std::string PosString = "+"; 2204 PosString += E; 2205 ASSERT_THAT(Features, Not(Contains(StrEq(PosString)))); 2206 // Features default to off, so the negative string is not expected in many 2207 // cases. 2208 } 2209 } 2210 2211 TEST_P(AArch64ExtensionDependenciesBaseCPUTestFixture, 2212 AArch64ExtensionDependenciesBaseCPU) { 2213 auto Params = GetParam(); 2214 2215 llvm::AArch64::ExtensionSet Extensions; 2216 const std::optional<llvm::AArch64::CpuInfo> CPU = 2217 llvm::AArch64::parseCpu(Params.CPUName); 2218 EXPECT_TRUE(CPU); 2219 Extensions.addCPUDefaults(*CPU); 2220 for (auto M : Params.Modifiers) { 2221 bool success = Extensions.parseModifier(M); 2222 EXPECT_TRUE(success); 2223 } 2224 std::vector<StringRef> Features; 2225 Extensions.toLLVMFeatureList(Features); 2226 2227 for (auto E : Params.ExpectedPos) { 2228 std::string PosString = "+"; 2229 PosString += E; 2230 std::string NegString = "-"; 2231 NegString += E; 2232 ASSERT_THAT(Features, Contains(StrEq(PosString))); 2233 ASSERT_THAT(Features, Not(Contains(StrEq(NegString)))); 2234 } 2235 2236 for (auto E : Params.ExpectedNeg) { 2237 std::string PosString = "+"; 2238 PosString += E; 2239 ASSERT_THAT(Features, Not(Contains(StrEq(PosString)))); 2240 // Features default to off, so the negative string is not expected in many 2241 // cases. 2242 } 2243 } 2244 2245 AArch64ExtensionDependenciesBaseArchTestParams 2246 AArch64ExtensionDependenciesArchData[] = { 2247 // Base architecture features 2248 {AArch64::ARMV8A, {}, {"v8a", "fp-armv8", "neon"}, {}}, 2249 {AArch64::ARMV8_1A, 2250 {}, 2251 {"v8.1a", "crc", "fp-armv8", "lse", "rdm", "neon"}, 2252 {}}, 2253 {AArch64::ARMV9_5A, {}, {"v9.5a", "sve", "sve2", "mops", "cpa"}, {}}, 2254 2255 // Positive modifiers 2256 {AArch64::ARMV8A, {"fp16"}, {"fullfp16"}, {}}, 2257 {AArch64::ARMV8A, {"dotprod"}, {"dotprod"}, {}}, 2258 2259 // Negative modifiers 2260 {AArch64::ARMV8A, {"nofp"}, {"v8a"}, {"fp-armv8", "neon"}}, 2261 2262 // Mixed modifiers 2263 {AArch64::ARMV8A, 2264 {"fp16", "nofp16"}, 2265 {"v8a", "fp-armv8", "neon"}, 2266 {"fullfp16"}}, 2267 {AArch64::ARMV8A, 2268 {"fp16", "nofp"}, 2269 {"v8a"}, 2270 {"fp-armv8", "neon", "fullfp16"}}, 2271 2272 // Long dependency chains: sve2-bitperm -> sve2 -> sve -> fp16 -> fp 2273 {AArch64::ARMV8A, 2274 {"nofp", "sve2-bitperm"}, 2275 {"fp-armv8", "fullfp16", "sve", "sve2", "sve2-bitperm"}, 2276 {}}, 2277 {AArch64::ARMV8A, 2278 {"sve2-bitperm", "nofp16"}, 2279 {"fp-armv8"}, 2280 {"full-fp16", "sve", "sve2", "sve2-bitperm"}}, 2281 2282 // Meaning of +crypto varies with base architecture. 2283 {AArch64::ARMV8A, {"crypto"}, {"aes", "sha2"}, {}}, 2284 {AArch64::ARMV8_4A, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}}, 2285 {AArch64::ARMV9A, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}}, 2286 2287 // -crypto always disables all crypto features, even if it wouldn't 2288 // enable them. 2289 {AArch64::ARMV8A, 2290 {"aes", "sha2", "sha3", "sm4", "nocrypto"}, 2291 {}, 2292 {"aes", "sha2", "sha3", "sm4"}}, 2293 {AArch64::ARMV8_4A, 2294 {"aes", "sha2", "sha3", "sm4", "nocrypto"}, 2295 {}, 2296 {"aes", "sha2", "sha3", "sm4"}}, 2297 2298 // +sve implies +f32mm if the base architecture is v8.6A+ or v9.1A+, but 2299 // not earlier architectures. 2300 {AArch64::ARMV8_5A, {"sve"}, {"sve"}, {"f32mm"}}, 2301 {AArch64::ARMV9A, {"sve"}, {"sve"}, {"f32mm"}}, 2302 {AArch64::ARMV8_6A, {"sve"}, {"sve", "f32mm"}, {}}, 2303 {AArch64::ARMV9_1A, {"sve"}, {"sve", "f32mm"}, {}}, 2304 2305 // +fp16 implies +fp16fml for v8.4A+, but not v9.0-A+ 2306 {AArch64::ARMV8_3A, {"fp16"}, {"fullfp16"}, {"fp16fml"}}, 2307 {AArch64::ARMV9A, {"fp16"}, {"fullfp16"}, {"fp16fml"}}, 2308 {AArch64::ARMV8_4A, {"fp16"}, {"fullfp16", "fp16fml"}, {}}, 2309 2310 // fp -> fp16 2311 {AArch64::ARMV8A, {"nofp", "fp16"}, {"fp-armv8", "fullfp16"}, {}}, 2312 {AArch64::ARMV8A, {"fp16", "nofp"}, {}, {"fp-armv8", "fullfp16"}}, 2313 2314 // fp -> simd 2315 {AArch64::ARMV8A, {"nofp", "simd"}, {"fp-armv8", "neon"}, {}}, 2316 {AArch64::ARMV8A, {"simd", "nofp"}, {}, {"fp-armv8", "neon"}}, 2317 2318 // fp -> jscvt 2319 {AArch64::ARMV8A, {"nofp", "jscvt"}, {"fp-armv8", "jsconv"}, {}}, 2320 {AArch64::ARMV8A, {"jscvt", "nofp"}, {}, {"fp-armv8", "jsconv"}}, 2321 2322 // simd -> {aes, sha2, sha3, sm4} 2323 {AArch64::ARMV8A, {"nosimd", "aes"}, {"neon", "aes"}, {}}, 2324 {AArch64::ARMV8A, {"aes", "nosimd"}, {}, {"neon", "aes"}}, 2325 {AArch64::ARMV8A, {"nosimd", "sha2"}, {"neon", "sha2"}, {}}, 2326 {AArch64::ARMV8A, {"sha2", "nosimd"}, {}, {"neon", "sha2"}}, 2327 {AArch64::ARMV8A, {"nosimd", "sha3"}, {"neon", "sha3"}, {}}, 2328 {AArch64::ARMV8A, {"sha3", "nosimd"}, {}, {"neon", "sha3"}}, 2329 {AArch64::ARMV8A, {"nosimd", "sm4"}, {"neon", "sm4"}, {}}, 2330 {AArch64::ARMV8A, {"sm4", "nosimd"}, {}, {"neon", "sm4"}}, 2331 2332 // simd -> {rdm, dotprod, fcma} 2333 {AArch64::ARMV8A, {"nosimd", "rdm"}, {"neon", "rdm"}, {}}, 2334 {AArch64::ARMV8A, {"rdm", "nosimd"}, {}, {"neon", "rdm"}}, 2335 {AArch64::ARMV8A, {"nosimd", "dotprod"}, {"neon", "dotprod"}, {}}, 2336 {AArch64::ARMV8A, {"dotprod", "nosimd"}, {}, {"neon", "dotprod"}}, 2337 {AArch64::ARMV8A, {"nosimd", "fcma"}, {"neon", "complxnum"}, {}}, 2338 {AArch64::ARMV8A, {"fcma", "nosimd"}, {}, {"neon", "complxnum"}}, 2339 2340 // fp16 -> {fp16fml, sve} 2341 {AArch64::ARMV8A, {"nofp16", "fp16fml"}, {"fullfp16", "fp16fml"}, {}}, 2342 {AArch64::ARMV8A, {"fp16fml", "nofp16"}, {}, {"fullfp16", "fp16fml"}}, 2343 {AArch64::ARMV8A, {"nofp16", "sve"}, {"fullfp16", "sve"}, {}}, 2344 {AArch64::ARMV8A, {"sve", "nofp16"}, {}, {"fullfp16", "sve"}}, 2345 2346 // bf16 -> {sme, b16b16} 2347 {AArch64::ARMV8A, {"nobf16", "sme"}, {"bf16", "sme"}, {}}, 2348 {AArch64::ARMV8A, {"sme", "nobf16"}, {}, {"bf16", "sme"}}, 2349 {AArch64::ARMV8A, {"nobf16", "b16b16"}, {"bf16", "b16b16"}, {}}, 2350 {AArch64::ARMV8A, {"b16b16", "nobf16"}, {}, {"bf16", "b16b16"}}, 2351 2352 // sve -> {sve2, f32mm, f64mm} 2353 {AArch64::ARMV8A, {"nosve", "sve2"}, {"sve", "sve2"}, {}}, 2354 {AArch64::ARMV8A, {"sve2", "nosve"}, {}, {"sve", "sve2"}}, 2355 {AArch64::ARMV8A, {"nosve", "f32mm"}, {"sve", "f32mm"}, {}}, 2356 {AArch64::ARMV8A, {"f32mm", "nosve"}, {}, {"sve", "f32mm"}}, 2357 {AArch64::ARMV8A, {"nosve", "f64mm"}, {"sve", "f64mm"}, {}}, 2358 {AArch64::ARMV8A, {"f64mm", "nosve"}, {}, {"sve", "f64mm"}}, 2359 2360 // sve2 -> {sve2p1, sve2-bitperm, sve2-aes, sve2-sha3, sve2-sm4} 2361 {AArch64::ARMV8A, {"nosve2", "sve2p1"}, {"sve2", "sve2p1"}, {}}, 2362 {AArch64::ARMV8A, {"sve2p1", "nosve2"}, {}, {"sve2", "sve2p1"}}, 2363 {AArch64::ARMV8A, 2364 {"nosve2", "sve2-bitperm"}, 2365 {"sve2", "sve2-bitperm"}, 2366 {}}, 2367 {AArch64::ARMV8A, 2368 {"sve2-bitperm", "nosve2"}, 2369 {}, 2370 {"sve2", "sve2-bitperm"}}, 2371 {AArch64::ARMV8A, {"nosve2", "sve2-aes"}, {"sve2", "sve2-aes"}, {}}, 2372 {AArch64::ARMV8A, {"sve2-aes", "nosve2"}, {}, {"sve2", "sve2-aes"}}, 2373 {AArch64::ARMV8A, {"nosve2", "sve2-sha3"}, {"sve2", "sve2-sha3"}, {}}, 2374 {AArch64::ARMV8A, {"sve2-sha3", "nosve2"}, {}, {"sve2", "sve2-sha3"}}, 2375 {AArch64::ARMV8A, {"nosve2", "sve2-sm4"}, {"sve2", "sve2-sm4"}, {}}, 2376 {AArch64::ARMV8A, {"sve2-sm4", "nosve2"}, {}, {"sve2", "sve2-sm4"}}, 2377 2378 // sme -> {sme2, sme-f16f16, sme-f64f64, sme-i16i64, sme-fa64} 2379 {AArch64::ARMV8A, {"nosme", "sme2"}, {"sme", "sme2"}, {}}, 2380 {AArch64::ARMV8A, {"sme2", "nosme"}, {}, {"sme", "sme2"}}, 2381 {AArch64::ARMV8A, {"nosme", "sme-f16f16"}, {"sme", "sme-f16f16"}, {}}, 2382 {AArch64::ARMV8A, {"sme-f16f16", "nosme"}, {}, {"sme", "sme-f16f16"}}, 2383 {AArch64::ARMV8A, {"nosme", "sme-f64f64"}, {"sme", "sme-f64f64"}, {}}, 2384 {AArch64::ARMV8A, {"sme-f64f64", "nosme"}, {}, {"sme", "sme-f64f64"}}, 2385 {AArch64::ARMV8A, {"nosme", "sme-i16i64"}, {"sme", "sme-i16i64"}, {}}, 2386 {AArch64::ARMV8A, {"sme-i16i64", "nosme"}, {}, {"sme", "sme-i16i64"}}, 2387 {AArch64::ARMV8A, {"nosme", "sme-fa64"}, {"sme", "sme-fa64"}, {}}, 2388 {AArch64::ARMV8A, {"sme-fa64", "nosme"}, {}, {"sme", "sme-fa64"}}, 2389 2390 // sme2 -> {sme2p1, ssve-fp8fma, ssve-fp8dot2, ssve-fp8dot4, sme-f8f16, 2391 // sme-f8f32} 2392 {AArch64::ARMV8A, {"nosme2", "sme2p1"}, {"sme2", "sme2p1"}, {}}, 2393 {AArch64::ARMV8A, {"sme2p1", "nosme2"}, {}, {"sme2", "sme2p1"}}, 2394 {AArch64::ARMV8A, 2395 {"nosme2", "ssve-fp8fma"}, 2396 {"sme2", "ssve-fp8fma"}, 2397 {}}, 2398 {AArch64::ARMV8A, 2399 {"ssve-fp8fma", "nosme2"}, 2400 {}, 2401 {"sme2", "ssve-fp8fma"}}, 2402 {AArch64::ARMV8A, 2403 {"nosme2", "ssve-fp8dot2"}, 2404 {"sme2", "ssve-fp8dot2"}, 2405 {}}, 2406 {AArch64::ARMV8A, 2407 {"ssve-fp8dot2", "nosme2"}, 2408 {}, 2409 {"sme2", "ssve-fp8dot2"}}, 2410 {AArch64::ARMV8A, 2411 {"nosme2", "ssve-fp8dot4"}, 2412 {"sme2", "ssve-fp8dot4"}, 2413 {}}, 2414 {AArch64::ARMV8A, 2415 {"ssve-fp8dot4", "nosme2"}, 2416 {}, 2417 {"sme2", "ssve-fp8dot4"}}, 2418 {AArch64::ARMV8A, {"nosme2", "sme-f8f16"}, {"sme2", "sme-f8f16"}, {}}, 2419 {AArch64::ARMV8A, {"sme-f8f16", "nosme2"}, {}, {"sme2", "sme-f8f16"}}, 2420 {AArch64::ARMV8A, {"nosme2", "sme-f8f32"}, {"sme2", "sme-f8f32"}, {}}, 2421 {AArch64::ARMV8A, {"sme-f8f32", "nosme2"}, {}, {"sme2", "sme-f8f32"}}, 2422 2423 // fp8 -> {sme-f8f16, sme-f8f32} 2424 {AArch64::ARMV8A, {"nofp8", "sme-f8f16"}, {"fp8", "sme-f8f16"}, {}}, 2425 {AArch64::ARMV8A, {"sme-f8f16", "nofp8"}, {}, {"fp8", "sme-f8f16"}}, 2426 {AArch64::ARMV8A, {"nofp8", "sme-f8f32"}, {"fp8", "sme-f8f32"}, {}}, 2427 {AArch64::ARMV8A, {"sme-f8f32", "nofp8"}, {}, {"fp8", "sme-f8f32"}}, 2428 2429 // lse -> lse128 2430 {AArch64::ARMV8A, {"nolse", "lse128"}, {"lse", "lse128"}, {}}, 2431 {AArch64::ARMV8A, {"lse128", "nolse"}, {}, {"lse", "lse128"}}, 2432 2433 // predres -> predres2 2434 {AArch64::ARMV8A, 2435 {"nopredres", "predres2"}, 2436 {"predres", "specres2"}, 2437 {}}, 2438 {AArch64::ARMV8A, 2439 {"predres2", "nopredres"}, 2440 {}, 2441 {"predres", "specres2"}}, 2442 2443 // ras -> ras2 2444 {AArch64::ARMV8A, {"noras", "rasv2"}, {"ras", "rasv2"}, {}}, 2445 {AArch64::ARMV8A, {"rasv2", "noras"}, {}, {"ras", "rasv2"}}, 2446 2447 // rcpc -> rcpc3 2448 {AArch64::ARMV8A, {"norcpc", "rcpc3"}, {"rcpc", "rcpc3"}, {}}, 2449 {AArch64::ARMV8A, {"rcpc3", "norcpc"}, {}, {"rcpc", "rcpc3"}}, 2450 }; 2451 2452 INSTANTIATE_TEST_SUITE_P( 2453 AArch64ExtensionDependenciesBaseArch, 2454 AArch64ExtensionDependenciesBaseArchTestFixture, 2455 ::testing::ValuesIn(AArch64ExtensionDependenciesArchData)); 2456 2457 AArch64ExtensionDependenciesBaseCPUTestParams 2458 AArch64ExtensionDependenciesCPUData[] = { 2459 // Base CPU features 2460 {"cortex-a57", 2461 {}, 2462 {"v8a", "aes", "crc", "fp-armv8", "sha2", "neon"}, 2463 {}}, 2464 {"cortex-r82", 2465 {}, 2466 {"v8r", "crc", "dotprod", "fp-armv8", "fullfp16", "fp16fml", "lse", 2467 "ras", "rcpc", "rdm", "sb", "neon", "ssbs"}, 2468 {}}, 2469 {"cortex-a520", 2470 {}, 2471 {"v9.2a", "bf16", "crc", "dotprod", "f32mm", "flagm", 2472 "fp-armv8", "fullfp16", "fp16fml", "i8mm", "lse", "mte", 2473 "pauth", "perfmon", "predres", "ras", "rcpc", "rdm", 2474 "sb", "neon", "ssbs", "sve", "sve2-bitperm", "sve2"}, 2475 {}}, 2476 2477 // Negative modifiers 2478 {"cortex-r82", 2479 {"nofp"}, 2480 {"v8r", "crc", "lse", "ras", "rcpc", "sb", "ssbs"}, 2481 {"fp-armv8", "neon", "fullfp16", "fp16fml", "dotprod", "rdm"}}, 2482 }; 2483 2484 INSTANTIATE_TEST_SUITE_P( 2485 AArch64ExtensionDependenciesBaseCPU, 2486 AArch64ExtensionDependenciesBaseCPUTestFixture, 2487 ::testing::ValuesIn(AArch64ExtensionDependenciesCPUData)); 2488 2489 } // namespace 2490