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