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