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", "armv9.6a", "armv9.6-a", 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-a510", "armv9-a", "neon-fp-armv8", 408 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 409 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 410 ARM::AEK_DSP | ARM::AEK_CRC | 411 ARM::AEK_RAS | ARM::AEK_DOTPROD | 412 ARM::AEK_FP16FML | ARM::AEK_BF16 | 413 ARM::AEK_I8MM | ARM::AEK_SB, 414 "9-A"), 415 ARMCPUTestParams<uint64_t>("cortex-a710", "armv9-a", "neon-fp-armv8", 416 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 417 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 418 ARM::AEK_DSP | ARM::AEK_CRC | 419 ARM::AEK_RAS | ARM::AEK_DOTPROD | 420 ARM::AEK_FP16FML | ARM::AEK_BF16 | 421 ARM::AEK_I8MM | ARM::AEK_SB, 422 "9-A"), 423 ARMCPUTestParams<uint64_t>( 424 "cortex-a77", "armv8.2-a", "crypto-neon-fp-armv8", 425 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 426 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | 427 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD, 428 "8.2-A"), 429 ARMCPUTestParams<uint64_t>( 430 "cortex-a78", "armv8.2-a", "crypto-neon-fp-armv8", 431 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_SEC | ARM::AEK_MP | 432 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 433 ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS, 434 "8.2-A"), 435 ARMCPUTestParams<uint64_t>( 436 "cortex-a78ae", "armv8.2-a", "crypto-neon-fp-armv8", 437 ARM::AEK_RAS | ARM::AEK_DOTPROD | ARM::AEK_SEC | ARM::AEK_MP | 438 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 439 ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS, 440 "8.2-A"), 441 ARMCPUTestParams<uint64_t>( 442 "cortex-x1", "armv8.2-a", "crypto-neon-fp-armv8", 443 ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD | ARM::AEK_SEC | 444 ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 445 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC, 446 "8.2-A"), 447 ARMCPUTestParams<uint64_t>( 448 "cortex-x1c", "armv8.2-a", "crypto-neon-fp-armv8", 449 ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_DOTPROD | ARM::AEK_SEC | 450 ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 451 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC, 452 "8.2-A"), 453 ARMCPUTestParams<uint64_t>( 454 "neoverse-n1", "armv8.2-a", "crypto-neon-fp-armv8", 455 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 456 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | 457 ARM::AEK_FP16 | ARM::AEK_RAS | ARM::AEK_DOTPROD, 458 "8.2-A"), 459 ARMCPUTestParams<uint64_t>( 460 "neoverse-n2", "armv9-a", "neon-fp-armv8", 461 ARM::AEK_CRC | ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM | 462 ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_VIRT | ARM::AEK_DSP | 463 ARM::AEK_BF16 | ARM::AEK_DOTPROD | ARM::AEK_RAS | 464 ARM::AEK_I8MM | ARM::AEK_FP16FML | ARM::AEK_SB, 465 "9-A"), 466 ARMCPUTestParams<uint64_t>( 467 "neoverse-v1", "armv8.4-a", "crypto-neon-fp-armv8", 468 ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 469 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC | 470 ARM::AEK_RAS | ARM::AEK_FP16 | ARM::AEK_BF16 | ARM::AEK_DOTPROD, 471 "8.4-A"), 472 ARMCPUTestParams<uint64_t>("cyclone", "armv8-a", "crypto-neon-fp-armv8", 473 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 474 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 475 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 476 "8-A"), 477 ARMCPUTestParams<uint64_t>("exynos-m3", "armv8-a", 478 "crypto-neon-fp-armv8", 479 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | 480 ARM::AEK_VIRT | ARM::AEK_HWDIVARM | 481 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 482 "8-A"), 483 ARMCPUTestParams<uint64_t>( 484 "exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8", 485 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 486 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | 487 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS, 488 "8.2-A"), 489 ARMCPUTestParams<uint64_t>( 490 "exynos-m5", "armv8.2-a", "crypto-neon-fp-armv8", 491 ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | 492 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | 493 ARM::AEK_DOTPROD | ARM::AEK_FP16 | ARM::AEK_RAS, 494 "8.2-A"), 495 ARMCPUTestParams<uint64_t>("cortex-m23", "armv8-m.base", "none", 496 ARM::AEK_NONE | ARM::AEK_HWDIVTHUMB, 497 "8-M.Baseline"), 498 ARMCPUTestParams<uint64_t>("cortex-m33", "armv8-m.main", "fpv5-sp-d16", 499 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 500 "8-M.Mainline"), 501 ARMCPUTestParams<uint64_t>("star-mc1", "armv8-m.main", "fpv5-sp-d16", 502 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 503 "8-M.Mainline"), 504 ARMCPUTestParams<uint64_t>("cortex-m35p", "armv8-m.main", "fpv5-sp-d16", 505 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, 506 "8-M.Mainline"), 507 ARMCPUTestParams<uint64_t>( 508 "cortex-m55", "armv8.1-m.main", "fp-armv8-fullfp16-d16", 509 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP | 510 ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16, 511 "8.1-M.Mainline"), 512 ARMCPUTestParams<uint64_t>( 513 "cortex-m85", "armv8.1-m.main", "fp-armv8-fullfp16-d16", 514 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP | 515 ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16 | ARM::AEK_PACBTI, 516 "8.1-M.Mainline"), 517 ARMCPUTestParams<uint64_t>( 518 "cortex-m52", "armv8.1-m.main", "fp-armv8-fullfp16-d16", 519 ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP | 520 ARM::AEK_RAS | ARM::AEK_LOB | ARM::AEK_FP16 | ARM::AEK_PACBTI, 521 "8.1-M.Mainline"), 522 ARMCPUTestParams<uint64_t>("iwmmxt", "iwmmxt", "none", ARM::AEK_NONE, 523 "iwmmxt"), 524 ARMCPUTestParams<uint64_t>("xscale", "xscale", "none", ARM::AEK_NONE, 525 "xscale"), 526 ARMCPUTestParams<uint64_t>("swift", "armv7s", "neon-vfpv4", 527 ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | 528 ARM::AEK_DSP, 529 "7-S")), 530 ARMCPUTestParams<uint64_t>::PrintToStringParamName); 531 532 static constexpr unsigned NumARMCPUArchs = 94; 533 534 TEST(TargetParserTest, testARMCPUArchList) { 535 SmallVector<StringRef, NumARMCPUArchs> List; 536 ARM::fillValidCPUArchList(List); 537 538 // No list exists for these in this test suite, so ensure all are 539 // valid, and match the expected 'magic' count. 540 EXPECT_EQ(List.size(), NumARMCPUArchs); 541 for (StringRef CPU : List) { 542 EXPECT_NE(ARM::parseCPUArch(CPU), ARM::ArchKind::INVALID); 543 } 544 } 545 546 TEST(TargetParserTest, testInvalidARMArch) { 547 auto InvalidArchStrings = {"armv", "armv99", "noarm"}; 548 for (const char *InvalidArch : InvalidArchStrings) 549 EXPECT_EQ(ARM::parseArch(InvalidArch), ARM::ArchKind::INVALID); 550 } 551 552 bool testARMArch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch, 553 unsigned ArchAttr) { 554 ARM::ArchKind AK = ARM::parseArch(Arch); 555 bool Result = (AK != ARM::ArchKind::INVALID); 556 Result &= ARM::getDefaultCPU(Arch) == DefaultCPU; 557 Result &= ARM::getSubArch(AK) == SubArch; 558 Result &= (ARM::getArchAttr(AK) == ArchAttr); 559 return Result; 560 } 561 562 TEST(TargetParserTest, testARMArch) { 563 EXPECT_TRUE( 564 testARMArch("armv4", "strongarm", "v4", ARMBuildAttrs::CPUArch::v4)); 565 EXPECT_TRUE( 566 testARMArch("armv4t", "arm7tdmi", "v4t", ARMBuildAttrs::CPUArch::v4T)); 567 EXPECT_TRUE( 568 testARMArch("armv5t", "arm10tdmi", "v5", ARMBuildAttrs::CPUArch::v5T)); 569 EXPECT_TRUE( 570 testARMArch("armv5te", "arm1022e", "v5e", ARMBuildAttrs::CPUArch::v5TE)); 571 EXPECT_TRUE(testARMArch("armv5tej", "arm926ej-s", "v5e", 572 ARMBuildAttrs::CPUArch::v5TEJ)); 573 EXPECT_TRUE( 574 testARMArch("armv6", "arm1136jf-s", "v6", ARMBuildAttrs::CPUArch::v6)); 575 EXPECT_TRUE( 576 testARMArch("armv6k", "mpcore", "v6k", ARMBuildAttrs::CPUArch::v6K)); 577 EXPECT_TRUE(testARMArch("armv6t2", "arm1156t2-s", "v6t2", 578 ARMBuildAttrs::CPUArch::v6T2)); 579 EXPECT_TRUE(testARMArch("armv6kz", "arm1176jzf-s", "v6kz", 580 ARMBuildAttrs::CPUArch::v6KZ)); 581 EXPECT_TRUE( 582 testARMArch("armv6-m", "cortex-m0", "v6m", ARMBuildAttrs::CPUArch::v6_M)); 583 EXPECT_TRUE( 584 testARMArch("armv7-a", "generic", "v7", ARMBuildAttrs::CPUArch::v7)); 585 EXPECT_TRUE( 586 testARMArch("armv7ve", "generic", "v7ve", ARMBuildAttrs::CPUArch::v7)); 587 EXPECT_TRUE( 588 testARMArch("armv7-r", "cortex-r4", "v7r", ARMBuildAttrs::CPUArch::v7)); 589 EXPECT_TRUE( 590 testARMArch("armv7-m", "cortex-m3", "v7m", ARMBuildAttrs::CPUArch::v7)); 591 EXPECT_TRUE(testARMArch("armv7e-m", "cortex-m4", "v7em", 592 ARMBuildAttrs::CPUArch::v7E_M)); 593 EXPECT_TRUE( 594 testARMArch("armv8-a", "generic", "v8a", ARMBuildAttrs::CPUArch::v8_A)); 595 EXPECT_TRUE(testARMArch("armv8.1-a", "generic", "v8.1a", 596 ARMBuildAttrs::CPUArch::v8_A)); 597 EXPECT_TRUE(testARMArch("armv8.2-a", "generic", "v8.2a", 598 ARMBuildAttrs::CPUArch::v8_A)); 599 EXPECT_TRUE(testARMArch("armv8.3-a", "generic", "v8.3a", 600 ARMBuildAttrs::CPUArch::v8_A)); 601 EXPECT_TRUE(testARMArch("armv8.4-a", "generic", "v8.4a", 602 ARMBuildAttrs::CPUArch::v8_A)); 603 EXPECT_TRUE(testARMArch("armv8.5-a", "generic", "v8.5a", 604 ARMBuildAttrs::CPUArch::v8_A)); 605 EXPECT_TRUE(testARMArch("armv8.6-a", "generic", "v8.6a", 606 ARMBuildAttrs::CPUArch::v8_A)); 607 EXPECT_TRUE(testARMArch("armv8.7-a", "generic", "v8.7a", 608 ARMBuildAttrs::CPUArch::v8_A)); 609 EXPECT_TRUE(testARMArch("armv8.8-a", "generic", "v8.8a", 610 ARMBuildAttrs::CPUArch::v8_A)); 611 EXPECT_TRUE(testARMArch("armv8.9-a", "generic", "v8.9a", 612 ARMBuildAttrs::CPUArch::v8_A)); 613 EXPECT_TRUE( 614 testARMArch("armv9-a", "generic", "v9a", ARMBuildAttrs::CPUArch::v9_A)); 615 EXPECT_TRUE(testARMArch("armv9.1-a", "generic", "v9.1a", 616 ARMBuildAttrs::CPUArch::v9_A)); 617 EXPECT_TRUE(testARMArch("armv9.2-a", "generic", "v9.2a", 618 ARMBuildAttrs::CPUArch::v9_A)); 619 EXPECT_TRUE(testARMArch("armv9.3-a", "generic", "v9.3a", 620 ARMBuildAttrs::CPUArch::v9_A)); 621 EXPECT_TRUE(testARMArch("armv9.4-a", "generic", "v9.4a", 622 ARMBuildAttrs::CPUArch::v9_A)); 623 EXPECT_TRUE(testARMArch("armv9.5-a", "generic", "v9.5a", 624 ARMBuildAttrs::CPUArch::v9_A)); 625 EXPECT_TRUE(testARMArch("armv9.6-a", "generic", "v9.6a", 626 ARMBuildAttrs::CPUArch::v9_A)); 627 EXPECT_TRUE( 628 testARMArch("armv8-r", "generic", "v8r", ARMBuildAttrs::CPUArch::v8_R)); 629 EXPECT_TRUE(testARMArch("armv8-m.base", "generic", "v8m.base", 630 ARMBuildAttrs::CPUArch::v8_M_Base)); 631 EXPECT_TRUE(testARMArch("armv8-m.main", "generic", "v8m.main", 632 ARMBuildAttrs::CPUArch::v8_M_Main)); 633 EXPECT_TRUE(testARMArch("armv8.1-m.main", "generic", "v8.1m.main", 634 ARMBuildAttrs::CPUArch::v8_1_M_Main)); 635 EXPECT_TRUE( 636 testARMArch("iwmmxt", "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE)); 637 EXPECT_TRUE( 638 testARMArch("iwmmxt2", "generic", "", ARMBuildAttrs::CPUArch::v5TE)); 639 EXPECT_TRUE( 640 testARMArch("xscale", "xscale", "v5e", ARMBuildAttrs::CPUArch::v5TE)); 641 EXPECT_TRUE( 642 testARMArch("armv7s", "swift", "v7s", ARMBuildAttrs::CPUArch::v7)); 643 EXPECT_TRUE( 644 testARMArch("armv7k", "generic", "v7k", ARMBuildAttrs::CPUArch::v7)); 645 } 646 647 bool testARMExtension(StringRef CPUName, ARM::ArchKind ArchKind, 648 StringRef ArchExt) { 649 return ARM::getDefaultExtensions(CPUName, ArchKind) & 650 ARM::parseArchExt(ArchExt); 651 } 652 653 TEST(TargetParserTest, testARMExtension) { 654 EXPECT_FALSE(testARMExtension("strongarm", ARM::ArchKind::INVALID, "dsp")); 655 EXPECT_FALSE(testARMExtension("arm7tdmi", ARM::ArchKind::INVALID, "dsp")); 656 EXPECT_FALSE(testARMExtension("arm10tdmi", ARM::ArchKind::INVALID, "simd")); 657 EXPECT_FALSE(testARMExtension("arm1022e", ARM::ArchKind::INVALID, "simd")); 658 EXPECT_FALSE(testARMExtension("arm926ej-s", ARM::ArchKind::INVALID, "simd")); 659 EXPECT_FALSE( 660 testARMExtension("arm1136jf-s", ARM::ArchKind::INVALID, "crypto")); 661 EXPECT_FALSE( 662 testARMExtension("arm1156t2-s", ARM::ArchKind::INVALID, "crypto")); 663 EXPECT_FALSE( 664 testARMExtension("arm1176jzf-s", ARM::ArchKind::INVALID, "crypto")); 665 EXPECT_FALSE(testARMExtension("cortex-m0", ARM::ArchKind::INVALID, "crypto")); 666 EXPECT_FALSE(testARMExtension("cortex-a8", ARM::ArchKind::INVALID, "crypto")); 667 EXPECT_FALSE(testARMExtension("cortex-r4", ARM::ArchKind::INVALID, "crypto")); 668 EXPECT_FALSE(testARMExtension("cortex-m3", ARM::ArchKind::INVALID, "crypto")); 669 EXPECT_FALSE(testARMExtension("cortex-a53", ARM::ArchKind::INVALID, "ras")); 670 EXPECT_FALSE(testARMExtension("cortex-a53", ARM::ArchKind::INVALID, "fp16")); 671 EXPECT_TRUE(testARMExtension("cortex-a55", ARM::ArchKind::INVALID, "fp16")); 672 EXPECT_FALSE( 673 testARMExtension("cortex-a55", ARM::ArchKind::INVALID, "fp16fml")); 674 EXPECT_TRUE(testARMExtension("cortex-a75", ARM::ArchKind::INVALID, "fp16")); 675 EXPECT_FALSE( 676 testARMExtension("cortex-a75", ARM::ArchKind::INVALID, "fp16fml")); 677 EXPECT_FALSE(testARMExtension("cortex-r52", ARM::ArchKind::INVALID, "ras")); 678 EXPECT_FALSE( 679 testARMExtension("cortex-r52plus", ARM::ArchKind::INVALID, "ras")); 680 EXPECT_FALSE(testARMExtension("iwmmxt", ARM::ArchKind::INVALID, "crc")); 681 EXPECT_FALSE(testARMExtension("xscale", ARM::ArchKind::INVALID, "crc")); 682 EXPECT_FALSE(testARMExtension("swift", ARM::ArchKind::INVALID, "crc")); 683 684 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4, "dsp")); 685 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4T, "dsp")); 686 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5T, "simd")); 687 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TE, "simd")); 688 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TEJ, "simd")); 689 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6, "crypto")); 690 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6K, "crypto")); 691 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6T2, "crypto")); 692 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6KZ, "crypto")); 693 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6M, "crypto")); 694 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7A, "crypto")); 695 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7R, "crypto")); 696 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7M, "crypto")); 697 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7EM, "crypto")); 698 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8A, "ras")); 699 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_1A, "ras")); 700 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "profile")); 701 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16")); 702 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16fml")); 703 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A, "fp16")); 704 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A, "fp16fml")); 705 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A, "fp16")); 706 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A, "fp16fml")); 707 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8R, "ras")); 708 EXPECT_FALSE( 709 testARMExtension("generic", ARM::ArchKind::ARMV8MBaseline, "crc")); 710 EXPECT_FALSE( 711 testARMExtension("generic", ARM::ArchKind::ARMV8MMainline, "crc")); 712 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT, "crc")); 713 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT2, "crc")); 714 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::XSCALE, "crc")); 715 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7S, "crypto")); 716 EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7K, "crypto")); 717 } 718 719 TEST(TargetParserTest, ARMFPUVersion) { 720 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0); 721 FK <= ARM::FPUKind::FK_LAST; 722 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) 723 if (FK == ARM::FK_LAST || ARM::getFPUName(FK) == "invalid" || 724 ARM::getFPUName(FK) == "none" || ARM::getFPUName(FK) == "softvfp") 725 EXPECT_EQ(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK)); 726 else 727 EXPECT_NE(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK)); 728 } 729 730 TEST(TargetParserTest, ARMFPUNeonSupportLevel) { 731 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0); 732 FK <= ARM::FPUKind::FK_LAST; 733 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) 734 if (FK == ARM::FK_LAST || 735 ARM::getFPUName(FK).find("neon") == std::string::npos) 736 EXPECT_EQ(ARM::NeonSupportLevel::None, ARM::getFPUNeonSupportLevel(FK)); 737 else 738 EXPECT_NE(ARM::NeonSupportLevel::None, ARM::getFPUNeonSupportLevel(FK)); 739 } 740 741 TEST(TargetParserTest, ARMFPURestriction) { 742 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0); 743 FK <= ARM::FPUKind::FK_LAST; 744 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) { 745 if (FK == ARM::FK_LAST || 746 (ARM::getFPUName(FK).find("d16") == std::string::npos && 747 ARM::getFPUName(FK).find("vfpv3xd") == std::string::npos)) 748 EXPECT_EQ(ARM::FPURestriction::None, ARM::getFPURestriction(FK)); 749 else 750 EXPECT_NE(ARM::FPURestriction::None, ARM::getFPURestriction(FK)); 751 } 752 } 753 754 TEST(TargetParserTest, ARMExtensionFeatures) { 755 std::map<uint64_t, std::vector<StringRef>> Extensions; 756 757 for (auto &Ext : ARM::ARCHExtNames) { 758 if (!Ext.Feature.empty() && !Ext.NegFeature.empty()) 759 Extensions[Ext.ID] = {Ext.Feature, Ext.NegFeature}; 760 } 761 762 Extensions[ARM::AEK_HWDIVARM] = {"+hwdiv-arm", "-hwdiv-arm"}; 763 Extensions[ARM::AEK_HWDIVTHUMB] = {"+hwdiv", "-hwdiv"}; 764 765 std::vector<StringRef> Features; 766 767 EXPECT_FALSE(ARM::getExtensionFeatures(ARM::AEK_INVALID, Features)); 768 769 for (auto &E : Extensions) { 770 // test +extension 771 Features.clear(); 772 ARM::getExtensionFeatures(E.first, Features); 773 EXPECT_TRUE(llvm::is_contained(Features, E.second.at(0))); 774 EXPECT_EQ(Extensions.size(), Features.size()); 775 776 // test -extension 777 Features.clear(); 778 ARM::getExtensionFeatures(~E.first, Features); 779 EXPECT_TRUE(llvm::is_contained(Features, E.second.at(1))); 780 EXPECT_EQ(Extensions.size(), Features.size()); 781 } 782 } 783 784 TEST(TargetParserTest, ARMFPUFeatures) { 785 std::vector<StringRef> Features; 786 for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0); 787 FK <= ARM::FPUKind::FK_LAST; 788 FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) { 789 if (FK == ARM::FK_INVALID || FK >= ARM::FK_LAST) 790 EXPECT_FALSE(ARM::getFPUFeatures(FK, Features)); 791 else 792 EXPECT_TRUE(ARM::getFPUFeatures(FK, Features)); 793 } 794 } 795 796 TEST(TargetParserTest, ARMArchExtFeature) { 797 const char *ArchExt[][4] = {{"crc", "nocrc", "+crc", "-crc"}, 798 {"crypto", "nocrypto", "+crypto", "-crypto"}, 799 {"dsp", "nodsp", "+dsp", "-dsp"}, 800 {"fp", "nofp", nullptr, nullptr}, 801 {"idiv", "noidiv", nullptr, nullptr}, 802 {"mp", "nomp", nullptr, nullptr}, 803 {"simd", "nosimd", nullptr, nullptr}, 804 {"sec", "nosec", nullptr, nullptr}, 805 {"virt", "novirt", nullptr, nullptr}, 806 {"fp16", "nofp16", "+fullfp16", "-fullfp16"}, 807 {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"}, 808 {"ras", "noras", "+ras", "-ras"}, 809 {"dotprod", "nodotprod", "+dotprod", "-dotprod"}, 810 {"os", "noos", nullptr, nullptr}, 811 {"iwmmxt", "noiwmmxt", nullptr, nullptr}, 812 {"iwmmxt2", "noiwmmxt2", nullptr, nullptr}, 813 {"maverick", "maverick", nullptr, nullptr}, 814 {"xscale", "noxscale", nullptr, nullptr}, 815 {"sb", "nosb", "+sb", "-sb"}, 816 {"i8mm", "noi8mm", "+i8mm", "-i8mm"}, 817 {"mve", "nomve", "+mve", "-mve"}, 818 {"mve.fp", "nomve.fp", "+mve.fp", "-mve.fp"}}; 819 820 for (unsigned i = 0; i < std::size(ArchExt); i++) { 821 EXPECT_EQ(StringRef(ArchExt[i][2]), ARM::getArchExtFeature(ArchExt[i][0])); 822 EXPECT_EQ(StringRef(ArchExt[i][3]), ARM::getArchExtFeature(ArchExt[i][1])); 823 } 824 } 825 826 static bool 827 testArchExtDependency(const char *ArchExt, 828 const std::initializer_list<const char *> &Expected) { 829 std::vector<StringRef> Features; 830 ARM::FPUKind FPUKind; 831 832 if (!ARM::appendArchExtFeatures("", ARM::ArchKind::ARMV8_1MMainline, ArchExt, 833 Features, FPUKind)) 834 return false; 835 836 return llvm::all_of(Expected, [&](StringRef Ext) { 837 return llvm::is_contained(Features, Ext); 838 }); 839 } 840 841 TEST(TargetParserTest, ARMArchExtDependencies) { 842 EXPECT_TRUE(testArchExtDependency("mve", {"+mve", "+dsp"})); 843 EXPECT_TRUE(testArchExtDependency("mve.fp", {"+mve.fp", "+mve", "+dsp"})); 844 EXPECT_TRUE(testArchExtDependency("nodsp", {"-dsp", "-mve", "-mve.fp"})); 845 EXPECT_TRUE(testArchExtDependency("nomve", {"-mve", "-mve.fp"})); 846 } 847 848 TEST(TargetParserTest, ARMparseHWDiv) { 849 const char *hwdiv[] = {"thumb", "arm", "arm,thumb", "thumb,arm"}; 850 851 for (unsigned i = 0; i < std::size(hwdiv); i++) 852 EXPECT_NE(ARM::AEK_INVALID, ARM::parseHWDiv((StringRef)hwdiv[i])); 853 } 854 855 TEST(TargetParserTest, ARMparseArchEndianAndISA) { 856 const char *Arch[] = { 857 "v2", "v2a", "v3", "v3m", "v4", "v4t", 858 "v5", "v5t", "v5e", "v5te", "v5tej", "v6", 859 "v6j", "v6k", "v6hl", "v6t2", "v6kz", "v6z", 860 "v6zk", "v6-m", "v6m", "v6sm", "v6s-m", "v7-a", 861 "v7", "v7a", "v7ve", "v7hl", "v7l", "v7-r", 862 "v7r", "v7-m", "v7m", "v7k", "v7s", "v7e-m", 863 "v7em", "v8-a", "v8", "v8a", "v8l", "v8.1-a", 864 "v8.1a", "v8.2-a", "v8.2a", "v8.3-a", "v8.3a", "v8.4-a", 865 "v8.4a", "v8.5-a", "v8.5a", "v8.6-a", "v8.6a", "v8.7-a", 866 "v8.7a", "v8.8-a", "v8.8a", "v8-r", "v8m.base", "v8m.main", 867 "v8.1m.main"}; 868 869 for (unsigned i = 0; i < std::size(Arch); i++) { 870 std::string arm_1 = "armeb" + (std::string)(Arch[i]); 871 std::string arm_2 = "arm" + (std::string)(Arch[i]) + "eb"; 872 std::string arm_3 = "arm" + (std::string)(Arch[i]); 873 std::string thumb_1 = "thumbeb" + (std::string)(Arch[i]); 874 std::string thumb_2 = "thumb" + (std::string)(Arch[i]) + "eb"; 875 std::string thumb_3 = "thumb" + (std::string)(Arch[i]); 876 877 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_1)); 878 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_2)); 879 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(arm_3)); 880 881 EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_1)); 882 EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_2)); 883 EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_3)); 884 if (i >= 4) { 885 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_1)); 886 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_2)); 887 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(thumb_3)); 888 889 EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_1)); 890 EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_2)); 891 EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_3)); 892 } 893 } 894 895 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("aarch64")); 896 EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("arm64_32")); 897 EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian("aarch64_be")); 898 899 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64")); 900 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_be")); 901 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64")); 902 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_be")); 903 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_32")); 904 EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_32")); 905 } 906 907 TEST(TargetParserTest, ARMparseArchProfile) { 908 for (unsigned i = 0; i < std::size(ARMArch); i++) { 909 switch (ARM::parseArch(ARMArch[i])) { 910 case ARM::ArchKind::ARMV6M: 911 case ARM::ArchKind::ARMV7M: 912 case ARM::ArchKind::ARMV7EM: 913 case ARM::ArchKind::ARMV8MMainline: 914 case ARM::ArchKind::ARMV8MBaseline: 915 case ARM::ArchKind::ARMV8_1MMainline: 916 EXPECT_EQ(ARM::ProfileKind::M, ARM::parseArchProfile(ARMArch[i])); 917 break; 918 case ARM::ArchKind::ARMV7R: 919 case ARM::ArchKind::ARMV8R: 920 EXPECT_EQ(ARM::ProfileKind::R, ARM::parseArchProfile(ARMArch[i])); 921 break; 922 case ARM::ArchKind::ARMV7A: 923 case ARM::ArchKind::ARMV7VE: 924 case ARM::ArchKind::ARMV7K: 925 case ARM::ArchKind::ARMV8A: 926 case ARM::ArchKind::ARMV8_1A: 927 case ARM::ArchKind::ARMV8_2A: 928 case ARM::ArchKind::ARMV8_3A: 929 case ARM::ArchKind::ARMV8_4A: 930 case ARM::ArchKind::ARMV8_5A: 931 case ARM::ArchKind::ARMV8_6A: 932 case ARM::ArchKind::ARMV8_7A: 933 case ARM::ArchKind::ARMV8_8A: 934 case ARM::ArchKind::ARMV8_9A: 935 case ARM::ArchKind::ARMV9A: 936 case ARM::ArchKind::ARMV9_1A: 937 case ARM::ArchKind::ARMV9_2A: 938 case ARM::ArchKind::ARMV9_3A: 939 case ARM::ArchKind::ARMV9_4A: 940 case ARM::ArchKind::ARMV9_5A: 941 case ARM::ArchKind::ARMV9_6A: 942 EXPECT_EQ(ARM::ProfileKind::A, ARM::parseArchProfile(ARMArch[i])); 943 break; 944 default: 945 EXPECT_EQ(ARM::ProfileKind::INVALID, ARM::parseArchProfile(ARMArch[i])); 946 break; 947 } 948 } 949 } 950 951 TEST(TargetParserTest, ARMparseArchVersion) { 952 for (unsigned i = 0; i < std::size(ARMArch); i++) 953 if (((std::string)ARMArch[i]).substr(0, 4) == "armv") 954 EXPECT_EQ((ARMArch[i][4] - 48u), ARM::parseArchVersion(ARMArch[i])); 955 else 956 EXPECT_EQ(5u, ARM::parseArchVersion(ARMArch[i])); 957 } 958 959 TEST(TargetParserTest, getARMCPUForArch) { 960 // Platform specific defaults. 961 { 962 llvm::Triple Triple("arm--nacl"); 963 EXPECT_EQ("cortex-a8", ARM::getARMCPUForArch(Triple)); 964 } 965 { 966 llvm::Triple Triple("arm--openbsd"); 967 EXPECT_EQ("cortex-a8", ARM::getARMCPUForArch(Triple)); 968 } 969 { 970 llvm::Triple Triple("armv6-unknown-freebsd"); 971 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple)); 972 } 973 { 974 llvm::Triple Triple("thumbv6-unknown-freebsd"); 975 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple)); 976 } 977 { 978 llvm::Triple Triple("armebv6-unknown-freebsd"); 979 EXPECT_EQ("arm1176jzf-s", ARM::getARMCPUForArch(Triple)); 980 } 981 { 982 llvm::Triple Triple("arm--win32"); 983 EXPECT_EQ("cortex-a9", ARM::getARMCPUForArch(Triple)); 984 EXPECT_EQ("generic", ARM::getARMCPUForArch(Triple, "armv8-a")); 985 } 986 // Some alternative architectures 987 { 988 llvm::Triple Triple("armv7k-apple-ios9"); 989 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple)); 990 } 991 { 992 llvm::Triple Triple("armv7k-apple-watchos3"); 993 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple)); 994 } 995 { 996 llvm::Triple Triple("armv7k-apple-tvos9"); 997 EXPECT_EQ("cortex-a7", ARM::getARMCPUForArch(Triple)); 998 } 999 // armeb is permitted, but armebeb is not 1000 { 1001 llvm::Triple Triple("armeb-none-eabi"); 1002 EXPECT_EQ("arm7tdmi", ARM::getARMCPUForArch(Triple)); 1003 } 1004 { 1005 llvm::Triple Triple("armebeb-none-eabi"); 1006 EXPECT_EQ("", ARM::getARMCPUForArch(Triple)); 1007 } 1008 { 1009 llvm::Triple Triple("armebv6eb-none-eabi"); 1010 EXPECT_EQ("", ARM::getARMCPUForArch(Triple)); 1011 } 1012 // xscaleeb is permitted, but armebxscale is not 1013 { 1014 llvm::Triple Triple("xscaleeb-none-eabi"); 1015 EXPECT_EQ("xscale", ARM::getARMCPUForArch(Triple)); 1016 } 1017 { 1018 llvm::Triple Triple("armebxscale-none-eabi"); 1019 EXPECT_EQ("", ARM::getARMCPUForArch(Triple)); 1020 } 1021 } 1022 1023 TEST(TargetParserTest, ARMPrintSupportedExtensions) { 1024 std::string expected = 1025 "All available -march extensions for ARM\n\n" 1026 " Name Description\n" 1027 " crc This is a long dummy description\n" 1028 " crypto\n" 1029 " sha2\n"; 1030 1031 StringMap<StringRef> DummyMap; 1032 DummyMap["crc"] = "This is a long dummy description"; 1033 1034 outs().flush(); 1035 testing::internal::CaptureStdout(); 1036 ARM::PrintSupportedExtensions(DummyMap); 1037 outs().flush(); 1038 std::string captured = testing::internal::GetCapturedStdout(); 1039 1040 // Check that the start of the output is as expected. 1041 EXPECT_EQ(0ULL, captured.find(expected)); 1042 1043 // Should not include "none" or "invalid". 1044 EXPECT_EQ(std::string::npos, captured.find("none")); 1045 EXPECT_EQ(std::string::npos, captured.find("invalid")); 1046 // Should not include anything that lacks a feature name. Checking a few here 1047 // but not all as if one is hidden correctly the rest should be. 1048 EXPECT_EQ(std::string::npos, captured.find("simd")); 1049 EXPECT_EQ(std::string::npos, captured.find("maverick")); 1050 EXPECT_EQ(std::string::npos, captured.find("xscale")); 1051 } 1052 1053 struct AArch64CPUTestParams 1054 : public ARMCPUTestParams<AArch64::ExtensionBitset> { 1055 AArch64CPUTestParams(StringRef CPUName, StringRef ExpectedArch) 1056 : ARMCPUTestParams<AArch64::ExtensionBitset>(CPUName, ExpectedArch, 1057 /*ignored*/ "", {}, 1058 /*ignored*/ "") {} 1059 /// Print a gtest-compatible facsimile of the CPUName, to make the test's name 1060 /// human-readable. 1061 /// 1062 /// https://github.com/google/googletest/blob/main/docs/advanced.md#specifying-names-for-value-parameterized-test-parameters 1063 static std::string PrintToStringParamName( 1064 const testing::TestParamInfo<AArch64CPUTestParams> &Info) { 1065 std::string Name = Info.param.CPUName.str(); 1066 for (char &C : Name) 1067 if (!std::isalnum(C)) 1068 C = '_'; 1069 return Name; 1070 } 1071 }; 1072 1073 class AArch64CPUTestFixture 1074 : public ::testing::TestWithParam<AArch64CPUTestParams> {}; 1075 1076 TEST_P(AArch64CPUTestFixture, testAArch64CPU) { 1077 auto params = GetParam(); 1078 1079 const std::optional<AArch64::CpuInfo> Cpu = AArch64::parseCpu(params.CPUName); 1080 EXPECT_TRUE(Cpu); 1081 EXPECT_EQ(params.ExpectedArch, Cpu->Arch.Name); 1082 } 1083 1084 INSTANTIATE_TEST_SUITE_P( 1085 AArch64CPUTests, AArch64CPUTestFixture, 1086 ::testing::Values(AArch64CPUTestParams("cortex-a34", "armv8-a"), 1087 AArch64CPUTestParams("cortex-a35", "armv8-a"), 1088 AArch64CPUTestParams("cortex-a53", "armv8-a"), 1089 AArch64CPUTestParams("cortex-a55", "armv8.2-a"), 1090 AArch64CPUTestParams("cortex-a510", "armv9-a"), 1091 AArch64CPUTestParams("cortex-a520", "armv9.2-a"), 1092 AArch64CPUTestParams("cortex-a520ae", "armv9.2-a"), 1093 AArch64CPUTestParams("cortex-a57", "armv8-a"), 1094 AArch64CPUTestParams("cortex-a65", "armv8.2-a"), 1095 AArch64CPUTestParams("cortex-a65ae", "armv8.2-a"), 1096 AArch64CPUTestParams("cortex-a72", "armv8-a"), 1097 AArch64CPUTestParams("cortex-a73", "armv8-a"), 1098 AArch64CPUTestParams("cortex-a75", "armv8.2-a"), 1099 AArch64CPUTestParams("cortex-a76", "armv8.2-a"), 1100 AArch64CPUTestParams("cortex-a76ae", "armv8.2-a"), 1101 AArch64CPUTestParams("cortex-a77", "armv8.2-a"), 1102 AArch64CPUTestParams("cortex-a78", "armv8.2-a"), 1103 AArch64CPUTestParams("cortex-a78ae", "armv8.2-a"), 1104 AArch64CPUTestParams("cortex-a78c", "armv8.2-a"), 1105 AArch64CPUTestParams("cortex-a710", "armv9-a"), 1106 AArch64CPUTestParams("cortex-a715", "armv9-a"), 1107 AArch64CPUTestParams("cortex-a720", "armv9.2-a"), 1108 AArch64CPUTestParams("cortex-a720ae", "armv9.2-a"), 1109 AArch64CPUTestParams("cortex-a725", "armv9.2-a"), 1110 AArch64CPUTestParams("neoverse-v1", "armv8.4-a"), 1111 AArch64CPUTestParams("neoverse-v2", "armv9-a"), 1112 AArch64CPUTestParams("neoverse-v3", "armv9.2-a"), 1113 AArch64CPUTestParams("neoverse-v3ae", "armv9.2-a"), 1114 AArch64CPUTestParams("cortex-r82", "armv8-r"), 1115 AArch64CPUTestParams("cortex-r82ae", "armv8-r"), 1116 AArch64CPUTestParams("cortex-x1", "armv8.2-a"), 1117 AArch64CPUTestParams("cortex-x1c", "armv8.2-a"), 1118 AArch64CPUTestParams("cortex-x2", "armv9-a"), 1119 AArch64CPUTestParams("cortex-x3", "armv9-a"), 1120 AArch64CPUTestParams("cortex-x4", "armv9.2-a"), 1121 AArch64CPUTestParams("cortex-x925", "armv9.2-a"), 1122 AArch64CPUTestParams("cyclone", "armv8-a"), 1123 AArch64CPUTestParams("apple-a7", "armv8-a"), 1124 AArch64CPUTestParams("apple-a8", "armv8-a"), 1125 AArch64CPUTestParams("apple-a9", "armv8-a"), 1126 AArch64CPUTestParams("apple-a10", "armv8-a"), 1127 AArch64CPUTestParams("apple-a11", "armv8.2-a"), 1128 AArch64CPUTestParams("apple-a12", "armv8.3-a"), 1129 AArch64CPUTestParams("apple-s4", "armv8.3-a"), 1130 AArch64CPUTestParams("apple-s5", "armv8.3-a"), 1131 AArch64CPUTestParams("apple-a13", "armv8.4-a"), 1132 AArch64CPUTestParams("apple-a14", "armv8.4-a"), 1133 AArch64CPUTestParams("apple-m1", "armv8.4-a"), 1134 AArch64CPUTestParams("apple-a15", "armv8.6-a"), 1135 AArch64CPUTestParams("apple-m2", "armv8.6-a"), 1136 AArch64CPUTestParams("apple-a16", "armv8.6-a"), 1137 AArch64CPUTestParams("apple-m3", "armv8.6-a"), 1138 AArch64CPUTestParams("apple-a17", "armv8.6-a"), 1139 AArch64CPUTestParams("apple-m4", "armv8.7-a"), 1140 AArch64CPUTestParams("exynos-m3", "armv8-a"), 1141 AArch64CPUTestParams("exynos-m4", "armv8.2-a"), 1142 AArch64CPUTestParams("exynos-m5", "armv8.2-a"), 1143 AArch64CPUTestParams("falkor", "armv8-a"), 1144 AArch64CPUTestParams("kryo", "armv8-a"), 1145 AArch64CPUTestParams("neoverse-e1", "armv8.2-a"), 1146 AArch64CPUTestParams("neoverse-n1", "armv8.2-a"), 1147 AArch64CPUTestParams("neoverse-n2", "armv9-a"), 1148 AArch64CPUTestParams("neoverse-n3", "armv9.2-a"), 1149 AArch64CPUTestParams("ampere1", "armv8.6-a"), 1150 AArch64CPUTestParams("ampere1a", "armv8.6-a"), 1151 AArch64CPUTestParams("ampere1b", "armv8.7-a"), 1152 AArch64CPUTestParams("neoverse-512tvb", "armv8.4-a"), 1153 AArch64CPUTestParams("thunderx2t99", "armv8.1-a"), 1154 AArch64CPUTestParams("thunderx3t110", "armv8.3-a"), 1155 AArch64CPUTestParams("thunderx", "armv8-a"), 1156 AArch64CPUTestParams("thunderxt81", "armv8-a"), 1157 AArch64CPUTestParams("thunderxt83", "armv8-a"), 1158 AArch64CPUTestParams("thunderxt88", "armv8-a"), 1159 AArch64CPUTestParams("tsv110", "armv8.2-a"), 1160 AArch64CPUTestParams("a64fx", "armv8.2-a"), 1161 AArch64CPUTestParams("fujitsu-monaka", "armv9.3-a"), 1162 AArch64CPUTestParams("carmel", "armv8.2-a"), 1163 AArch64CPUTestParams("saphira", "armv8.4-a"), 1164 AArch64CPUTestParams("oryon-1", "armv8.6-a")), 1165 AArch64CPUTestParams::PrintToStringParamName); 1166 1167 // Note: number of CPUs includes aliases. 1168 static constexpr unsigned NumAArch64CPUArchs = 82; 1169 1170 TEST(TargetParserTest, testAArch64CPUArchList) { 1171 SmallVector<StringRef, NumAArch64CPUArchs> List; 1172 AArch64::fillValidCPUArchList(List); 1173 1174 // No list exists for these in this test suite, so ensure all are 1175 // valid, and match the expected 'magic' count. 1176 EXPECT_EQ(List.size(), NumAArch64CPUArchs); 1177 for (StringRef CPU : List) { 1178 EXPECT_TRUE(AArch64::parseCpu(CPU)); 1179 } 1180 } 1181 1182 bool testAArch64Arch(StringRef Arch) { 1183 const AArch64::ArchInfo *AI = AArch64::parseArch(Arch); 1184 return AI != nullptr; 1185 } 1186 1187 TEST(TargetParserTest, testAArch64Arch) { 1188 EXPECT_TRUE(testAArch64Arch("armv8-a")); 1189 EXPECT_TRUE(testAArch64Arch("armv8.1-a")); 1190 EXPECT_TRUE(testAArch64Arch("armv8.2-a")); 1191 EXPECT_TRUE(testAArch64Arch("armv8.3-a")); 1192 EXPECT_TRUE(testAArch64Arch("armv8.4-a")); 1193 EXPECT_TRUE(testAArch64Arch("armv8.5-a")); 1194 EXPECT_TRUE(testAArch64Arch("armv8.6-a")); 1195 EXPECT_TRUE(testAArch64Arch("armv8.7-a")); 1196 EXPECT_TRUE(testAArch64Arch("armv8.8-a")); 1197 EXPECT_TRUE(testAArch64Arch("armv8.9-a")); 1198 EXPECT_TRUE(testAArch64Arch("armv9-a")); 1199 EXPECT_TRUE(testAArch64Arch("armv9.1-a")); 1200 EXPECT_TRUE(testAArch64Arch("armv9.2-a")); 1201 EXPECT_TRUE(testAArch64Arch("armv9.3-a")); 1202 EXPECT_TRUE(testAArch64Arch("armv9.4-a")); 1203 EXPECT_TRUE(testAArch64Arch("armv9.5-a")); 1204 EXPECT_TRUE(testAArch64Arch("armv9.6-a")); 1205 } 1206 1207 bool testAArch64Extension(StringRef CPUName, StringRef ArchExt) { 1208 std::optional<AArch64::ExtensionInfo> Extension = 1209 AArch64::parseArchExtension(ArchExt); 1210 if (!Extension) 1211 return false; 1212 std::optional<AArch64::CpuInfo> CpuInfo = AArch64::parseCpu(CPUName); 1213 return CpuInfo->getImpliedExtensions().test(Extension->ID); 1214 } 1215 1216 bool testAArch64Extension(const AArch64::ArchInfo &AI, StringRef ArchExt) { 1217 std::optional<AArch64::ExtensionInfo> Extension = 1218 AArch64::parseArchExtension(ArchExt); 1219 if (!Extension) 1220 return false; 1221 return AI.DefaultExts.test(Extension->ID); 1222 } 1223 1224 TEST(TargetParserTest, testAArch64Extension) { 1225 EXPECT_FALSE(testAArch64Extension("cortex-a34", "ras")); 1226 EXPECT_FALSE(testAArch64Extension("cortex-a35", "ras")); 1227 EXPECT_FALSE(testAArch64Extension("cortex-a53", "ras")); 1228 EXPECT_TRUE(testAArch64Extension("cortex-a55", "ras")); 1229 EXPECT_TRUE(testAArch64Extension("cortex-a55", "fp16")); 1230 EXPECT_FALSE(testAArch64Extension("cortex-a55", "fp16fml")); 1231 EXPECT_TRUE(testAArch64Extension("cortex-a55", "dotprod")); 1232 EXPECT_FALSE(testAArch64Extension("cortex-a57", "ras")); 1233 EXPECT_FALSE(testAArch64Extension("cortex-a72", "ras")); 1234 EXPECT_FALSE(testAArch64Extension("cortex-a73", "ras")); 1235 EXPECT_TRUE(testAArch64Extension("cortex-a75", "ras")); 1236 EXPECT_TRUE(testAArch64Extension("cortex-a75", "fp16")); 1237 EXPECT_FALSE(testAArch64Extension("cortex-a75", "fp16fml")); 1238 EXPECT_TRUE(testAArch64Extension("cortex-a75", "dotprod")); 1239 EXPECT_TRUE(testAArch64Extension("cortex-r82", "ras")); 1240 EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16")); 1241 EXPECT_TRUE(testAArch64Extension("cortex-r82", "fp16fml")); 1242 EXPECT_TRUE(testAArch64Extension("cortex-r82", "dotprod")); 1243 EXPECT_TRUE(testAArch64Extension("cortex-r82", "lse")); 1244 EXPECT_FALSE(testAArch64Extension("cyclone", "ras")); 1245 EXPECT_FALSE(testAArch64Extension("exynos-m3", "ras")); 1246 EXPECT_TRUE(testAArch64Extension("exynos-m4", "dotprod")); 1247 EXPECT_TRUE(testAArch64Extension("exynos-m4", "fp16")); 1248 EXPECT_TRUE(testAArch64Extension("exynos-m4", "lse")); 1249 EXPECT_TRUE(testAArch64Extension("exynos-m4", "ras")); 1250 EXPECT_TRUE(testAArch64Extension("exynos-m4", "rdm")); 1251 EXPECT_TRUE(testAArch64Extension("exynos-m5", "dotprod")); 1252 EXPECT_TRUE(testAArch64Extension("exynos-m5", "fp16")); 1253 EXPECT_TRUE(testAArch64Extension("exynos-m5", "lse")); 1254 EXPECT_TRUE(testAArch64Extension("exynos-m5", "ras")); 1255 EXPECT_TRUE(testAArch64Extension("exynos-m5", "rdm")); 1256 EXPECT_TRUE(testAArch64Extension("falkor", "rdm")); 1257 EXPECT_FALSE(testAArch64Extension("kryo", "ras")); 1258 EXPECT_TRUE(testAArch64Extension("saphira", "crc")); 1259 EXPECT_TRUE(testAArch64Extension("saphira", "lse")); 1260 EXPECT_TRUE(testAArch64Extension("saphira", "rdm")); 1261 EXPECT_TRUE(testAArch64Extension("saphira", "ras")); 1262 EXPECT_TRUE(testAArch64Extension("saphira", "rcpc")); 1263 EXPECT_TRUE(testAArch64Extension("saphira", "profile")); 1264 EXPECT_FALSE(testAArch64Extension("saphira", "fp16")); 1265 EXPECT_FALSE(testAArch64Extension("thunderx2t99", "ras")); 1266 EXPECT_FALSE(testAArch64Extension("thunderx", "lse")); 1267 EXPECT_FALSE(testAArch64Extension("thunderxt81", "lse")); 1268 EXPECT_FALSE(testAArch64Extension("thunderxt83", "lse")); 1269 EXPECT_FALSE(testAArch64Extension("thunderxt88", "lse")); 1270 EXPECT_TRUE(testAArch64Extension("tsv110", "aes")); 1271 EXPECT_TRUE(testAArch64Extension("tsv110", "sha2")); 1272 EXPECT_FALSE(testAArch64Extension("tsv110", "sha3")); 1273 EXPECT_FALSE(testAArch64Extension("tsv110", "sm4")); 1274 EXPECT_TRUE(testAArch64Extension("tsv110", "ras")); 1275 EXPECT_TRUE(testAArch64Extension("tsv110", "profile")); 1276 EXPECT_TRUE(testAArch64Extension("tsv110", "fp16")); 1277 EXPECT_TRUE(testAArch64Extension("tsv110", "fp16fml")); 1278 EXPECT_TRUE(testAArch64Extension("tsv110", "dotprod")); 1279 EXPECT_TRUE(testAArch64Extension("tsv110", "jscvt")); 1280 EXPECT_TRUE(testAArch64Extension("tsv110", "fcma")); 1281 EXPECT_TRUE(testAArch64Extension("a64fx", "fp16")); 1282 EXPECT_TRUE(testAArch64Extension("a64fx", "sve")); 1283 EXPECT_FALSE(testAArch64Extension("a64fx", "sve2")); 1284 EXPECT_TRUE(testAArch64Extension("carmel", "aes")); 1285 EXPECT_TRUE(testAArch64Extension("carmel", "sha2")); 1286 EXPECT_TRUE(testAArch64Extension("carmel", "fp16")); 1287 1288 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8A, "ras")); 1289 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_1A, "ras")); 1290 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "profile")); 1291 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "fp16")); 1292 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_2A, "fp16fml")); 1293 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A, "fp16")); 1294 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_3A, "fp16fml")); 1295 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A, "fp16")); 1296 EXPECT_FALSE(testAArch64Extension(AArch64::ARMV8_4A, "fp16fml")); 1297 } 1298 1299 TEST(TargetParserTest, AArch64ExtensionFeatures) { 1300 std::vector<uint64_t> Extensions = { 1301 AArch64::AEK_CRC, AArch64::AEK_LSE, 1302 AArch64::AEK_RDM, AArch64::AEK_CRYPTO, 1303 AArch64::AEK_SM4, AArch64::AEK_SHA3, 1304 AArch64::AEK_SHA2, AArch64::AEK_AES, 1305 AArch64::AEK_DOTPROD, AArch64::AEK_FP, 1306 AArch64::AEK_SIMD, AArch64::AEK_FP16, 1307 AArch64::AEK_FP16FML, AArch64::AEK_PROFILE, 1308 AArch64::AEK_RAS, AArch64::AEK_SVE, 1309 AArch64::AEK_SVE2, AArch64::AEK_SVE2AES, 1310 AArch64::AEK_SVE2SM4, AArch64::AEK_SVE2SHA3, 1311 AArch64::AEK_SVE2BITPERM, AArch64::AEK_RCPC, 1312 AArch64::AEK_RAND, AArch64::AEK_MTE, 1313 AArch64::AEK_SSBS, AArch64::AEK_SB, 1314 AArch64::AEK_PREDRES, AArch64::AEK_BF16, 1315 AArch64::AEK_I8MM, AArch64::AEK_F32MM, 1316 AArch64::AEK_F64MM, AArch64::AEK_TME, 1317 AArch64::AEK_LS64, AArch64::AEK_BRBE, 1318 AArch64::AEK_PAUTH, AArch64::AEK_FLAGM, 1319 AArch64::AEK_SME, AArch64::AEK_SMEF64F64, 1320 AArch64::AEK_SMEI16I64, AArch64::AEK_SME2, 1321 AArch64::AEK_HBC, AArch64::AEK_MOPS, 1322 AArch64::AEK_PERFMON, AArch64::AEK_SVE2P1, 1323 AArch64::AEK_SME2P1, AArch64::AEK_SMEB16B16, 1324 AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC, 1325 AArch64::AEK_RCPC3, AArch64::AEK_THE, 1326 AArch64::AEK_D128, AArch64::AEK_LSE128, 1327 AArch64::AEK_SPECRES2, AArch64::AEK_RASV2, 1328 AArch64::AEK_ITE, AArch64::AEK_GCS, 1329 AArch64::AEK_FAMINMAX, AArch64::AEK_FP8FMA, 1330 AArch64::AEK_SSVE_FP8FMA, AArch64::AEK_FP8DOT2, 1331 AArch64::AEK_SSVE_FP8DOT2, AArch64::AEK_FP8DOT4, 1332 AArch64::AEK_SSVE_FP8DOT4, AArch64::AEK_LUT, 1333 AArch64::AEK_SME_LUTV2, AArch64::AEK_SMEF8F16, 1334 AArch64::AEK_SMEF8F32, AArch64::AEK_SMEFA64, 1335 AArch64::AEK_CPA, AArch64::AEK_PAUTHLR, 1336 AArch64::AEK_TLBIW, AArch64::AEK_JSCVT, 1337 AArch64::AEK_FCMA, AArch64::AEK_FP8, 1338 AArch64::AEK_SVEB16B16, AArch64::AEK_SVE2P2, 1339 AArch64::AEK_SME2P2, AArch64::AEK_SVE_BFSCALE, 1340 AArch64::AEK_SVE_F16F32MM, AArch64::AEK_SVE_AES2, 1341 AArch64::AEK_SSVE_AES, AArch64::AEK_F8F32MM, 1342 AArch64::AEK_F8F16MM, AArch64::AEK_LSFE, 1343 AArch64::AEK_FPRCVT, AArch64::AEK_CMPBR, 1344 AArch64::AEK_LSUI, AArch64::AEK_OCCMO, 1345 AArch64::AEK_PCDPHINT, AArch64::AEK_POPS, 1346 AArch64::AEK_SVEAES, AArch64::AEK_SME_MOP4, 1347 AArch64::AEK_SME_TMOP, AArch64::AEK_SVEBITPERM, 1348 AArch64::AEK_SSVE_BITPERM, 1349 }; 1350 1351 std::vector<StringRef> Features; 1352 1353 AArch64::ExtensionBitset ExtVal; 1354 for (auto Ext : Extensions) 1355 ExtVal.set(Ext); 1356 1357 // Test an empty set of features. 1358 EXPECT_TRUE(AArch64::getExtensionFeatures({}, Features)); 1359 EXPECT_TRUE(Features.size() == 0); 1360 1361 AArch64::getExtensionFeatures(ExtVal, Features); 1362 EXPECT_EQ(Extensions.size(), Features.size()); 1363 1364 EXPECT_TRUE(llvm::is_contained(Features, "+crc")); 1365 EXPECT_TRUE(llvm::is_contained(Features, "+lse")); 1366 EXPECT_TRUE(llvm::is_contained(Features, "+rdm")); 1367 EXPECT_TRUE(llvm::is_contained(Features, "+crypto")); 1368 EXPECT_TRUE(llvm::is_contained(Features, "+sm4")); 1369 EXPECT_TRUE(llvm::is_contained(Features, "+sha3")); 1370 EXPECT_TRUE(llvm::is_contained(Features, "+sha2")); 1371 EXPECT_TRUE(llvm::is_contained(Features, "+aes")); 1372 EXPECT_TRUE(llvm::is_contained(Features, "+dotprod")); 1373 EXPECT_TRUE(llvm::is_contained(Features, "+fp-armv8")); 1374 EXPECT_TRUE(llvm::is_contained(Features, "+neon")); 1375 EXPECT_TRUE(llvm::is_contained(Features, "+fullfp16")); 1376 EXPECT_TRUE(llvm::is_contained(Features, "+fp16fml")); 1377 EXPECT_TRUE(llvm::is_contained(Features, "+spe")); 1378 EXPECT_TRUE(llvm::is_contained(Features, "+ras")); 1379 EXPECT_TRUE(llvm::is_contained(Features, "+sve")); 1380 EXPECT_TRUE(llvm::is_contained(Features, "+sve-b16b16")); 1381 EXPECT_TRUE(llvm::is_contained(Features, "+sve-bfscale")); 1382 EXPECT_TRUE(llvm::is_contained(Features, "+sve-f16f32mm")); 1383 EXPECT_TRUE(llvm::is_contained(Features, "+sve2")); 1384 EXPECT_TRUE(llvm::is_contained(Features, "+sve-aes")); 1385 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-aes")); 1386 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sm4")); 1387 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-sha3")); 1388 EXPECT_TRUE(llvm::is_contained(Features, "+sve-bitperm")); 1389 EXPECT_TRUE(llvm::is_contained(Features, "+sve2-bitperm")); 1390 EXPECT_TRUE(llvm::is_contained(Features, "+ssve-bitperm")); 1391 EXPECT_TRUE(llvm::is_contained(Features, "+sve-aes2")); 1392 EXPECT_TRUE(llvm::is_contained(Features, "+ssve-aes")); 1393 EXPECT_TRUE(llvm::is_contained(Features, "+sve2p1")); 1394 EXPECT_TRUE(llvm::is_contained(Features, "+sve2p2")); 1395 EXPECT_TRUE(llvm::is_contained(Features, "+rcpc")); 1396 EXPECT_TRUE(llvm::is_contained(Features, "+rand")); 1397 EXPECT_TRUE(llvm::is_contained(Features, "+mte")); 1398 EXPECT_TRUE(llvm::is_contained(Features, "+ssbs")); 1399 EXPECT_TRUE(llvm::is_contained(Features, "+sb")); 1400 EXPECT_TRUE(llvm::is_contained(Features, "+predres")); 1401 EXPECT_TRUE(llvm::is_contained(Features, "+bf16")); 1402 EXPECT_TRUE(llvm::is_contained(Features, "+i8mm")); 1403 EXPECT_TRUE(llvm::is_contained(Features, "+f32mm")); 1404 EXPECT_TRUE(llvm::is_contained(Features, "+f64mm")); 1405 EXPECT_TRUE(llvm::is_contained(Features, "+tme")); 1406 EXPECT_TRUE(llvm::is_contained(Features, "+ls64")); 1407 EXPECT_TRUE(llvm::is_contained(Features, "+brbe")); 1408 EXPECT_TRUE(llvm::is_contained(Features, "+pauth")); 1409 EXPECT_TRUE(llvm::is_contained(Features, "+flagm")); 1410 EXPECT_TRUE(llvm::is_contained(Features, "+sme")); 1411 EXPECT_TRUE(llvm::is_contained(Features, "+sme-f64f64")); 1412 EXPECT_TRUE(llvm::is_contained(Features, "+sme-i16i64")); 1413 EXPECT_TRUE(llvm::is_contained(Features, "+sme-f16f16")); 1414 EXPECT_TRUE(llvm::is_contained(Features, "+sme2")); 1415 EXPECT_TRUE(llvm::is_contained(Features, "+sme-b16b16")); 1416 EXPECT_TRUE(llvm::is_contained(Features, "+sme2p1")); 1417 EXPECT_TRUE(llvm::is_contained(Features, "+sme2p2")); 1418 EXPECT_TRUE(llvm::is_contained(Features, "+hbc")); 1419 EXPECT_TRUE(llvm::is_contained(Features, "+mops")); 1420 EXPECT_TRUE(llvm::is_contained(Features, "+perfmon")); 1421 EXPECT_TRUE(llvm::is_contained(Features, "+cssc")); 1422 EXPECT_TRUE(llvm::is_contained(Features, "+rcpc3")); 1423 EXPECT_TRUE(llvm::is_contained(Features, "+the")); 1424 EXPECT_TRUE(llvm::is_contained(Features, "+d128")); 1425 EXPECT_TRUE(llvm::is_contained(Features, "+lse128")); 1426 EXPECT_TRUE(llvm::is_contained(Features, "+specres2")); 1427 EXPECT_TRUE(llvm::is_contained(Features, "+ite")); 1428 EXPECT_TRUE(llvm::is_contained(Features, "+gcs")); 1429 EXPECT_TRUE(llvm::is_contained(Features, "+fp8")); 1430 EXPECT_TRUE(llvm::is_contained(Features, "+faminmax")); 1431 EXPECT_TRUE(llvm::is_contained(Features, "+fp8fma")); 1432 EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8fma")); 1433 EXPECT_TRUE(llvm::is_contained(Features, "+fp8dot2")); 1434 EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8dot2")); 1435 EXPECT_TRUE(llvm::is_contained(Features, "+fp8dot4")); 1436 EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8dot4")); 1437 EXPECT_TRUE(llvm::is_contained(Features, "+f8f32mm")); 1438 EXPECT_TRUE(llvm::is_contained(Features, "+f8f16mm")); 1439 EXPECT_TRUE(llvm::is_contained(Features, "+lut")); 1440 EXPECT_TRUE(llvm::is_contained(Features, "+sme-lutv2")); 1441 EXPECT_TRUE(llvm::is_contained(Features, "+sme-f8f16")); 1442 EXPECT_TRUE(llvm::is_contained(Features, "+sme-f8f32")); 1443 EXPECT_TRUE(llvm::is_contained(Features, "+sme-fa64")); 1444 EXPECT_TRUE(llvm::is_contained(Features, "+cpa")); 1445 EXPECT_TRUE(llvm::is_contained(Features, "+pauth-lr")); 1446 EXPECT_TRUE(llvm::is_contained(Features, "+tlbiw")); 1447 EXPECT_TRUE(llvm::is_contained(Features, "+jsconv")); 1448 EXPECT_TRUE(llvm::is_contained(Features, "+complxnum")); 1449 EXPECT_TRUE(llvm::is_contained(Features, "+lsfe")); 1450 EXPECT_TRUE(llvm::is_contained(Features, "+fprcvt")); 1451 EXPECT_TRUE(llvm::is_contained(Features, "+cmpbr")); 1452 EXPECT_TRUE(llvm::is_contained(Features, "+lsui")); 1453 EXPECT_TRUE(llvm::is_contained(Features, "+occmo")); 1454 EXPECT_TRUE(llvm::is_contained(Features, "+pcdphint")); 1455 EXPECT_TRUE(llvm::is_contained(Features, "+pops")); 1456 EXPECT_TRUE(llvm::is_contained(Features, "+sme-mop4")); 1457 EXPECT_TRUE(llvm::is_contained(Features, "+sme-tmop")); 1458 1459 // Assuming we listed every extension above, this should produce the same 1460 // result. 1461 std::vector<StringRef> AllFeatures; 1462 EXPECT_TRUE(AArch64::getExtensionFeatures(ExtVal, AllFeatures)); 1463 EXPECT_THAT(Features, ::testing::ContainerEq(AllFeatures)); 1464 } 1465 1466 TEST(TargetParserTest, AArch64ArchFeatures) { 1467 EXPECT_EQ(AArch64::ARMV8A.ArchFeature, "+v8a"); 1468 EXPECT_EQ(AArch64::ARMV8_1A.ArchFeature, "+v8.1a"); 1469 EXPECT_EQ(AArch64::ARMV8_2A.ArchFeature, "+v8.2a"); 1470 EXPECT_EQ(AArch64::ARMV8_3A.ArchFeature, "+v8.3a"); 1471 EXPECT_EQ(AArch64::ARMV8_4A.ArchFeature, "+v8.4a"); 1472 EXPECT_EQ(AArch64::ARMV8_5A.ArchFeature, "+v8.5a"); 1473 EXPECT_EQ(AArch64::ARMV8_6A.ArchFeature, "+v8.6a"); 1474 EXPECT_EQ(AArch64::ARMV8_7A.ArchFeature, "+v8.7a"); 1475 EXPECT_EQ(AArch64::ARMV8_8A.ArchFeature, "+v8.8a"); 1476 EXPECT_EQ(AArch64::ARMV8_9A.ArchFeature, "+v8.9a"); 1477 EXPECT_EQ(AArch64::ARMV9A.ArchFeature, "+v9a"); 1478 EXPECT_EQ(AArch64::ARMV9_1A.ArchFeature, "+v9.1a"); 1479 EXPECT_EQ(AArch64::ARMV9_2A.ArchFeature, "+v9.2a"); 1480 EXPECT_EQ(AArch64::ARMV9_3A.ArchFeature, "+v9.3a"); 1481 EXPECT_EQ(AArch64::ARMV9_4A.ArchFeature, "+v9.4a"); 1482 EXPECT_EQ(AArch64::ARMV9_5A.ArchFeature, "+v9.5a"); 1483 EXPECT_EQ(AArch64::ARMV9_6A.ArchFeature, "+v9.6a"); 1484 EXPECT_EQ(AArch64::ARMV8R.ArchFeature, "+v8r"); 1485 } 1486 1487 TEST(TargetParserTest, AArch64ArchPartialOrder) { 1488 for (const auto *A : AArch64::ArchInfos) { 1489 EXPECT_EQ(*A, *A); 1490 1491 // v8r has no relation to other valid architectures 1492 if (*A != AArch64::ARMV8R) { 1493 EXPECT_FALSE(A->implies(AArch64::ARMV8R)); 1494 EXPECT_FALSE(AArch64::ARMV8R.implies(*A)); 1495 } 1496 } 1497 1498 for (const auto *A : { 1499 &AArch64::ARMV8_1A, 1500 &AArch64::ARMV8_2A, 1501 &AArch64::ARMV8_3A, 1502 &AArch64::ARMV8_4A, 1503 &AArch64::ARMV8_5A, 1504 &AArch64::ARMV8_6A, 1505 &AArch64::ARMV8_7A, 1506 &AArch64::ARMV8_8A, 1507 &AArch64::ARMV8_9A, 1508 }) 1509 EXPECT_TRUE(A->implies(AArch64::ARMV8A)); 1510 1511 for (const auto *A : 1512 {&AArch64::ARMV9_1A, &AArch64::ARMV9_2A, &AArch64::ARMV9_3A, 1513 &AArch64::ARMV9_4A, &AArch64::ARMV9_5A, &AArch64::ARMV9_6A}) 1514 EXPECT_TRUE(A->implies(AArch64::ARMV9A)); 1515 1516 EXPECT_TRUE(AArch64::ARMV8_1A.implies(AArch64::ARMV8A)); 1517 EXPECT_TRUE(AArch64::ARMV8_2A.implies(AArch64::ARMV8_1A)); 1518 EXPECT_TRUE(AArch64::ARMV8_3A.implies(AArch64::ARMV8_2A)); 1519 EXPECT_TRUE(AArch64::ARMV8_4A.implies(AArch64::ARMV8_3A)); 1520 EXPECT_TRUE(AArch64::ARMV8_5A.implies(AArch64::ARMV8_4A)); 1521 EXPECT_TRUE(AArch64::ARMV8_6A.implies(AArch64::ARMV8_5A)); 1522 EXPECT_TRUE(AArch64::ARMV8_7A.implies(AArch64::ARMV8_6A)); 1523 EXPECT_TRUE(AArch64::ARMV8_8A.implies(AArch64::ARMV8_7A)); 1524 EXPECT_TRUE(AArch64::ARMV8_9A.implies(AArch64::ARMV8_8A)); 1525 1526 EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV9A)); 1527 EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV9_1A)); 1528 EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV9_2A)); 1529 EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV9_3A)); 1530 EXPECT_TRUE(AArch64::ARMV9_5A.implies(AArch64::ARMV9_4A)); 1531 EXPECT_TRUE(AArch64::ARMV9_6A.implies(AArch64::ARMV9_5A)); 1532 1533 EXPECT_TRUE(AArch64::ARMV9A.implies(AArch64::ARMV8_5A)); 1534 EXPECT_TRUE(AArch64::ARMV9_1A.implies(AArch64::ARMV8_6A)); 1535 EXPECT_TRUE(AArch64::ARMV9_2A.implies(AArch64::ARMV8_7A)); 1536 EXPECT_TRUE(AArch64::ARMV9_3A.implies(AArch64::ARMV8_8A)); 1537 EXPECT_TRUE(AArch64::ARMV9_4A.implies(AArch64::ARMV8_9A)); 1538 } 1539 1540 TEST(TargetParserTest, AArch64ArchExtFeature) { 1541 const char *ArchExt[][4] = { 1542 {"crc", "nocrc", "+crc", "-crc"}, 1543 {"crypto", "nocrypto", "+crypto", "-crypto"}, 1544 {"flagm", "noflagm", "+flagm", "-flagm"}, 1545 {"fp", "nofp", "+fp-armv8", "-fp-armv8"}, 1546 {"simd", "nosimd", "+neon", "-neon"}, 1547 {"fp16", "nofp16", "+fullfp16", "-fullfp16"}, 1548 {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"}, 1549 {"profile", "noprofile", "+spe", "-spe"}, 1550 {"ras", "noras", "+ras", "-ras"}, 1551 {"lse", "nolse", "+lse", "-lse"}, 1552 {"rdm", "nordm", "+rdm", "-rdm"}, 1553 {"sve", "nosve", "+sve", "-sve"}, 1554 {"sve-b16b16", "nosve-b16b16", "+sve-b16b16", "-sve-b16b16"}, 1555 {"sve-bfscale", "nosve-bfscale", "+sve-bfscale", "-sve-bfscale"}, 1556 {"sve-f16f32mm", "nosve-f16f32mm", "+sve-f16f32mm", "-sve-f16f32mm"}, 1557 {"sve2", "nosve2", "+sve2", "-sve2"}, 1558 {"sve-aes", "nosve-aes", "+sve-aes", "-sve-aes"}, 1559 {"sve2-aes", "nosve2-aes", "+sve2-aes", "-sve2-aes"}, 1560 {"sve2-sm4", "nosve2-sm4", "+sve2-sm4", "-sve2-sm4"}, 1561 {"sve2-sha3", "nosve2-sha3", "+sve2-sha3", "-sve2-sha3"}, 1562 {"sve2p1", "nosve2p1", "+sve2p1", "-sve2p1"}, 1563 {"sve2p2", "nosve2p2", "+sve2p2", "-sve2p2"}, 1564 {"sve-bitperm", "nosve-bitperm", "+sve-bitperm", "-sve-bitperm"}, 1565 {"ssve-bitperm", "nossve-bitperm", "+ssve-bitperm", "-ssve-bitperm"}, 1566 {"sve2-bitperm", "nosve2-bitperm", "+sve2-bitperm", "-sve2-bitperm"}, 1567 {"sve-aes2", "nosve-aes2", "+sve-aes2", "-sve-aes2"}, 1568 {"ssve-aes", "nossve-aes", "+ssve-aes", "-ssve-aes"}, 1569 {"dotprod", "nodotprod", "+dotprod", "-dotprod"}, 1570 {"rcpc", "norcpc", "+rcpc", "-rcpc"}, 1571 {"rng", "norng", "+rand", "-rand"}, 1572 {"memtag", "nomemtag", "+mte", "-mte"}, 1573 {"tme", "notme", "+tme", "-tme"}, 1574 {"pauth", "nopauth", "+pauth", "-pauth"}, 1575 {"ssbs", "nossbs", "+ssbs", "-ssbs"}, 1576 {"sb", "nosb", "+sb", "-sb"}, 1577 {"predres", "nopredres", "+predres", "-predres"}, 1578 {"i8mm", "noi8mm", "+i8mm", "-i8mm"}, 1579 {"f32mm", "nof32mm", "+f32mm", "-f32mm"}, 1580 {"f64mm", "nof64mm", "+f64mm", "-f64mm"}, 1581 {"f8f32mm", "nof8f32mm", "+f8f32mm", "-f8f32mm"}, 1582 {"f8f16mm", "nof8f16mm", "+f8f16mm", "-f8f16mm"}, 1583 {"sme", "nosme", "+sme", "-sme"}, 1584 {"sme-fa64", "nosme-fa64", "+sme-fa64", "-sme-fa64"}, 1585 {"sme-f64f64", "nosme-f64f64", "+sme-f64f64", "-sme-f64f64"}, 1586 {"sme-i16i64", "nosme-i16i64", "+sme-i16i64", "-sme-i16i64"}, 1587 {"sme-f16f16", "nosme-f16f16", "+sme-f16f16", "-sme-f16f16"}, 1588 {"sme2", "nosme2", "+sme2", "-sme2"}, 1589 {"sme-b16b16", "nosme-b16b16", "+sme-b16b16", "-sme-b16b16"}, 1590 {"sme2p1", "nosme2p1", "+sme2p1", "-sme2p1"}, 1591 {"sme2p2", "nosme2p2", "+sme2p2", "-sme2p2"}, 1592 {"hbc", "nohbc", "+hbc", "-hbc"}, 1593 {"mops", "nomops", "+mops", "-mops"}, 1594 {"pmuv3", "nopmuv3", "+perfmon", "-perfmon"}, 1595 {"predres2", "nopredres2", "+specres2", "-specres2"}, 1596 {"rasv2", "norasv2", "+rasv2", "-rasv2"}, 1597 {"gcs", "nogcs", "+gcs", "-gcs"}, 1598 {"fp8", "nofp8", "+fp8", "-fp8"}, 1599 {"faminmax", "nofaminmax", "+faminmax", "-faminmax"}, 1600 {"fp8fma", "nofp8fma", "+fp8fma", "-fp8fma"}, 1601 {"ssve-fp8fma", "nossve-fp8fma", "+ssve-fp8fma", "-ssve-fp8fma"}, 1602 {"fp8dot2", "nofp8dot2", "+fp8dot2", "-fp8dot2"}, 1603 {"ssve-fp8dot2", "nossve-fp8dot2", "+ssve-fp8dot2", "-ssve-fp8dot2"}, 1604 {"fp8dot4", "nofp8dot4", "+fp8dot4", "-fp8dot4"}, 1605 {"ssve-fp8dot4", "nossve-fp8dot4", "+ssve-fp8dot4", "-ssve-fp8dot4"}, 1606 {"lut", "nolut", "+lut", "-lut"}, 1607 {"sme-lutv2", "nosme-lutv2", "+sme-lutv2", "-sme-lutv2"}, 1608 {"sme-f8f16", "nosme-f8f16", "+sme-f8f16", "-sme-f8f16"}, 1609 {"sme-f8f32", "nosme-f8f32", "+sme-f8f32", "-sme-f8f32"}, 1610 {"lsfe", "nolsfe", "+lsfe", "-lsfe"}, 1611 {"fprcvt", "nofprcvt", "+fprcvt", "-fprcvt"}, 1612 {"cmpbr", "nocmpbr", "+cmpbr", "-cmpbr"}, 1613 {"lsui", "nolsui", "+lsui", "-lsui"}, 1614 {"occmo", "nooccmo", "+occmo", "-occmo"}, 1615 {"pcdphint", "nopcdphint", "+pcdphint", "-pcdphint"}, 1616 {"pops", "nopops", "+pops", "-pops"}, 1617 {"sme-mop4", "nosme-mop4", "+sme-mop4", "-sme-mop4"}, 1618 {"sme-tmop", "nosme-tmop", "+sme-tmop", "-sme-tmop"}, 1619 }; 1620 1621 for (unsigned i = 0; i < std::size(ArchExt); i++) { 1622 EXPECT_EQ(StringRef(ArchExt[i][2]), 1623 AArch64::getArchExtFeature(ArchExt[i][0])); 1624 EXPECT_EQ(StringRef(ArchExt[i][3]), 1625 AArch64::getArchExtFeature(ArchExt[i][1])); 1626 } 1627 } 1628 1629 TEST(TargetParserTest, AArch64PrintSupportedExtensions) { 1630 std::string expected = "All available -march extensions for AArch64\n\n" 1631 " Name Architecture Feature(s) " 1632 " Description\n"; 1633 1634 outs().flush(); 1635 testing::internal::CaptureStdout(); 1636 AArch64::PrintSupportedExtensions(); 1637 outs().flush(); 1638 std::string captured = testing::internal::GetCapturedStdout(); 1639 1640 // Check that the start of the output is as expected. 1641 EXPECT_EQ(0ULL, captured.find(expected)); 1642 1643 // Should not include "none". 1644 EXPECT_EQ(std::string::npos, captured.find("none")); 1645 // Should not include anything that lacks a feature name. Checking a few here 1646 // but not all as if one is hidden correctly the rest should be. 1647 EXPECT_EQ(std::string::npos, captured.find("memtag3")); 1648 EXPECT_EQ(std::string::npos, captured.find("sha1")); 1649 EXPECT_EQ(std::string::npos, captured.find("ssbs2")); 1650 } 1651 1652 struct AArch64ExtensionDependenciesBaseArchTestParams { 1653 const llvm::AArch64::ArchInfo &Arch; 1654 std::vector<StringRef> Modifiers; 1655 std::vector<StringRef> ExpectedPos; 1656 std::vector<StringRef> ExpectedNeg; 1657 }; 1658 1659 class AArch64ExtensionDependenciesBaseArchTestFixture 1660 : public ::testing::TestWithParam< 1661 AArch64ExtensionDependenciesBaseArchTestParams> {}; 1662 1663 struct AArch64ExtensionDependenciesBaseCPUTestParams { 1664 StringRef CPUName; 1665 std::vector<StringRef> Modifiers; 1666 std::vector<StringRef> ExpectedPos; 1667 std::vector<StringRef> ExpectedNeg; 1668 }; 1669 1670 class AArch64ExtensionDependenciesBaseCPUTestFixture 1671 : public ::testing::TestWithParam< 1672 AArch64ExtensionDependenciesBaseCPUTestParams> {}; 1673 1674 TEST_P(AArch64ExtensionDependenciesBaseArchTestFixture, 1675 AArch64ExtensionDependenciesBaseArch) { 1676 auto Params = GetParam(); 1677 1678 llvm::AArch64::ExtensionSet Extensions; 1679 Extensions.addArchDefaults(Params.Arch); 1680 for (auto M : Params.Modifiers) { 1681 bool success = Extensions.parseModifier(M); 1682 EXPECT_TRUE(success); 1683 } 1684 std::vector<StringRef> Features; 1685 Extensions.toLLVMFeatureList(Features); 1686 1687 for (auto E : Params.ExpectedPos) { 1688 std::string PosString = "+"; 1689 PosString += E; 1690 std::string NegString = "-"; 1691 NegString += E; 1692 ASSERT_THAT(Features, Contains(StrEq(PosString))); 1693 ASSERT_THAT(Features, Not(Contains(StrEq(NegString)))); 1694 } 1695 1696 for (auto E : Params.ExpectedNeg) { 1697 std::string PosString = "+"; 1698 PosString += E; 1699 ASSERT_THAT(Features, Not(Contains(StrEq(PosString)))); 1700 // Features default to off, so the negative string is not expected in many 1701 // cases. 1702 } 1703 } 1704 1705 TEST_P(AArch64ExtensionDependenciesBaseCPUTestFixture, 1706 AArch64ExtensionDependenciesBaseCPU) { 1707 auto Params = GetParam(); 1708 1709 llvm::AArch64::ExtensionSet Extensions; 1710 const std::optional<llvm::AArch64::CpuInfo> CPU = 1711 llvm::AArch64::parseCpu(Params.CPUName); 1712 EXPECT_TRUE(CPU); 1713 Extensions.addCPUDefaults(*CPU); 1714 for (auto M : Params.Modifiers) { 1715 bool success = Extensions.parseModifier(M); 1716 EXPECT_TRUE(success); 1717 } 1718 std::vector<StringRef> Features; 1719 Extensions.toLLVMFeatureList(Features); 1720 1721 for (auto E : Params.ExpectedPos) { 1722 std::string PosString = "+"; 1723 PosString += E; 1724 std::string NegString = "-"; 1725 NegString += E; 1726 ASSERT_THAT(Features, Contains(StrEq(PosString))); 1727 ASSERT_THAT(Features, Not(Contains(StrEq(NegString)))); 1728 } 1729 1730 for (auto E : Params.ExpectedNeg) { 1731 std::string PosString = "+"; 1732 PosString += E; 1733 ASSERT_THAT(Features, Not(Contains(StrEq(PosString)))); 1734 // Features default to off, so the negative string is not expected in many 1735 // cases. 1736 } 1737 } 1738 1739 AArch64ExtensionDependenciesBaseArchTestParams 1740 AArch64ExtensionDependenciesArchData[] = { 1741 // Base architecture features 1742 {AArch64::ARMV8A, {}, {"v8a", "fp-armv8", "neon"}, {}}, 1743 {AArch64::ARMV8_1A, 1744 {}, 1745 {"v8.1a", "crc", "fp-armv8", "lse", "rdm", "neon"}, 1746 {}}, 1747 {AArch64::ARMV9_5A, {}, {"v9.5a", "mops", "cpa"}, {}}, 1748 1749 // Positive modifiers 1750 {AArch64::ARMV8A, {"fp16"}, {"fullfp16"}, {}}, 1751 {AArch64::ARMV8A, {"dotprod"}, {"dotprod"}, {}}, 1752 1753 // Negative modifiers 1754 {AArch64::ARMV8A, {"nofp"}, {"v8a"}, {"fp-armv8", "neon"}}, 1755 1756 // Mixed modifiers 1757 {AArch64::ARMV8A, 1758 {"fp16", "nofp16"}, 1759 {"v8a", "fp-armv8", "neon"}, 1760 {"fullfp16"}}, 1761 {AArch64::ARMV8A, 1762 {"fp16", "nofp"}, 1763 {"v8a"}, 1764 {"fp-armv8", "neon", "fullfp16"}}, 1765 1766 // Long dependency chains: sve2-bitperm -> sve2 -> sve -> fp16 -> fp 1767 {AArch64::ARMV8A, 1768 {"nofp", "sve2", "sve-bitperm"}, 1769 {"fp-armv8", "fullfp16", "sve", "sve2", "sve-bitperm"}, 1770 {}}, 1771 {AArch64::ARMV8A, 1772 {"sve2", "sve-bitperm", "nofp16"}, 1773 {"fp-armv8"}, 1774 {"full-fp16", "sve", "sve2", "sve-bitperm"}}, 1775 1776 // Meaning of +crypto varies with base architecture. 1777 {AArch64::ARMV8A, {"crypto"}, {"aes", "sha2"}, {}}, 1778 {AArch64::ARMV8_4A, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}}, 1779 {AArch64::ARMV9A, {"crypto"}, {"aes", "sha2", "sha3", "sm4"}, {}}, 1780 1781 // -crypto always disables all crypto features, even if it wouldn't 1782 // enable them. 1783 {AArch64::ARMV8A, 1784 {"aes", "sha2", "sha3", "sm4", "nocrypto"}, 1785 {}, 1786 {"aes", "sha2", "sha3", "sm4"}}, 1787 {AArch64::ARMV8_4A, 1788 {"aes", "sha2", "sha3", "sm4", "nocrypto"}, 1789 {}, 1790 {"aes", "sha2", "sha3", "sm4"}}, 1791 1792 // +fp16 implies +fp16fml for v8.4A+, but not v9.0-A+ 1793 {AArch64::ARMV8_3A, {"fp16"}, {"fullfp16"}, {"fp16fml"}}, 1794 {AArch64::ARMV9A, {"fp16"}, {"fullfp16"}, {"fp16fml"}}, 1795 {AArch64::ARMV8_4A, {"fp16"}, {"fullfp16", "fp16fml"}, {}}, 1796 1797 // fp -> fp16 1798 {AArch64::ARMV8A, {"nofp", "fp16"}, {"fp-armv8", "fullfp16"}, {}}, 1799 {AArch64::ARMV8A, {"fp16", "nofp"}, {}, {"fp-armv8", "fullfp16"}}, 1800 1801 // fp -> simd 1802 {AArch64::ARMV8A, {"nofp", "simd"}, {"fp-armv8", "neon"}, {}}, 1803 {AArch64::ARMV8A, {"simd", "nofp"}, {}, {"fp-armv8", "neon"}}, 1804 1805 // fp -> jscvt 1806 {AArch64::ARMV8A, {"nofp", "jscvt"}, {"fp-armv8", "jsconv"}, {}}, 1807 {AArch64::ARMV8A, {"jscvt", "nofp"}, {}, {"fp-armv8", "jsconv"}}, 1808 1809 // fp -> lsfe 1810 {AArch64::ARMV9_6A, {"nofp", "lsfe"}, {"fp-armv8", "lsfe"}, {}}, 1811 {AArch64::ARMV9_6A, {"lsfe", "nofp"}, {}, {"fp-armv8", "lsfe"}}, 1812 1813 // fp -> fprcvt 1814 {AArch64::ARMV9_6A, {"nofp", "fprcvt"}, {"fp-armv8", "fprcvt"}, {}}, 1815 {AArch64::ARMV9_6A, {"fprcvt", "nofp"}, {}, {"fp-armv8", "fprcvt"}}, 1816 1817 // simd -> {aes, sha2, sha3, sm4, f8f16mm, f8f32mm, fp8dot4, fp8dot2} 1818 {AArch64::ARMV8A, {"nosimd", "aes"}, {"neon", "aes"}, {}}, 1819 {AArch64::ARMV8A, {"aes", "nosimd"}, {}, {"neon", "aes"}}, 1820 {AArch64::ARMV8A, {"nosimd", "sha2"}, {"neon", "sha2"}, {}}, 1821 {AArch64::ARMV8A, {"sha2", "nosimd"}, {}, {"neon", "sha2"}}, 1822 {AArch64::ARMV8A, {"nosimd", "sha3"}, {"neon", "sha3"}, {}}, 1823 {AArch64::ARMV8A, {"sha3", "nosimd"}, {}, {"neon", "sha3"}}, 1824 {AArch64::ARMV8A, {"nosimd", "sm4"}, {"neon", "sm4"}, {}}, 1825 {AArch64::ARMV8A, {"sm4", "nosimd"}, {}, {"neon", "sm4"}}, 1826 {AArch64::ARMV9_6A, {"nosimd", "f8f16mm"}, {"neon", "f8f16mm"}, {}}, 1827 {AArch64::ARMV9_6A, {"f8f16mm", "nosimd"}, {}, {"neon", "f8f16mm"}}, 1828 {AArch64::ARMV9_6A, {"nosimd", "f8f32mm"}, {"neon", "f8f32mm"}, {}}, 1829 {AArch64::ARMV9_6A, {"f8f32mm", "nosimd"}, {}, {"neon", "f8f32mm"}}, 1830 {AArch64::ARMV9_6A, {"nosimd", "fp8dot4"}, {"neon", "fp8dot4"}, {}}, 1831 {AArch64::ARMV9_6A, {"fp8dot4", "nosimd"}, {}, {"neon", "fp8dot4"}}, 1832 {AArch64::ARMV9_6A, {"nosimd", "fp8dot2"}, {"neon", "fp8dot2"}, {}}, 1833 {AArch64::ARMV9_6A, {"fp8dot2", "nosimd"}, {}, {"neon", "fp8dot2"}}, 1834 1835 // simd -> {rdm, dotprod, fcma} 1836 {AArch64::ARMV8A, {"nosimd", "rdm"}, {"neon", "rdm"}, {}}, 1837 {AArch64::ARMV8A, {"rdm", "nosimd"}, {}, {"neon", "rdm"}}, 1838 {AArch64::ARMV8A, {"nosimd", "dotprod"}, {"neon", "dotprod"}, {}}, 1839 {AArch64::ARMV8A, {"dotprod", "nosimd"}, {}, {"neon", "dotprod"}}, 1840 {AArch64::ARMV8A, {"nosimd", "fcma"}, {"neon", "complxnum"}, {}}, 1841 {AArch64::ARMV8A, {"fcma", "nosimd"}, {}, {"neon", "complxnum"}}, 1842 1843 // fp16 -> {fp16fml, sve} 1844 {AArch64::ARMV8A, {"nofp16", "fp16fml"}, {"fullfp16", "fp16fml"}, {}}, 1845 {AArch64::ARMV8A, {"fp16fml", "nofp16"}, {}, {"fullfp16", "fp16fml"}}, 1846 {AArch64::ARMV8A, {"nofp16", "sve"}, {"fullfp16", "sve"}, {}}, 1847 {AArch64::ARMV8A, {"sve", "nofp16"}, {}, {"fullfp16", "sve"}}, 1848 1849 // bf16 -> {sme} 1850 {AArch64::ARMV8A, {"nobf16", "sme"}, {"bf16", "sme"}, {}}, 1851 {AArch64::ARMV8A, {"sme", "nobf16"}, {}, {"bf16", "sme"}}, 1852 1853 // sve -> {sve2, f32mm, f64mm, sve-f16f32mm} 1854 {AArch64::ARMV8A, {"nosve", "sve2"}, {"sve", "sve2"}, {}}, 1855 {AArch64::ARMV8A, {"sve2", "nosve"}, {}, {"sve", "sve2"}}, 1856 {AArch64::ARMV8A, {"nosve", "f32mm"}, {"sve", "f32mm"}, {}}, 1857 {AArch64::ARMV8A, {"f32mm", "nosve"}, {}, {"sve", "f32mm"}}, 1858 {AArch64::ARMV8A, {"nosve", "f64mm"}, {"sve", "f64mm"}, {}}, 1859 {AArch64::ARMV8A, {"f64mm", "nosve"}, {}, {"sve", "f64mm"}}, 1860 {AArch64::ARMV9_6A, 1861 {"nosve", "sve-f16f32mm"}, 1862 {"sve", "sve-f16f32mm"}, 1863 {}}, 1864 {AArch64::ARMV9_6A, 1865 {"sve-f16f32mm", "nosve"}, 1866 {}, 1867 {"sve", "sve-f16f32mm"}}, 1868 1869 // aes -> {sve-aes} 1870 {AArch64::ARMV8A, {"noaes", "sve-aes"}, {"aes", "sve-aes"}, {}}, 1871 {AArch64::ARMV8A, {"sve-aes", "noaes"}, {}, {"aes", "sve-aes"}}, 1872 1873 // sve2 -> {sve2p1, sve2-bitperm, sve2-sha3, sve2-sm4, sve2-aes} 1874 {AArch64::ARMV8A, {"nosve2", "sve2p1"}, {"sve2", "sve2p1"}, {}}, 1875 {AArch64::ARMV8A, {"sve2p1", "nosve2"}, {}, {"sve2", "sve2p1"}}, 1876 {AArch64::ARMV8A, 1877 {"nosve2", "sve2-bitperm"}, 1878 {"sve2", "sve-bitperm"}, 1879 {}}, 1880 {AArch64::ARMV8A, 1881 {"sve2-bitperm", "nosve2"}, 1882 {"sve"}, 1883 {"sve-bitperm", "sve2", "sve2-bitperm"}}, 1884 {AArch64::ARMV8A, 1885 {"ssve-bitperm", "nosve-bitperm"}, 1886 {"sme"}, 1887 {"ssve-bitperm", "sve-bitperm"}}, 1888 {AArch64::ARMV8A, 1889 {"nosve-bitperm", "ssve-bitperm"}, 1890 {"sve-bitperm", "sve-bitperm"}, 1891 {""}}, 1892 {AArch64::ARMV8A, {"nosve2", "sve2-sha3"}, {"sve2", "sve2-sha3"}, {}}, 1893 {AArch64::ARMV8A, {"sve2-sha3", "nosve2"}, {}, {"sve2", "sve2-sha3"}}, 1894 {AArch64::ARMV8A, {"nosve2", "sve2-sm4"}, {"sve2", "sve2-sm4"}, {}}, 1895 {AArch64::ARMV8A, {"sve2-sm4", "nosve2"}, {}, {"sve2", "sve2-sm4"}}, 1896 {AArch64::ARMV8A, {"nosve2", "sve2-aes"}, {"sve2", "sve2-aes"}, {}}, 1897 {AArch64::ARMV8A, {"sve2-aes", "nosve2"}, {}, {"sve2", "sve2-aes"}}, 1898 1899 // sve-b16b16 -> {sme-b16b16} 1900 {AArch64::ARMV9_4A, 1901 {"nosve-b16b16", "sme-b16b16"}, 1902 {"sve-b16b16", "sme-b16b16"}, 1903 {}}, 1904 {AArch64::ARMV9_4A, 1905 {"sme-b16b16", "nosve-b16b16"}, 1906 {}, 1907 {"sve-b16b16", "sme-b16b16"}}, 1908 1909 // sve2p1 -> {sve2p2} 1910 {AArch64::ARMV9_6A, {"nosve2p1", "sve2p2"}, {"sve2p1", "sve2p2"}, {}}, 1911 {AArch64::ARMV9_6A, {"sve2p2", "nosve2p1"}, {}, {"sve2p1", "sve2p2"}}, 1912 1913 // sme -> {sme2, sme-f16f16, sme-f64f64, sme-i16i64, sme-fa64} 1914 {AArch64::ARMV8A, {"nosme", "sme2"}, {"sme", "sme2"}, {}}, 1915 {AArch64::ARMV8A, {"sme2", "nosme"}, {}, {"sme", "sme2"}}, 1916 {AArch64::ARMV8A, {"nosme", "sme-f16f16"}, {"sme", "sme-f16f16"}, {}}, 1917 {AArch64::ARMV8A, {"sme-f16f16", "nosme"}, {}, {"sme", "sme-f16f16"}}, 1918 {AArch64::ARMV8A, {"nosme", "sme-f64f64"}, {"sme", "sme-f64f64"}, {}}, 1919 {AArch64::ARMV8A, {"sme-f64f64", "nosme"}, {}, {"sme", "sme-f64f64"}}, 1920 {AArch64::ARMV8A, {"nosme", "sme-i16i64"}, {"sme", "sme-i16i64"}, {}}, 1921 {AArch64::ARMV8A, {"sme-i16i64", "nosme"}, {}, {"sme", "sme-i16i64"}}, 1922 {AArch64::ARMV8A, {"nosme", "sme-fa64"}, {"sme", "sme-fa64"}, {}}, 1923 {AArch64::ARMV8A, {"sme-fa64", "nosme"}, {}, {"sme", "sme-fa64"}}, 1924 1925 // sme2 -> {sme2p1, ssve-fp8fma, ssve-fp8dot2, ssve-fp8dot4, sme-f8f16, 1926 // sme-f8f32, sme-b16b16, ssve-aes} 1927 {AArch64::ARMV8A, {"nosme2", "sme2p1"}, {"sme2", "sme2p1"}, {}}, 1928 {AArch64::ARMV8A, {"sme2p1", "nosme2"}, {}, {"sme2", "sme2p1"}}, 1929 {AArch64::ARMV8A, 1930 {"nosme2", "ssve-fp8fma"}, 1931 {"sme2", "ssve-fp8fma"}, 1932 {}}, 1933 {AArch64::ARMV8A, 1934 {"ssve-fp8fma", "nosme2"}, 1935 {}, 1936 {"sme2", "ssve-fp8fma"}}, 1937 {AArch64::ARMV8A, 1938 {"nosme2", "ssve-fp8dot2"}, 1939 {"sme2", "ssve-fp8dot2"}, 1940 {}}, 1941 {AArch64::ARMV8A, 1942 {"ssve-fp8dot2", "nosme2"}, 1943 {}, 1944 {"sme2", "ssve-fp8dot2"}}, 1945 {AArch64::ARMV8A, 1946 {"nosme2", "ssve-fp8dot4"}, 1947 {"sme2", "ssve-fp8dot4"}, 1948 {}}, 1949 {AArch64::ARMV8A, 1950 {"ssve-fp8dot4", "nosme2"}, 1951 {}, 1952 {"sme2", "ssve-fp8dot4"}}, 1953 {AArch64::ARMV8A, {"nosme2", "sme-f8f16"}, {"sme2", "sme-f8f16"}, {}}, 1954 {AArch64::ARMV8A, {"sme-f8f16", "nosme2"}, {}, {"sme2", "sme-f8f16"}}, 1955 {AArch64::ARMV8A, {"nosme2", "sme-f8f32"}, {"sme2", "sme-f8f32"}, {}}, 1956 {AArch64::ARMV8A, {"sme-f8f32", "nosme2"}, {}, {"sme2", "sme-f8f32"}}, 1957 {AArch64::ARMV8A, {"nosme2", "sme-b16b16"}, {"sme2", "sme-b16b16"}, {}}, 1958 {AArch64::ARMV8A, {"sme-b16b16", "nosme2"}, {}, {"sme2", "sme-b16b16"}}, 1959 {AArch64::ARMV9_6A, {"nosme2", "ssve-aes"}, {"sme2", "ssve-aes"}, {}}, 1960 {AArch64::ARMV9_6A, {"ssve-aes", "nosme2"}, {}, {"ssve-aes", "sme2"}}, 1961 1962 // sme2p1 -> {sme2p2} 1963 {AArch64::ARMV9_6A, {"nosme2p1", "sme2p2"}, {"sme2p2", "sme2p1"}, {}}, 1964 {AArch64::ARMV9_6A, {"sme2p2", "nosme2p1"}, {}, {"sme2p1", "sme2p2"}}, 1965 1966 // fp8 -> {sme-f8f16, sme-f8f32, f8f16mm, f8f32mm, fp8dot4, fp8dot2, 1967 // ssve-fp8dot4, ssve-fp8dot2} 1968 {AArch64::ARMV8A, {"nofp8", "sme-f8f16"}, {"fp8", "sme-f8f16"}, {}}, 1969 {AArch64::ARMV8A, {"sme-f8f16", "nofp8"}, {}, {"fp8", "sme-f8f16"}}, 1970 {AArch64::ARMV8A, {"nofp8", "sme-f8f32"}, {"fp8", "sme-f8f32"}, {}}, 1971 {AArch64::ARMV8A, {"sme-f8f32", "nofp8"}, {}, {"fp8", "sme-f8f32"}}, 1972 {AArch64::ARMV9_6A, {"nofp8", "f8f16mm"}, {"fp8", "f8f16mm"}, {}}, 1973 {AArch64::ARMV9_6A, {"f8f16mm", "nofp8"}, {}, {"fp8", "f8f16mm"}}, 1974 {AArch64::ARMV9_6A, {"nofp8", "f8f32mm"}, {"fp8", "f8f32mm"}, {}}, 1975 {AArch64::ARMV9_6A, {"f8f32mm", "nofp8"}, {}, {"fp8", "f8f32mm"}}, 1976 {AArch64::ARMV9_6A, {"nofp8", "fp8dot4"}, {"fp8", "fp8dot4"}, {}}, 1977 {AArch64::ARMV9_6A, {"fp8dot4", "nofp8"}, {}, {"fp8", "fp8dot4"}}, 1978 {AArch64::ARMV9_6A, {"nofp8", "fp8dot2"}, {"fp8", "fp8dot2"}, {}}, 1979 {AArch64::ARMV9_6A, {"fp8dot2", "nofp8"}, {}, {"fp8", "fp8dot2"}}, 1980 {AArch64::ARMV9_6A, 1981 {"nofp8", "ssve-fp8dot4"}, 1982 {"fp8", "ssve-fp8dot4"}, 1983 {}}, 1984 {AArch64::ARMV9_6A, 1985 {"ssve-fp8dot4", "nofp8"}, 1986 {}, 1987 {"fp8", "ssve-fp8dot4"}}, 1988 {AArch64::ARMV9_6A, 1989 {"nofp8", "ssve-fp8dot2"}, 1990 {"fp8", "ssve-fp8dot2"}, 1991 {}}, 1992 {AArch64::ARMV9_6A, 1993 {"ssve-fp8dot2", "nofp8"}, 1994 {}, 1995 {"fp8", "ssve-fp8dot2"}}, 1996 1997 // lse -> lse128 1998 {AArch64::ARMV8A, {"nolse", "lse128"}, {"lse", "lse128"}, {}}, 1999 {AArch64::ARMV8A, {"lse128", "nolse"}, {}, {"lse", "lse128"}}, 2000 2001 // predres -> predres2 2002 {AArch64::ARMV8A, 2003 {"nopredres", "predres2"}, 2004 {"predres", "specres2"}, 2005 {}}, 2006 {AArch64::ARMV8A, 2007 {"predres2", "nopredres"}, 2008 {}, 2009 {"predres", "specres2"}}, 2010 2011 // ras -> ras2 2012 {AArch64::ARMV8A, {"noras", "rasv2"}, {"ras", "rasv2"}, {}}, 2013 {AArch64::ARMV8A, {"rasv2", "noras"}, {}, {"ras", "rasv2"}}, 2014 2015 // rcpc -> rcpc3 2016 {AArch64::ARMV8A, {"norcpc", "rcpc3"}, {"rcpc", "rcpc3"}, {}}, 2017 {AArch64::ARMV8A, {"rcpc3", "norcpc"}, {}, {"rcpc", "rcpc3"}}, 2018 2019 // sve-aes -> {ssve-aes, sve2-aes} 2020 {AArch64::ARMV9_6A, 2021 {"nosve-aes", "ssve-aes"}, 2022 {"sve-aes", "ssve-aes"}, 2023 {}}, 2024 {AArch64::ARMV9_6A, 2025 {"ssve-aes", "nosve-aes"}, 2026 {}, 2027 {"ssve-aes", "sve-aes"}}, 2028 {AArch64::ARMV9_6A, 2029 {"nosve-aes", "sve2-aes"}, 2030 {"sve2-aes", "sve-aes"}, 2031 {}}, 2032 {AArch64::ARMV9_6A, 2033 {"sve2-aes", "nosve-aes"}, 2034 {}, 2035 {"sve2-aes", "sve-aes"}}, 2036 2037 // -sve2-aes should disable sve-aes (only) 2038 {AArch64::ARMV9_6A, 2039 {"sve2", "sve-aes", "nosve2-aes"}, 2040 {"sve2"}, 2041 {"sve2-aes", "sve-aes"}}, 2042 2043 // sme-tmop -> sme 2044 {AArch64::ARMV8A, {"nosme2", "sme-tmop"}, {"sme2", "sme-tmop"}, {}}, 2045 {AArch64::ARMV8A, {"sme-tmop", "nosme2"}, {}, {"sme2", "sme-tmop"}}, 2046 2047 // sme-mop4 -> sme 2048 {AArch64::ARMV8A, {"nosme", "sme-mop4"}, {"sme", "sme-mop4"}, {}}, 2049 {AArch64::ARMV8A, {"sme-mop4", "nosme"}, {}, {"sme", "sme-mop4"}}}; 2050 2051 INSTANTIATE_TEST_SUITE_P( 2052 AArch64ExtensionDependenciesBaseArch, 2053 AArch64ExtensionDependenciesBaseArchTestFixture, 2054 ::testing::ValuesIn(AArch64ExtensionDependenciesArchData)); 2055 2056 AArch64ExtensionDependenciesBaseCPUTestParams 2057 AArch64ExtensionDependenciesCPUData[] = { 2058 // Base CPU features 2059 {"cortex-a57", 2060 {}, 2061 {"v8a", "aes", "crc", "fp-armv8", "sha2", "neon"}, 2062 {}}, 2063 {"cortex-r82", 2064 {}, 2065 {"v8r", "crc", "dotprod", "fp-armv8", "fullfp16", "fp16fml", "lse", 2066 "ras", "rcpc", "rdm", "sb", "neon", "ssbs"}, 2067 {}}, 2068 {"cortex-a520", 2069 {}, 2070 {"v9.2a", "bf16", "crc", "dotprod", "flagm", "fp-armv8", 2071 "fullfp16", "fp16fml", "i8mm", "lse", "mte", "pauth", 2072 "perfmon", "predres", "ras", "rcpc", "rdm", "sb", 2073 "neon", "ssbs", "sve", "sve-bitperm", "sve2"}, 2074 {}}, 2075 2076 // Negative modifiers 2077 {"cortex-r82", 2078 {"nofp"}, 2079 {"v8r", "crc", "lse", "ras", "rcpc", "sb", "ssbs"}, 2080 {"fp-armv8", "neon", "fullfp16", "fp16fml", "dotprod", "rdm"}}, 2081 }; 2082 2083 INSTANTIATE_TEST_SUITE_P( 2084 AArch64ExtensionDependenciesBaseCPU, 2085 AArch64ExtensionDependenciesBaseCPUTestFixture, 2086 ::testing::ValuesIn(AArch64ExtensionDependenciesCPUData)); 2087 2088 } // namespace 2089