1 //===-- TargetParser - Parser for target features ---------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements a target parser to recognise hardware features such as 11 // FPU/CPU/ARCH names as well as specific support such as HDIV, etc. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/Support/ARMBuildAttributes.h" 16 #include "llvm/Support/TargetParser.h" 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/StringSwitch.h" 19 #include "llvm/ADT/Twine.h" 20 #include <cctype> 21 22 using namespace llvm; 23 using namespace ARM; 24 using namespace AArch64; 25 using namespace AMDGPU; 26 27 namespace { 28 29 // List of canonical FPU names (use getFPUSynonym) and which architectural 30 // features they correspond to (use getFPUFeatures). 31 // FIXME: TableGen this. 32 // The entries must appear in the order listed in ARM::FPUKind for correct indexing 33 static const struct { 34 const char *NameCStr; 35 size_t NameLength; 36 ARM::FPUKind ID; 37 ARM::FPUVersion FPUVersion; 38 ARM::NeonSupportLevel NeonSupport; 39 ARM::FPURestriction Restriction; 40 41 StringRef getName() const { return StringRef(NameCStr, NameLength); } 42 } FPUNames[] = { 43 #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \ 44 { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION }, 45 #include "llvm/Support/ARMTargetParser.def" 46 }; 47 48 // List of canonical arch names (use getArchSynonym). 49 // This table also provides the build attribute fields for CPU arch 50 // and Arch ID, according to the Addenda to the ARM ABI, chapters 51 // 2.4 and 2.3.5.2 respectively. 52 // FIXME: SubArch values were simplified to fit into the expectations 53 // of the triples and are not conforming with their official names. 54 // Check to see if the expectation should be changed. 55 // FIXME: TableGen this. 56 template <typename T> struct ArchNames { 57 const char *NameCStr; 58 size_t NameLength; 59 const char *CPUAttrCStr; 60 size_t CPUAttrLength; 61 const char *SubArchCStr; 62 size_t SubArchLength; 63 unsigned DefaultFPU; 64 unsigned ArchBaseExtensions; 65 T ID; 66 ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes. 67 68 StringRef getName() const { return StringRef(NameCStr, NameLength); } 69 70 // CPU class in build attributes. 71 StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); } 72 73 // Sub-Arch name. 74 StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); } 75 }; 76 ArchNames<ARM::ArchKind> ARCHNames[] = { 77 #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \ 78 {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \ 79 sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ARM::ArchKind::ID, ARCH_ATTR}, 80 #include "llvm/Support/ARMTargetParser.def" 81 }; 82 83 ArchNames<AArch64::ArchKind> AArch64ARCHNames[] = { 84 #define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \ 85 {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \ 86 sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, AArch64::ArchKind::ID, ARCH_ATTR}, 87 #include "llvm/Support/AArch64TargetParser.def" 88 }; 89 90 91 // List of Arch Extension names. 92 // FIXME: TableGen this. 93 static const struct { 94 const char *NameCStr; 95 size_t NameLength; 96 unsigned ID; 97 const char *Feature; 98 const char *NegFeature; 99 100 StringRef getName() const { return StringRef(NameCStr, NameLength); } 101 } ARCHExtNames[] = { 102 #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \ 103 { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE }, 104 #include "llvm/Support/ARMTargetParser.def" 105 },AArch64ARCHExtNames[] = { 106 #define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \ 107 { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE }, 108 #include "llvm/Support/AArch64TargetParser.def" 109 }; 110 111 // List of HWDiv names (use getHWDivSynonym) and which architectural 112 // features they correspond to (use getHWDivFeatures). 113 // FIXME: TableGen this. 114 static const struct { 115 const char *NameCStr; 116 size_t NameLength; 117 unsigned ID; 118 119 StringRef getName() const { return StringRef(NameCStr, NameLength); } 120 } HWDivNames[] = { 121 #define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID }, 122 #include "llvm/Support/ARMTargetParser.def" 123 }; 124 125 // List of CPU names and their arches. 126 // The same CPU can have multiple arches and can be default on multiple arches. 127 // When finding the Arch for a CPU, first-found prevails. Sort them accordingly. 128 // When this becomes table-generated, we'd probably need two tables. 129 // FIXME: TableGen this. 130 template <typename T> struct CpuNames { 131 const char *NameCStr; 132 size_t NameLength; 133 T ArchID; 134 bool Default; // is $Name the default CPU for $ArchID ? 135 unsigned DefaultExtensions; 136 137 StringRef getName() const { return StringRef(NameCStr, NameLength); } 138 }; 139 CpuNames<ARM::ArchKind> CPUNames[] = { 140 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 141 { NAME, sizeof(NAME) - 1, ARM::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT }, 142 #include "llvm/Support/ARMTargetParser.def" 143 }; 144 145 CpuNames<AArch64::ArchKind> AArch64CPUNames[] = { 146 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 147 { NAME, sizeof(NAME) - 1, AArch64::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT }, 148 #include "llvm/Support/AArch64TargetParser.def" 149 }; 150 151 } // namespace 152 153 // ======================================================= // 154 // Information by ID 155 // ======================================================= // 156 157 StringRef ARM::getFPUName(unsigned FPUKind) { 158 if (FPUKind >= ARM::FK_LAST) 159 return StringRef(); 160 return FPUNames[FPUKind].getName(); 161 } 162 163 FPUVersion ARM::getFPUVersion(unsigned FPUKind) { 164 if (FPUKind >= ARM::FK_LAST) 165 return FPUVersion::NONE; 166 return FPUNames[FPUKind].FPUVersion; 167 } 168 169 ARM::NeonSupportLevel ARM::getFPUNeonSupportLevel(unsigned FPUKind) { 170 if (FPUKind >= ARM::FK_LAST) 171 return ARM::NeonSupportLevel::None; 172 return FPUNames[FPUKind].NeonSupport; 173 } 174 175 ARM::FPURestriction ARM::getFPURestriction(unsigned FPUKind) { 176 if (FPUKind >= ARM::FK_LAST) 177 return ARM::FPURestriction::None; 178 return FPUNames[FPUKind].Restriction; 179 } 180 181 unsigned llvm::ARM::getDefaultFPU(StringRef CPU, ArchKind AK) { 182 if (CPU == "generic") 183 return ARCHNames[static_cast<unsigned>(AK)].DefaultFPU; 184 185 return StringSwitch<unsigned>(CPU) 186 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 187 .Case(NAME, DEFAULT_FPU) 188 #include "llvm/Support/ARMTargetParser.def" 189 .Default(ARM::FK_INVALID); 190 } 191 192 unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, ArchKind AK) { 193 if (CPU == "generic") 194 return ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions; 195 196 return StringSwitch<unsigned>(CPU) 197 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 198 .Case(NAME, ARCHNames[static_cast<unsigned>(ARM::ArchKind::ID)]\ 199 .ArchBaseExtensions | DEFAULT_EXT) 200 #include "llvm/Support/ARMTargetParser.def" 201 .Default(ARM::AEK_INVALID); 202 } 203 204 bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind, 205 std::vector<StringRef> &Features) { 206 207 if (HWDivKind == ARM::AEK_INVALID) 208 return false; 209 210 if (HWDivKind & ARM::AEK_HWDIVARM) 211 Features.push_back("+hwdiv-arm"); 212 else 213 Features.push_back("-hwdiv-arm"); 214 215 if (HWDivKind & ARM::AEK_HWDIVTHUMB) 216 Features.push_back("+hwdiv"); 217 else 218 Features.push_back("-hwdiv"); 219 220 return true; 221 } 222 223 bool llvm::ARM::getExtensionFeatures(unsigned Extensions, 224 std::vector<StringRef> &Features) { 225 226 if (Extensions == ARM::AEK_INVALID) 227 return false; 228 229 if (Extensions & ARM::AEK_CRC) 230 Features.push_back("+crc"); 231 else 232 Features.push_back("-crc"); 233 234 if (Extensions & ARM::AEK_DSP) 235 Features.push_back("+dsp"); 236 else 237 Features.push_back("-dsp"); 238 239 if (Extensions & ARM::AEK_FP16FML) 240 Features.push_back("+fp16fml"); 241 else 242 Features.push_back("-fp16fml"); 243 244 if (Extensions & ARM::AEK_RAS) 245 Features.push_back("+ras"); 246 else 247 Features.push_back("-ras"); 248 249 if (Extensions & ARM::AEK_DOTPROD) 250 Features.push_back("+dotprod"); 251 else 252 Features.push_back("-dotprod"); 253 254 return getHWDivFeatures(Extensions, Features); 255 } 256 257 bool llvm::ARM::getFPUFeatures(unsigned FPUKind, 258 std::vector<StringRef> &Features) { 259 260 if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID) 261 return false; 262 263 // fp-only-sp and d16 subtarget features are independent of each other, so we 264 // must enable/disable both. 265 switch (FPUNames[FPUKind].Restriction) { 266 case ARM::FPURestriction::SP_D16: 267 Features.push_back("+fp-only-sp"); 268 Features.push_back("+d16"); 269 break; 270 case ARM::FPURestriction::D16: 271 Features.push_back("-fp-only-sp"); 272 Features.push_back("+d16"); 273 break; 274 case ARM::FPURestriction::None: 275 Features.push_back("-fp-only-sp"); 276 Features.push_back("-d16"); 277 break; 278 } 279 280 // FPU version subtarget features are inclusive of lower-numbered ones, so 281 // enable the one corresponding to this version and disable all that are 282 // higher. We also have to make sure to disable fp16 when vfp4 is disabled, 283 // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16. 284 switch (FPUNames[FPUKind].FPUVersion) { 285 case ARM::FPUVersion::VFPV5: 286 Features.push_back("+fp-armv8"); 287 break; 288 case ARM::FPUVersion::VFPV4: 289 Features.push_back("+vfp4"); 290 Features.push_back("-fp-armv8"); 291 break; 292 case ARM::FPUVersion::VFPV3_FP16: 293 Features.push_back("+vfp3"); 294 Features.push_back("+fp16"); 295 Features.push_back("-vfp4"); 296 Features.push_back("-fp-armv8"); 297 break; 298 case ARM::FPUVersion::VFPV3: 299 Features.push_back("+vfp3"); 300 Features.push_back("-fp16"); 301 Features.push_back("-vfp4"); 302 Features.push_back("-fp-armv8"); 303 break; 304 case ARM::FPUVersion::VFPV2: 305 Features.push_back("+vfp2"); 306 Features.push_back("-vfp3"); 307 Features.push_back("-fp16"); 308 Features.push_back("-vfp4"); 309 Features.push_back("-fp-armv8"); 310 break; 311 case ARM::FPUVersion::NONE: 312 Features.push_back("-vfp2"); 313 Features.push_back("-vfp3"); 314 Features.push_back("-fp16"); 315 Features.push_back("-vfp4"); 316 Features.push_back("-fp-armv8"); 317 break; 318 } 319 320 // crypto includes neon, so we handle this similarly to FPU version. 321 switch (FPUNames[FPUKind].NeonSupport) { 322 case ARM::NeonSupportLevel::Crypto: 323 Features.push_back("+neon"); 324 Features.push_back("+crypto"); 325 break; 326 case ARM::NeonSupportLevel::Neon: 327 Features.push_back("+neon"); 328 Features.push_back("-crypto"); 329 break; 330 case ARM::NeonSupportLevel::None: 331 Features.push_back("-neon"); 332 Features.push_back("-crypto"); 333 break; 334 } 335 336 return true; 337 } 338 339 StringRef llvm::ARM::getArchName(ArchKind AK) { 340 return ARCHNames[static_cast<unsigned>(AK)].getName(); 341 } 342 343 StringRef llvm::ARM::getCPUAttr(ArchKind AK) { 344 return ARCHNames[static_cast<unsigned>(AK)].getCPUAttr(); 345 } 346 347 StringRef llvm::ARM::getSubArch(ArchKind AK) { 348 return ARCHNames[static_cast<unsigned>(AK)].getSubArch(); 349 } 350 351 unsigned llvm::ARM::getArchAttr(ArchKind AK) { 352 return ARCHNames[static_cast<unsigned>(AK)].ArchAttr; 353 } 354 355 StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) { 356 for (const auto AE : ARCHExtNames) { 357 if (ArchExtKind == AE.ID) 358 return AE.getName(); 359 } 360 return StringRef(); 361 } 362 363 StringRef llvm::ARM::getArchExtFeature(StringRef ArchExt) { 364 if (ArchExt.startswith("no")) { 365 StringRef ArchExtBase(ArchExt.substr(2)); 366 for (const auto AE : ARCHExtNames) { 367 if (AE.NegFeature && ArchExtBase == AE.getName()) 368 return StringRef(AE.NegFeature); 369 } 370 } 371 for (const auto AE : ARCHExtNames) { 372 if (AE.Feature && ArchExt == AE.getName()) 373 return StringRef(AE.Feature); 374 } 375 376 return StringRef(); 377 } 378 379 StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) { 380 for (const auto D : HWDivNames) { 381 if (HWDivKind == D.ID) 382 return D.getName(); 383 } 384 return StringRef(); 385 } 386 387 StringRef llvm::ARM::getDefaultCPU(StringRef Arch) { 388 ArchKind AK = parseArch(Arch); 389 if (AK == ARM::ArchKind::INVALID) 390 return StringRef(); 391 392 // Look for multiple AKs to find the default for pair AK+Name. 393 for (const auto CPU : CPUNames) { 394 if (CPU.ArchID == AK && CPU.Default) 395 return CPU.getName(); 396 } 397 398 // If we can't find a default then target the architecture instead 399 return "generic"; 400 } 401 402 StringRef llvm::AArch64::getFPUName(unsigned FPUKind) { 403 return ARM::getFPUName(FPUKind); 404 } 405 406 ARM::FPUVersion AArch64::getFPUVersion(unsigned FPUKind) { 407 return ARM::getFPUVersion(FPUKind); 408 } 409 410 ARM::NeonSupportLevel AArch64::getFPUNeonSupportLevel(unsigned FPUKind) { 411 return ARM::getFPUNeonSupportLevel( FPUKind); 412 } 413 414 ARM::FPURestriction AArch64::getFPURestriction(unsigned FPUKind) { 415 return ARM::getFPURestriction(FPUKind); 416 } 417 418 unsigned llvm::AArch64::getDefaultFPU(StringRef CPU, ArchKind AK) { 419 if (CPU == "generic") 420 return AArch64ARCHNames[static_cast<unsigned>(AK)].DefaultFPU; 421 422 return StringSwitch<unsigned>(CPU) 423 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 424 .Case(NAME, DEFAULT_FPU) 425 #include "llvm/Support/AArch64TargetParser.def" 426 .Default(ARM::FK_INVALID); 427 } 428 429 unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, ArchKind AK) { 430 if (CPU == "generic") 431 return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions; 432 433 return StringSwitch<unsigned>(CPU) 434 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 435 .Case(NAME, \ 436 AArch64ARCHNames[static_cast<unsigned>(AArch64::ArchKind::ID)] \ 437 .ArchBaseExtensions | \ 438 DEFAULT_EXT) 439 #include "llvm/Support/AArch64TargetParser.def" 440 .Default(AArch64::AEK_INVALID); 441 } 442 443 AArch64::ArchKind llvm::AArch64::getCPUArchKind(StringRef CPU) { 444 if (CPU == "generic") 445 return AArch64::ArchKind::ARMV8A; 446 447 return StringSwitch<AArch64::ArchKind>(CPU) 448 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 449 .Case(NAME, AArch64::ArchKind:: ID) 450 #include "llvm/Support/AArch64TargetParser.def" 451 .Default(AArch64::ArchKind::INVALID); 452 } 453 454 bool llvm::AArch64::getExtensionFeatures(unsigned Extensions, 455 std::vector<StringRef> &Features) { 456 457 if (Extensions == AArch64::AEK_INVALID) 458 return false; 459 460 if (Extensions & AArch64::AEK_FP) 461 Features.push_back("+fp-armv8"); 462 if (Extensions & AArch64::AEK_SIMD) 463 Features.push_back("+neon"); 464 if (Extensions & AArch64::AEK_CRC) 465 Features.push_back("+crc"); 466 if (Extensions & AArch64::AEK_CRYPTO) 467 Features.push_back("+crypto"); 468 if (Extensions & AArch64::AEK_DOTPROD) 469 Features.push_back("+dotprod"); 470 if (Extensions & AArch64::AEK_FP16FML) 471 Features.push_back("+fp16fml"); 472 if (Extensions & AArch64::AEK_FP16) 473 Features.push_back("+fullfp16"); 474 if (Extensions & AArch64::AEK_PROFILE) 475 Features.push_back("+spe"); 476 if (Extensions & AArch64::AEK_RAS) 477 Features.push_back("+ras"); 478 if (Extensions & AArch64::AEK_LSE) 479 Features.push_back("+lse"); 480 if (Extensions & AArch64::AEK_RDM) 481 Features.push_back("+rdm"); 482 if (Extensions & AArch64::AEK_SVE) 483 Features.push_back("+sve"); 484 if (Extensions & AArch64::AEK_RCPC) 485 Features.push_back("+rcpc"); 486 487 return true; 488 } 489 490 bool llvm::AArch64::getFPUFeatures(unsigned FPUKind, 491 std::vector<StringRef> &Features) { 492 return ARM::getFPUFeatures(FPUKind, Features); 493 } 494 495 bool llvm::AArch64::getArchFeatures(AArch64::ArchKind AK, 496 std::vector<StringRef> &Features) { 497 if (AK == AArch64::ArchKind::ARMV8_1A) 498 Features.push_back("+v8.1a"); 499 if (AK == AArch64::ArchKind::ARMV8_2A) 500 Features.push_back("+v8.2a"); 501 if (AK == AArch64::ArchKind::ARMV8_3A) 502 Features.push_back("+v8.3a"); 503 if (AK == AArch64::ArchKind::ARMV8_4A) 504 Features.push_back("+v8.4a"); 505 if (AK == AArch64::ArchKind::ARMV8_5A) 506 Features.push_back("+v8.5a"); 507 508 return AK != AArch64::ArchKind::INVALID; 509 } 510 511 StringRef llvm::AArch64::getArchName(ArchKind AK) { 512 return AArch64ARCHNames[static_cast<unsigned>(AK)].getName(); 513 } 514 515 StringRef llvm::AArch64::getCPUAttr(ArchKind AK) { 516 return AArch64ARCHNames[static_cast<unsigned>(AK)].getCPUAttr(); 517 } 518 519 StringRef llvm::AArch64::getSubArch(ArchKind AK) { 520 return AArch64ARCHNames[static_cast<unsigned>(AK)].getSubArch(); 521 } 522 523 unsigned llvm::AArch64::getArchAttr(ArchKind AK) { 524 return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchAttr; 525 } 526 527 StringRef llvm::AArch64::getArchExtName(unsigned ArchExtKind) { 528 for (const auto &AE : AArch64ARCHExtNames) 529 if (ArchExtKind == AE.ID) 530 return AE.getName(); 531 return StringRef(); 532 } 533 534 StringRef llvm::AArch64::getArchExtFeature(StringRef ArchExt) { 535 if (ArchExt.startswith("no")) { 536 StringRef ArchExtBase(ArchExt.substr(2)); 537 for (const auto &AE : AArch64ARCHExtNames) { 538 if (AE.NegFeature && ArchExtBase == AE.getName()) 539 return StringRef(AE.NegFeature); 540 } 541 } 542 543 for (const auto &AE : AArch64ARCHExtNames) 544 if (AE.Feature && ArchExt == AE.getName()) 545 return StringRef(AE.Feature); 546 return StringRef(); 547 } 548 549 StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) { 550 AArch64::ArchKind AK = parseArch(Arch); 551 if (AK == ArchKind::INVALID) 552 return StringRef(); 553 554 // Look for multiple AKs to find the default for pair AK+Name. 555 for (const auto &CPU : AArch64CPUNames) 556 if (CPU.ArchID == AK && CPU.Default) 557 return CPU.getName(); 558 559 // If we can't find a default then target the architecture instead 560 return "generic"; 561 } 562 563 unsigned llvm::AArch64::checkArchVersion(StringRef Arch) { 564 if (Arch.size() >= 2 && Arch[0] == 'v' && std::isdigit(Arch[1])) 565 return (Arch[1] - 48); 566 return 0; 567 } 568 569 // ======================================================= // 570 // Parsers 571 // ======================================================= // 572 573 static StringRef getHWDivSynonym(StringRef HWDiv) { 574 return StringSwitch<StringRef>(HWDiv) 575 .Case("thumb,arm", "arm,thumb") 576 .Default(HWDiv); 577 } 578 579 static StringRef getFPUSynonym(StringRef FPU) { 580 return StringSwitch<StringRef>(FPU) 581 .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported 582 .Case("vfp2", "vfpv2") 583 .Case("vfp3", "vfpv3") 584 .Case("vfp4", "vfpv4") 585 .Case("vfp3-d16", "vfpv3-d16") 586 .Case("vfp4-d16", "vfpv4-d16") 587 .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16") 588 .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16") 589 .Case("fp5-sp-d16", "fpv5-sp-d16") 590 .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16") 591 // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3. 592 .Case("neon-vfpv3", "neon") 593 .Default(FPU); 594 } 595 596 static StringRef getArchSynonym(StringRef Arch) { 597 return StringSwitch<StringRef>(Arch) 598 .Case("v5", "v5t") 599 .Case("v5e", "v5te") 600 .Case("v6j", "v6") 601 .Case("v6hl", "v6k") 602 .Cases("v6m", "v6sm", "v6s-m", "v6-m") 603 .Cases("v6z", "v6zk", "v6kz") 604 .Cases("v7", "v7a", "v7hl", "v7l", "v7-a") 605 .Case("v7r", "v7-r") 606 .Case("v7m", "v7-m") 607 .Case("v7em", "v7e-m") 608 .Cases("v8", "v8a", "v8l", "aarch64", "arm64", "v8-a") 609 .Case("v8.1a", "v8.1-a") 610 .Case("v8.2a", "v8.2-a") 611 .Case("v8.3a", "v8.3-a") 612 .Case("v8.4a", "v8.4-a") 613 .Case("v8.5a", "v8.5-a") 614 .Case("v8r", "v8-r") 615 .Case("v8m.base", "v8-m.base") 616 .Case("v8m.main", "v8-m.main") 617 .Default(Arch); 618 } 619 620 // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but 621 // (iwmmxt|xscale)(eb)? is also permitted. If the former, return 622 // "v.+", if the latter, return unmodified string, minus 'eb'. 623 // If invalid, return empty string. 624 StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) { 625 size_t offset = StringRef::npos; 626 StringRef A = Arch; 627 StringRef Error = ""; 628 629 // Begins with "arm" / "thumb", move past it. 630 if (A.startswith("arm64")) 631 offset = 5; 632 else if (A.startswith("arm")) 633 offset = 3; 634 else if (A.startswith("thumb")) 635 offset = 5; 636 else if (A.startswith("aarch64")) { 637 offset = 7; 638 // AArch64 uses "_be", not "eb" suffix. 639 if (A.find("eb") != StringRef::npos) 640 return Error; 641 if (A.substr(offset, 3) == "_be") 642 offset += 3; 643 } 644 645 // Ex. "armebv7", move past the "eb". 646 if (offset != StringRef::npos && A.substr(offset, 2) == "eb") 647 offset += 2; 648 // Or, if it ends with eb ("armv7eb"), chop it off. 649 else if (A.endswith("eb")) 650 A = A.substr(0, A.size() - 2); 651 // Trim the head 652 if (offset != StringRef::npos) 653 A = A.substr(offset); 654 655 // Empty string means offset reached the end, which means it's valid. 656 if (A.empty()) 657 return Arch; 658 659 // Only match non-marketing names 660 if (offset != StringRef::npos) { 661 // Must start with 'vN'. 662 if (A.size() >= 2 && (A[0] != 'v' || !std::isdigit(A[1]))) 663 return Error; 664 // Can't have an extra 'eb'. 665 if (A.find("eb") != StringRef::npos) 666 return Error; 667 } 668 669 // Arch will either be a 'v' name (v7a) or a marketing name (xscale). 670 return A; 671 } 672 673 unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) { 674 StringRef Syn = getHWDivSynonym(HWDiv); 675 for (const auto D : HWDivNames) { 676 if (Syn == D.getName()) 677 return D.ID; 678 } 679 return ARM::AEK_INVALID; 680 } 681 682 unsigned llvm::ARM::parseFPU(StringRef FPU) { 683 StringRef Syn = getFPUSynonym(FPU); 684 for (const auto F : FPUNames) { 685 if (Syn == F.getName()) 686 return F.ID; 687 } 688 return ARM::FK_INVALID; 689 } 690 691 // Allows partial match, ex. "v7a" matches "armv7a". 692 ARM::ArchKind ARM::parseArch(StringRef Arch) { 693 Arch = getCanonicalArchName(Arch); 694 StringRef Syn = getArchSynonym(Arch); 695 for (const auto A : ARCHNames) { 696 if (A.getName().endswith(Syn)) 697 return A.ID; 698 } 699 return ARM::ArchKind::INVALID; 700 } 701 702 unsigned llvm::ARM::parseArchExt(StringRef ArchExt) { 703 for (const auto A : ARCHExtNames) { 704 if (ArchExt == A.getName()) 705 return A.ID; 706 } 707 return ARM::AEK_INVALID; 708 } 709 710 ARM::ArchKind llvm::ARM::parseCPUArch(StringRef CPU) { 711 for (const auto C : CPUNames) { 712 if (CPU == C.getName()) 713 return C.ArchID; 714 } 715 return ARM::ArchKind::INVALID; 716 } 717 718 void llvm::ARM::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) { 719 for (const CpuNames<ARM::ArchKind> &Arch : CPUNames) { 720 if (Arch.ArchID != ARM::ArchKind::INVALID) 721 Values.push_back(Arch.getName()); 722 } 723 } 724 725 void llvm::AArch64::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) { 726 for (const CpuNames<AArch64::ArchKind> &Arch : AArch64CPUNames) { 727 if (Arch.ArchID != AArch64::ArchKind::INVALID) 728 Values.push_back(Arch.getName()); 729 } 730 } 731 732 // ARM, Thumb, AArch64 733 ARM::ISAKind ARM::parseArchISA(StringRef Arch) { 734 return StringSwitch<ARM::ISAKind>(Arch) 735 .StartsWith("aarch64", ARM::ISAKind::AARCH64) 736 .StartsWith("arm64", ARM::ISAKind::AARCH64) 737 .StartsWith("thumb", ARM::ISAKind::THUMB) 738 .StartsWith("arm", ARM::ISAKind::ARM) 739 .Default(ARM::ISAKind::INVALID); 740 } 741 742 // Little/Big endian 743 ARM::EndianKind ARM::parseArchEndian(StringRef Arch) { 744 if (Arch.startswith("armeb") || Arch.startswith("thumbeb") || 745 Arch.startswith("aarch64_be")) 746 return ARM::EndianKind::BIG; 747 748 if (Arch.startswith("arm") || Arch.startswith("thumb")) { 749 if (Arch.endswith("eb")) 750 return ARM::EndianKind::BIG; 751 else 752 return ARM::EndianKind::LITTLE; 753 } 754 755 if (Arch.startswith("aarch64")) 756 return ARM::EndianKind::LITTLE; 757 758 return ARM::EndianKind::INVALID; 759 } 760 761 // Profile A/R/M 762 ARM::ProfileKind ARM::parseArchProfile(StringRef Arch) { 763 Arch = getCanonicalArchName(Arch); 764 switch (parseArch(Arch)) { 765 case ARM::ArchKind::ARMV6M: 766 case ARM::ArchKind::ARMV7M: 767 case ARM::ArchKind::ARMV7EM: 768 case ARM::ArchKind::ARMV8MMainline: 769 case ARM::ArchKind::ARMV8MBaseline: 770 return ARM::ProfileKind::M; 771 case ARM::ArchKind::ARMV7R: 772 case ARM::ArchKind::ARMV8R: 773 return ARM::ProfileKind::R; 774 case ARM::ArchKind::ARMV7A: 775 case ARM::ArchKind::ARMV7VE: 776 case ARM::ArchKind::ARMV7K: 777 case ARM::ArchKind::ARMV8A: 778 case ARM::ArchKind::ARMV8_1A: 779 case ARM::ArchKind::ARMV8_2A: 780 case ARM::ArchKind::ARMV8_3A: 781 case ARM::ArchKind::ARMV8_4A: 782 case ARM::ArchKind::ARMV8_5A: 783 return ARM::ProfileKind::A; 784 case ARM::ArchKind::ARMV2: 785 case ARM::ArchKind::ARMV2A: 786 case ARM::ArchKind::ARMV3: 787 case ARM::ArchKind::ARMV3M: 788 case ARM::ArchKind::ARMV4: 789 case ARM::ArchKind::ARMV4T: 790 case ARM::ArchKind::ARMV5T: 791 case ARM::ArchKind::ARMV5TE: 792 case ARM::ArchKind::ARMV5TEJ: 793 case ARM::ArchKind::ARMV6: 794 case ARM::ArchKind::ARMV6K: 795 case ARM::ArchKind::ARMV6T2: 796 case ARM::ArchKind::ARMV6KZ: 797 case ARM::ArchKind::ARMV7S: 798 case ARM::ArchKind::IWMMXT: 799 case ARM::ArchKind::IWMMXT2: 800 case ARM::ArchKind::XSCALE: 801 case ARM::ArchKind::INVALID: 802 return ARM::ProfileKind::INVALID; 803 } 804 llvm_unreachable("Unhandled architecture"); 805 } 806 807 // Version number (ex. v7 = 7). 808 unsigned llvm::ARM::parseArchVersion(StringRef Arch) { 809 Arch = getCanonicalArchName(Arch); 810 switch (parseArch(Arch)) { 811 case ARM::ArchKind::ARMV2: 812 case ARM::ArchKind::ARMV2A: 813 return 2; 814 case ARM::ArchKind::ARMV3: 815 case ARM::ArchKind::ARMV3M: 816 return 3; 817 case ARM::ArchKind::ARMV4: 818 case ARM::ArchKind::ARMV4T: 819 return 4; 820 case ARM::ArchKind::ARMV5T: 821 case ARM::ArchKind::ARMV5TE: 822 case ARM::ArchKind::IWMMXT: 823 case ARM::ArchKind::IWMMXT2: 824 case ARM::ArchKind::XSCALE: 825 case ARM::ArchKind::ARMV5TEJ: 826 return 5; 827 case ARM::ArchKind::ARMV6: 828 case ARM::ArchKind::ARMV6K: 829 case ARM::ArchKind::ARMV6T2: 830 case ARM::ArchKind::ARMV6KZ: 831 case ARM::ArchKind::ARMV6M: 832 return 6; 833 case ARM::ArchKind::ARMV7A: 834 case ARM::ArchKind::ARMV7VE: 835 case ARM::ArchKind::ARMV7R: 836 case ARM::ArchKind::ARMV7M: 837 case ARM::ArchKind::ARMV7S: 838 case ARM::ArchKind::ARMV7EM: 839 case ARM::ArchKind::ARMV7K: 840 return 7; 841 case ARM::ArchKind::ARMV8A: 842 case ARM::ArchKind::ARMV8_1A: 843 case ARM::ArchKind::ARMV8_2A: 844 case ARM::ArchKind::ARMV8_3A: 845 case ARM::ArchKind::ARMV8_4A: 846 case ARM::ArchKind::ARMV8_5A: 847 case ARM::ArchKind::ARMV8R: 848 case ARM::ArchKind::ARMV8MBaseline: 849 case ARM::ArchKind::ARMV8MMainline: 850 return 8; 851 case ARM::ArchKind::INVALID: 852 return 0; 853 } 854 llvm_unreachable("Unhandled architecture"); 855 } 856 857 StringRef llvm::ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) { 858 StringRef ArchName = 859 CPU.empty() ? TT.getArchName() : ARM::getArchName(ARM::parseCPUArch(CPU)); 860 861 if (TT.isOSBinFormatMachO()) { 862 if (TT.getEnvironment() == Triple::EABI || 863 TT.getOS() == Triple::UnknownOS || 864 llvm::ARM::parseArchProfile(ArchName) == ARM::ProfileKind::M) 865 return "aapcs"; 866 if (TT.isWatchABI()) 867 return "aapcs16"; 868 return "apcs-gnu"; 869 } else if (TT.isOSWindows()) 870 // FIXME: this is invalid for WindowsCE. 871 return "aapcs"; 872 873 // Select the default based on the platform. 874 switch (TT.getEnvironment()) { 875 case Triple::Android: 876 case Triple::GNUEABI: 877 case Triple::GNUEABIHF: 878 case Triple::MuslEABI: 879 case Triple::MuslEABIHF: 880 return "aapcs-linux"; 881 case Triple::EABIHF: 882 case Triple::EABI: 883 return "aapcs"; 884 default: 885 if (TT.isOSNetBSD()) 886 return "apcs-gnu"; 887 if (TT.isOSOpenBSD()) 888 return "aapcs-linux"; 889 return "aapcs"; 890 } 891 } 892 893 StringRef llvm::AArch64::getCanonicalArchName(StringRef Arch) { 894 return ARM::getCanonicalArchName(Arch); 895 } 896 897 unsigned llvm::AArch64::parseFPU(StringRef FPU) { 898 return ARM::parseFPU(FPU); 899 } 900 901 // Allows partial match, ex. "v8a" matches "armv8a". 902 AArch64::ArchKind AArch64::parseArch(StringRef Arch) { 903 Arch = getCanonicalArchName(Arch); 904 if (checkArchVersion(Arch) < 8) 905 return ArchKind::INVALID; 906 907 StringRef Syn = getArchSynonym(Arch); 908 for (const auto A : AArch64ARCHNames) { 909 if (A.getName().endswith(Syn)) 910 return A.ID; 911 } 912 return ArchKind::INVALID; 913 } 914 915 AArch64::ArchExtKind llvm::AArch64::parseArchExt(StringRef ArchExt) { 916 for (const auto A : AArch64ARCHExtNames) { 917 if (ArchExt == A.getName()) 918 return static_cast<ArchExtKind>(A.ID); 919 } 920 return AArch64::AEK_INVALID; 921 } 922 923 AArch64::ArchKind llvm::AArch64::parseCPUArch(StringRef CPU) { 924 for (const auto C : AArch64CPUNames) { 925 if (CPU == C.getName()) 926 return C.ArchID; 927 } 928 return ArchKind::INVALID; 929 } 930 931 // ARM, Thumb, AArch64 932 ARM::ISAKind AArch64::parseArchISA(StringRef Arch) { 933 return ARM::parseArchISA(Arch); 934 } 935 936 // Little/Big endian 937 ARM::EndianKind AArch64::parseArchEndian(StringRef Arch) { 938 return ARM::parseArchEndian(Arch); 939 } 940 941 // Profile A/R/M 942 ARM::ProfileKind AArch64::parseArchProfile(StringRef Arch) { 943 return ARM::parseArchProfile(Arch); 944 } 945 946 // Version number (ex. v8 = 8). 947 unsigned llvm::AArch64::parseArchVersion(StringRef Arch) { 948 return ARM::parseArchVersion(Arch); 949 } 950 951 bool llvm::AArch64::isX18ReservedByDefault(const Triple &TT) { 952 return TT.isAndroid() || TT.isOSDarwin() || TT.isOSFuchsia() || 953 TT.isOSWindows(); 954 } 955 956 namespace { 957 958 struct GPUInfo { 959 StringLiteral Name; 960 StringLiteral CanonicalName; 961 AMDGPU::GPUKind Kind; 962 unsigned Features; 963 }; 964 965 constexpr GPUInfo R600GPUs[26] = { 966 // Name Canonical Kind Features 967 // Name 968 {{"r600"}, {"r600"}, GK_R600, FEATURE_NONE }, 969 {{"rv630"}, {"r600"}, GK_R600, FEATURE_NONE }, 970 {{"rv635"}, {"r600"}, GK_R600, FEATURE_NONE }, 971 {{"r630"}, {"r630"}, GK_R630, FEATURE_NONE }, 972 {{"rs780"}, {"rs880"}, GK_RS880, FEATURE_NONE }, 973 {{"rs880"}, {"rs880"}, GK_RS880, FEATURE_NONE }, 974 {{"rv610"}, {"rs880"}, GK_RS880, FEATURE_NONE }, 975 {{"rv620"}, {"rs880"}, GK_RS880, FEATURE_NONE }, 976 {{"rv670"}, {"rv670"}, GK_RV670, FEATURE_NONE }, 977 {{"rv710"}, {"rv710"}, GK_RV710, FEATURE_NONE }, 978 {{"rv730"}, {"rv730"}, GK_RV730, FEATURE_NONE }, 979 {{"rv740"}, {"rv770"}, GK_RV770, FEATURE_NONE }, 980 {{"rv770"}, {"rv770"}, GK_RV770, FEATURE_NONE }, 981 {{"cedar"}, {"cedar"}, GK_CEDAR, FEATURE_NONE }, 982 {{"palm"}, {"cedar"}, GK_CEDAR, FEATURE_NONE }, 983 {{"cypress"}, {"cypress"}, GK_CYPRESS, FEATURE_FMA }, 984 {{"hemlock"}, {"cypress"}, GK_CYPRESS, FEATURE_FMA }, 985 {{"juniper"}, {"juniper"}, GK_JUNIPER, FEATURE_NONE }, 986 {{"redwood"}, {"redwood"}, GK_REDWOOD, FEATURE_NONE }, 987 {{"sumo"}, {"sumo"}, GK_SUMO, FEATURE_NONE }, 988 {{"sumo2"}, {"sumo"}, GK_SUMO, FEATURE_NONE }, 989 {{"barts"}, {"barts"}, GK_BARTS, FEATURE_NONE }, 990 {{"caicos"}, {"caicos"}, GK_CAICOS, FEATURE_NONE }, 991 {{"aruba"}, {"cayman"}, GK_CAYMAN, FEATURE_FMA }, 992 {{"cayman"}, {"cayman"}, GK_CAYMAN, FEATURE_FMA }, 993 {{"turks"}, {"turks"}, GK_TURKS, FEATURE_NONE } 994 }; 995 996 // This table should be sorted by the value of GPUKind 997 // Don't bother listing the implicitly true features 998 constexpr GPUInfo AMDGCNGPUs[33] = { 999 // Name Canonical Kind Features 1000 // Name 1001 {{"gfx600"}, {"gfx600"}, GK_GFX600, FEATURE_FAST_FMA_F32}, 1002 {{"tahiti"}, {"gfx600"}, GK_GFX600, FEATURE_FAST_FMA_F32}, 1003 {{"gfx601"}, {"gfx601"}, GK_GFX601, FEATURE_NONE}, 1004 {{"hainan"}, {"gfx601"}, GK_GFX601, FEATURE_NONE}, 1005 {{"oland"}, {"gfx601"}, GK_GFX601, FEATURE_NONE}, 1006 {{"pitcairn"}, {"gfx601"}, GK_GFX601, FEATURE_NONE}, 1007 {{"verde"}, {"gfx601"}, GK_GFX601, FEATURE_NONE}, 1008 {{"gfx700"}, {"gfx700"}, GK_GFX700, FEATURE_NONE}, 1009 {{"kaveri"}, {"gfx700"}, GK_GFX700, FEATURE_NONE}, 1010 {{"gfx701"}, {"gfx701"}, GK_GFX701, FEATURE_FAST_FMA_F32}, 1011 {{"hawaii"}, {"gfx701"}, GK_GFX701, FEATURE_FAST_FMA_F32}, 1012 {{"gfx702"}, {"gfx702"}, GK_GFX702, FEATURE_FAST_FMA_F32}, 1013 {{"gfx703"}, {"gfx703"}, GK_GFX703, FEATURE_NONE}, 1014 {{"kabini"}, {"gfx703"}, GK_GFX703, FEATURE_NONE}, 1015 {{"mullins"}, {"gfx703"}, GK_GFX703, FEATURE_NONE}, 1016 {{"gfx704"}, {"gfx704"}, GK_GFX704, FEATURE_NONE}, 1017 {{"bonaire"}, {"gfx704"}, GK_GFX704, FEATURE_NONE}, 1018 {{"gfx801"}, {"gfx801"}, GK_GFX801, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32}, 1019 {{"carrizo"}, {"gfx801"}, GK_GFX801, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32}, 1020 {{"gfx802"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32}, 1021 {{"iceland"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32}, 1022 {{"tonga"}, {"gfx802"}, GK_GFX802, FEATURE_FAST_DENORMAL_F32}, 1023 {{"gfx803"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32}, 1024 {{"fiji"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32}, 1025 {{"polaris10"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32}, 1026 {{"polaris11"}, {"gfx803"}, GK_GFX803, FEATURE_FAST_DENORMAL_F32}, 1027 {{"gfx810"}, {"gfx810"}, GK_GFX810, FEATURE_FAST_DENORMAL_F32}, 1028 {{"stoney"}, {"gfx810"}, GK_GFX810, FEATURE_FAST_DENORMAL_F32}, 1029 {{"gfx900"}, {"gfx900"}, GK_GFX900, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32}, 1030 {{"gfx902"}, {"gfx902"}, GK_GFX902, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32}, 1031 {{"gfx904"}, {"gfx904"}, GK_GFX904, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32}, 1032 {{"gfx906"}, {"gfx906"}, GK_GFX906, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32}, 1033 {{"gfx909"}, {"gfx909"}, GK_GFX909, FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32}, 1034 }; 1035 1036 const GPUInfo *getArchEntry(AMDGPU::GPUKind AK, ArrayRef<GPUInfo> Table) { 1037 GPUInfo Search = { {""}, {""}, AK, AMDGPU::FEATURE_NONE }; 1038 1039 auto I = std::lower_bound(Table.begin(), Table.end(), Search, 1040 [](const GPUInfo &A, const GPUInfo &B) { 1041 return A.Kind < B.Kind; 1042 }); 1043 1044 if (I == Table.end()) 1045 return nullptr; 1046 return I; 1047 } 1048 1049 } // namespace 1050 1051 StringRef llvm::AMDGPU::getArchNameAMDGCN(GPUKind AK) { 1052 if (const auto *Entry = getArchEntry(AK, AMDGCNGPUs)) 1053 return Entry->CanonicalName; 1054 return ""; 1055 } 1056 1057 StringRef llvm::AMDGPU::getArchNameR600(GPUKind AK) { 1058 if (const auto *Entry = getArchEntry(AK, R600GPUs)) 1059 return Entry->CanonicalName; 1060 return ""; 1061 } 1062 1063 AMDGPU::GPUKind llvm::AMDGPU::parseArchAMDGCN(StringRef CPU) { 1064 for (const auto C : AMDGCNGPUs) { 1065 if (CPU == C.Name) 1066 return C.Kind; 1067 } 1068 1069 return AMDGPU::GPUKind::GK_NONE; 1070 } 1071 1072 AMDGPU::GPUKind llvm::AMDGPU::parseArchR600(StringRef CPU) { 1073 for (const auto C : R600GPUs) { 1074 if (CPU == C.Name) 1075 return C.Kind; 1076 } 1077 1078 return AMDGPU::GPUKind::GK_NONE; 1079 } 1080 1081 unsigned AMDGPU::getArchAttrAMDGCN(GPUKind AK) { 1082 if (const auto *Entry = getArchEntry(AK, AMDGCNGPUs)) 1083 return Entry->Features; 1084 return FEATURE_NONE; 1085 } 1086 1087 unsigned AMDGPU::getArchAttrR600(GPUKind AK) { 1088 if (const auto *Entry = getArchEntry(AK, R600GPUs)) 1089 return Entry->Features; 1090 return FEATURE_NONE; 1091 } 1092 1093 void AMDGPU::fillValidArchListAMDGCN(SmallVectorImpl<StringRef> &Values) { 1094 // XXX: Should this only report unique canonical names? 1095 for (const auto C : AMDGCNGPUs) 1096 Values.push_back(C.Name); 1097 } 1098 1099 void AMDGPU::fillValidArchListR600(SmallVectorImpl<StringRef> &Values) { 1100 for (const auto C : R600GPUs) 1101 Values.push_back(C.Name); 1102 } 1103 1104 AMDGPU::IsaVersion AMDGPU::getIsaVersion(StringRef GPU) { 1105 if (GPU == "generic") 1106 return {7, 0, 0}; 1107 1108 AMDGPU::GPUKind AK = parseArchAMDGCN(GPU); 1109 if (AK == AMDGPU::GPUKind::GK_NONE) 1110 return {0, 0, 0}; 1111 1112 switch (AK) { 1113 case GK_GFX600: return {6, 0, 0}; 1114 case GK_GFX601: return {6, 0, 1}; 1115 case GK_GFX700: return {7, 0, 0}; 1116 case GK_GFX701: return {7, 0, 1}; 1117 case GK_GFX702: return {7, 0, 2}; 1118 case GK_GFX703: return {7, 0, 3}; 1119 case GK_GFX704: return {7, 0, 4}; 1120 case GK_GFX801: return {8, 0, 1}; 1121 case GK_GFX802: return {8, 0, 2}; 1122 case GK_GFX803: return {8, 0, 3}; 1123 case GK_GFX810: return {8, 1, 0}; 1124 case GK_GFX900: return {9, 0, 0}; 1125 case GK_GFX902: return {9, 0, 2}; 1126 case GK_GFX904: return {9, 0, 4}; 1127 case GK_GFX906: return {9, 0, 6}; 1128 case GK_GFX909: return {9, 0, 9}; 1129 default: return {0, 0, 0}; 1130 } 1131 } 1132