LCOV - code coverage report
Current view: top level - lib/Support - TargetParser.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 367 413 88.9 %
Date: 2018-10-20 13:21:21 Functions: 60 82 73.2 %
Legend: Lines: hit not hit

          Line data    Source code
       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           0 :   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           0 :   StringRef getName() const { return StringRef(NameCStr, NameLength); }
      69             : 
      70             :   // CPU class in build attributes.
      71           0 :   StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
      72             : 
      73             :   // Sub-Arch name.
      74           0 :   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           0 :   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           0 :   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           0 :   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        1336 : StringRef ARM::getFPUName(unsigned FPUKind) {
     158        1336 :   if (FPUKind >= ARM::FK_LAST)
     159           0 :     return StringRef();
     160        1336 :   return FPUNames[FPUKind].getName();
     161             : }
     162             : 
     163          23 : FPUVersion ARM::getFPUVersion(unsigned FPUKind) {
     164          23 :   if (FPUKind >= ARM::FK_LAST)
     165             :     return FPUVersion::NONE;
     166          22 :   return FPUNames[FPUKind].FPUVersion;
     167             : }
     168             : 
     169          23 : ARM::NeonSupportLevel ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
     170          23 :   if (FPUKind >= ARM::FK_LAST)
     171             :     return ARM::NeonSupportLevel::None;
     172          22 :   return FPUNames[FPUKind].NeonSupport;
     173             : }
     174             : 
     175          23 : ARM::FPURestriction ARM::getFPURestriction(unsigned FPUKind) {
     176          23 :   if (FPUKind >= ARM::FK_LAST)
     177             :     return ARM::FPURestriction::None;
     178          22 :   return FPUNames[FPUKind].Restriction;
     179             : }
     180             : 
     181         737 : unsigned llvm::ARM::getDefaultFPU(StringRef CPU, ArchKind AK) {
     182             :   if (CPU == "generic")
     183          35 :     return ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
     184             : 
     185         702 :   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         861 : unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, ArchKind AK) {
     193             :   if (CPU == "generic")
     194          70 :     return ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
     195             : 
     196         791 :   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      139377 : bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
     205             :                                  std::vector<StringRef> &Features) {
     206             : 
     207      139377 :   if (HWDivKind == ARM::AEK_INVALID)
     208             :     return false;
     209             : 
     210      139377 :   if (HWDivKind & ARM::AEK_HWDIVARM)
     211       69635 :     Features.push_back("+hwdiv-arm");
     212             :   else
     213       69742 :     Features.push_back("-hwdiv-arm");
     214             : 
     215      139377 :   if (HWDivKind & ARM::AEK_HWDIVTHUMB)
     216       69672 :     Features.push_back("+hwdiv");
     217             :   else
     218       69705 :     Features.push_back("-hwdiv");
     219             : 
     220             :   return true;
     221             : }
     222             : 
     223      139843 : bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
     224             :                                      std::vector<StringRef> &Features) {
     225             : 
     226      139843 :   if (Extensions == ARM::AEK_INVALID)
     227             :     return false;
     228             : 
     229      139366 :   if (Extensions & ARM::AEK_CRC)
     230       69593 :     Features.push_back("+crc");
     231             :   else
     232       69773 :     Features.push_back("-crc");
     233             : 
     234      139366 :   if (Extensions & ARM::AEK_DSP)
     235       69678 :     Features.push_back("+dsp");
     236             :   else
     237       69688 :     Features.push_back("-dsp");
     238             : 
     239      139366 :   if (Extensions & ARM::AEK_FP16FML)
     240        8055 :     Features.push_back("+fp16fml");
     241             :   else
     242      131311 :     Features.push_back("-fp16fml");
     243             : 
     244      139366 :   if (Extensions & ARM::AEK_RAS)
     245       69498 :     Features.push_back("+ras");
     246             :   else
     247       69868 :     Features.push_back("-ras");
     248             : 
     249      139366 :   if (Extensions & ARM::AEK_DOTPROD)
     250       65539 :     Features.push_back("+dotprod");
     251             :   else
     252       73827 :     Features.push_back("-dotprod");
     253             : 
     254      139366 :   return getHWDivFeatures(Extensions, Features);
     255             : }
     256             : 
     257        1397 : bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
     258             :                                std::vector<StringRef> &Features) {
     259             : 
     260        1397 :   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         926 :   switch (FPUNames[FPUKind].Restriction) {
     266             :   case ARM::FPURestriction::SP_D16:
     267          17 :     Features.push_back("+fp-only-sp");
     268          17 :     Features.push_back("+d16");
     269          17 :     break;
     270             :   case ARM::FPURestriction::D16:
     271          30 :     Features.push_back("-fp-only-sp");
     272          30 :     Features.push_back("+d16");
     273          30 :     break;
     274             :   case ARM::FPURestriction::None:
     275         879 :     Features.push_back("-fp-only-sp");
     276         879 :     Features.push_back("-d16");
     277         879 :     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         926 :   switch (FPUNames[FPUKind].FPUVersion) {
     285             :   case ARM::FPUVersion::VFPV5:
     286          44 :     Features.push_back("+fp-armv8");
     287          44 :     break;
     288             :   case ARM::FPUVersion::VFPV4:
     289          45 :     Features.push_back("+vfp4");
     290          45 :     Features.push_back("-fp-armv8");
     291          45 :     break;
     292             :   case ARM::FPUVersion::VFPV3_FP16:
     293          17 :     Features.push_back("+vfp3");
     294          17 :     Features.push_back("+fp16");
     295          17 :     Features.push_back("-vfp4");
     296          17 :     Features.push_back("-fp-armv8");
     297          17 :     break;
     298             :   case ARM::FPUVersion::VFPV3:
     299         104 :     Features.push_back("+vfp3");
     300         104 :     Features.push_back("-fp16");
     301         104 :     Features.push_back("-vfp4");
     302         104 :     Features.push_back("-fp-armv8");
     303         104 :     break;
     304             :   case ARM::FPUVersion::VFPV2:
     305          14 :     Features.push_back("+vfp2");
     306          14 :     Features.push_back("-vfp3");
     307          14 :     Features.push_back("-fp16");
     308          14 :     Features.push_back("-vfp4");
     309          14 :     Features.push_back("-fp-armv8");
     310          14 :     break;
     311             :   case ARM::FPUVersion::NONE:
     312         702 :     Features.push_back("-vfp2");
     313         702 :     Features.push_back("-vfp3");
     314         702 :     Features.push_back("-fp16");
     315         702 :     Features.push_back("-vfp4");
     316         702 :     Features.push_back("-fp-armv8");
     317         702 :     break;
     318             :   }
     319             : 
     320             :   // crypto includes neon, so we handle this similarly to FPU version.
     321         926 :   switch (FPUNames[FPUKind].NeonSupport) {
     322             :   case ARM::NeonSupportLevel::Crypto:
     323          27 :     Features.push_back("+neon");
     324          27 :     Features.push_back("+crypto");
     325          27 :     break;
     326             :   case ARM::NeonSupportLevel::Neon:
     327         119 :     Features.push_back("+neon");
     328         119 :     Features.push_back("-crypto");
     329         119 :     break;
     330             :   case ARM::NeonSupportLevel::None:
     331         780 :     Features.push_back("-neon");
     332         780 :     Features.push_back("-crypto");
     333         780 :     break;
     334             :   }
     335             : 
     336             :   return true;
     337             : }
     338             : 
     339        9232 : StringRef llvm::ARM::getArchName(ArchKind AK) {
     340        9232 :   return ARCHNames[static_cast<unsigned>(AK)].getName();
     341             : }
     342             : 
     343         377 : StringRef llvm::ARM::getCPUAttr(ArchKind AK) {
     344         377 :   return ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
     345             : }
     346             : 
     347        2373 : StringRef llvm::ARM::getSubArch(ArchKind AK) {
     348        2373 :   return ARCHNames[static_cast<unsigned>(AK)].getSubArch();
     349             : }
     350             : 
     351          82 : unsigned llvm::ARM::getArchAttr(ArchKind AK) {
     352          82 :   return ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
     353             : }
     354             : 
     355           3 : StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
     356          30 :   for (const auto AE : ARCHExtNames) {
     357          30 :     if (ArchExtKind == AE.ID)
     358             :       return AE.getName();
     359             :   }
     360           0 :   return StringRef();
     361             : }
     362             : 
     363          46 : StringRef llvm::ARM::getArchExtFeature(StringRef ArchExt) {
     364             :   if (ArchExt.startswith("no")) {
     365          19 :     StringRef ArchExtBase(ArchExt.substr(2));
     366         337 :     for (const auto AE : ARCHExtNames) {
     367         327 :       if (AE.NegFeature && ArchExtBase == AE.getName())
     368           9 :         return StringRef(AE.NegFeature);
     369             :     }
     370             :   }
     371         653 :   for (const auto AE : ARCHExtNames) {
     372         631 :     if (AE.Feature && ArchExt == AE.getName())
     373          15 :       return StringRef(AE.Feature);
     374             :   }
     375             : 
     376          22 :   return StringRef();
     377             : }
     378             : 
     379           0 : StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
     380           0 :   for (const auto D : HWDivNames) {
     381           0 :     if (HWDivKind == D.ID)
     382             :       return D.getName();
     383             :   }
     384           0 :   return StringRef();
     385             : }
     386             : 
     387        3326 : StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
     388        3326 :   ArchKind AK = parseArch(Arch);
     389        3326 :   if (AK == ARM::ArchKind::INVALID)
     390         558 :     return StringRef();
     391             : 
     392             :   // Look for multiple AKs to find the default for pair AK+Name.
     393      173433 :   for (const auto CPU : CPUNames) {
     394      171816 :     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        1617 :   return "generic";
     400             : }
     401             : 
     402          21 : StringRef llvm::AArch64::getFPUName(unsigned FPUKind) {
     403          21 :   return ARM::getFPUName(FPUKind);
     404             : }
     405             : 
     406           0 : ARM::FPUVersion AArch64::getFPUVersion(unsigned FPUKind) {
     407           0 :   return ARM::getFPUVersion(FPUKind);
     408             : }
     409             : 
     410           0 : ARM::NeonSupportLevel AArch64::getFPUNeonSupportLevel(unsigned FPUKind) {
     411           0 :   return ARM::getFPUNeonSupportLevel( FPUKind);
     412             : }
     413             : 
     414           0 : ARM::FPURestriction AArch64::getFPURestriction(unsigned FPUKind) {
     415           0 :   return ARM::getFPURestriction(FPUKind);
     416             : }
     417             : 
     418          21 : unsigned llvm::AArch64::getDefaultFPU(StringRef CPU, ArchKind AK) {
     419             :   if (CPU == "generic")
     420           1 :     return AArch64ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
     421             : 
     422          20 :   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         675 : unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, ArchKind AK) {
     430             :   if (CPU == "generic")
     431          21 :     return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
     432             : 
     433         654 :   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          21 : AArch64::ArchKind llvm::AArch64::getCPUArchKind(StringRef CPU) {
     444             :   if (CPU == "generic")
     445             :     return AArch64::ArchKind::ARMV8A;
     446             : 
     447           0 :   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      139878 : bool llvm::AArch64::getExtensionFeatures(unsigned Extensions,
     455             :                                      std::vector<StringRef> &Features) {
     456             : 
     457      139878 :   if (Extensions == AArch64::AEK_INVALID)
     458             :     return false;
     459             : 
     460      139877 :   if (Extensions & AArch64::AEK_FP)
     461       70246 :     Features.push_back("+fp-armv8");
     462      139877 :   if (Extensions & AArch64::AEK_SIMD)
     463       70246 :     Features.push_back("+neon");
     464      139877 :   if (Extensions & AArch64::AEK_CRC)
     465       70165 :     Features.push_back("+crc");
     466      139877 :   if (Extensions & AArch64::AEK_CRYPTO)
     467       70246 :     Features.push_back("+crypto");
     468      139877 :   if (Extensions & AArch64::AEK_DOTPROD)
     469       69706 :     Features.push_back("+dotprod");
     470      139877 :   if (Extensions & AArch64::AEK_FP16FML)
     471        8191 :     Features.push_back("+fp16fml");
     472      139877 :   if (Extensions & AArch64::AEK_FP16)
     473       69706 :     Features.push_back("+fullfp16");
     474      139877 :   if (Extensions & AArch64::AEK_PROFILE)
     475       69631 :     Features.push_back("+spe");
     476      139877 :   if (Extensions & AArch64::AEK_RAS)
     477       69706 :     Features.push_back("+ras");
     478      139877 :   if (Extensions & AArch64::AEK_LSE)
     479       69749 :     Features.push_back("+lse");
     480      139877 :   if (Extensions & AArch64::AEK_RDM)
     481       69768 :     Features.push_back("+rdm");
     482      139877 :   if (Extensions & AArch64::AEK_SVE)
     483       69631 :     Features.push_back("+sve");
     484      139877 :   if (Extensions & AArch64::AEK_RCPC)
     485       69706 :     Features.push_back("+rcpc");
     486             : 
     487             :   return true;
     488             : }
     489             : 
     490           0 : bool llvm::AArch64::getFPUFeatures(unsigned FPUKind,
     491             :                                std::vector<StringRef> &Features) {
     492           0 :   return ARM::getFPUFeatures(FPUKind, Features);
     493             : }
     494             : 
     495         883 : bool llvm::AArch64::getArchFeatures(AArch64::ArchKind AK,
     496             :                                     std::vector<StringRef> &Features) {
     497         883 :   if (AK == AArch64::ArchKind::ARMV8_1A)
     498          79 :     Features.push_back("+v8.1a");
     499         883 :   if (AK == AArch64::ArchKind::ARMV8_2A)
     500         158 :     Features.push_back("+v8.2a");
     501         883 :   if (AK == AArch64::ArchKind::ARMV8_3A)
     502          35 :     Features.push_back("+v8.3a");
     503         883 :   if (AK == AArch64::ArchKind::ARMV8_4A)
     504          47 :     Features.push_back("+v8.4a");
     505         883 :   if (AK == AArch64::ArchKind::ARMV8_5A)
     506          20 :     Features.push_back("+v8.5a");
     507             : 
     508         883 :   return AK != AArch64::ArchKind::INVALID;
     509             : }
     510             : 
     511          21 : StringRef llvm::AArch64::getArchName(ArchKind AK) {
     512          21 :   return AArch64ARCHNames[static_cast<unsigned>(AK)].getName();
     513             : }
     514             : 
     515          21 : StringRef llvm::AArch64::getCPUAttr(ArchKind AK) {
     516          21 :   return AArch64ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
     517             : }
     518             : 
     519           6 : StringRef llvm::AArch64::getSubArch(ArchKind AK) {
     520           6 :   return AArch64ARCHNames[static_cast<unsigned>(AK)].getSubArch();
     521             : }
     522             : 
     523           6 : unsigned llvm::AArch64::getArchAttr(ArchKind AK) {
     524           6 :   return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
     525             : }
     526             : 
     527           0 : StringRef llvm::AArch64::getArchExtName(unsigned ArchExtKind) {
     528           0 :   for (const auto &AE : AArch64ARCHExtNames)
     529           0 :     if (ArchExtKind == AE.ID)
     530           0 :       return AE.getName();
     531           0 :   return StringRef();
     532             : }
     533             : 
     534         304 : StringRef llvm::AArch64::getArchExtFeature(StringRef ArchExt) {
     535             :   if (ArchExt.startswith("no")) {
     536         128 :     StringRef ArchExtBase(ArchExt.substr(2));
     537        1497 :     for (const auto &AE : AArch64ARCHExtNames) {
     538        1494 :       if (AE.NegFeature && ArchExtBase == AE.getName())
     539         125 :         return StringRef(AE.NegFeature);
     540             :     }
     541             :   }
     542             : 
     543        2225 :   for (const auto &AE : AArch64ARCHExtNames)
     544        2219 :     if (AE.Feature && ArchExt == AE.getName())
     545         173 :       return StringRef(AE.Feature);
     546           6 :   return StringRef();
     547             : }
     548             : 
     549           6 : StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) {
     550           6 :   AArch64::ArchKind AK = parseArch(Arch);
     551           6 :   if (AK == ArchKind::INVALID)
     552           0 :     return StringRef();
     553             : 
     554             :   // Look for multiple AKs to find the default for pair AK+Name.
     555         112 :   for (const auto &CPU : AArch64CPUNames)
     556         107 :     if (CPU.ArchID == AK && CPU.Default)
     557           1 :       return CPU.getName();
     558             : 
     559             :   // If we can't find a default then target the architecture instead
     560           5 :   return "generic";
     561             : }
     562             : 
     563         286 : unsigned llvm::AArch64::checkArchVersion(StringRef Arch) {
     564         286 :   if (Arch.size() >= 2 && Arch[0] == 'v' && std::isdigit(Arch[1]))
     565         283 :     return (Arch[1] - 48);
     566             :   return 0;
     567             : }
     568             : 
     569             : // ======================================================= //
     570             : // Parsers
     571             : // ======================================================= //
     572             : 
     573          15 : static StringRef getHWDivSynonym(StringRef HWDiv) {
     574          15 :   return StringSwitch<StringRef>(HWDiv)
     575          15 :       .Case("thumb,arm", "arm,thumb")
     576          15 :       .Default(HWDiv);
     577             : }
     578             : 
     579          81 : static StringRef getFPUSynonym(StringRef FPU) {
     580          81 :   return StringSwitch<StringRef>(FPU)
     581             :       .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
     582          81 :       .Case("vfp2", "vfpv2")
     583          81 :       .Case("vfp3", "vfpv3")
     584          81 :       .Case("vfp4", "vfpv4")
     585          81 :       .Case("vfp3-d16", "vfpv3-d16")
     586          81 :       .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          81 :       .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          81 :       .Case("neon-vfpv3", "neon")
     593          81 :       .Default(FPU);
     594             : }
     595             : 
     596     1245133 : static StringRef getArchSynonym(StringRef Arch) {
     597     1245133 :   return StringSwitch<StringRef>(Arch)
     598     1245133 :       .Case("v5", "v5t")
     599     1245133 :       .Case("v5e", "v5te")
     600     1245133 :       .Case("v6j", "v6")
     601     1245133 :       .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     1245133 :       .Case("v7r", "v7-r")
     606     1245133 :       .Case("v7m", "v7-m")
     607     1245133 :       .Case("v7em", "v7e-m")
     608             :       .Cases("v8", "v8a", "v8l", "aarch64", "arm64", "v8-a")
     609     1245133 :       .Case("v8.1a", "v8.1-a")
     610     1245133 :       .Case("v8.2a", "v8.2-a")
     611     1245133 :       .Case("v8.3a", "v8.3-a")
     612     1245133 :       .Case("v8.4a", "v8.4-a")
     613     1245133 :       .Case("v8.5a", "v8.5-a")
     614     1245133 :       .Case("v8r", "v8-r")
     615     1245133 :       .Case("v8m.base", "v8-m.base")
     616     1245133 :       .Case("v8m.main", "v8-m.main")
     617     1245133 :       .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     2560377 : StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
     625             :   size_t offset = StringRef::npos;
     626     2560377 :   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       62594 :     if (A.find("eb") != StringRef::npos)
     640           0 :       return Error;
     641       62594 :     if (A.substr(offset, 3) == "_be")
     642             :       offset += 3;
     643             :   }
     644             : 
     645             :   // Ex. "armebv7", move past the "eb".
     646      200156 :   if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
     647        3175 :     offset += 2;
     648             :   // Or, if it ends with eb ("armv7eb"), chop it off.
     649             :   else if (A.endswith("eb"))
     650         952 :     A = A.substr(0, A.size() - 2);
     651             :   // Trim the head
     652     2560377 :   if (offset != StringRef::npos)
     653      200156 :     A = A.substr(offset);
     654             : 
     655             :   // Empty string means offset reached the end, which means it's valid.
     656     2560377 :   if (A.empty())
     657      159695 :     return Arch;
     658             : 
     659             :   // Only match non-marketing names
     660     2400682 :   if (offset != StringRef::npos) {
     661             :     // Must start with 'vN'.
     662       89887 :     if (A.size() >= 2 && (A[0] != 'v' || !std::isdigit(A[1])))
     663          42 :       return Error;
     664             :     // Can't have an extra 'eb'.
     665       89845 :     if (A.find("eb") != StringRef::npos)
     666           3 :       return Error;
     667             :   }
     668             : 
     669             :   // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
     670     2400637 :   return A;
     671             : }
     672             : 
     673          15 : unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
     674          15 :   StringRef Syn = getHWDivSynonym(HWDiv);
     675          58 :   for (const auto D : HWDivNames) {
     676             :     if (Syn == D.getName())
     677             :       return D.ID;
     678             :   }
     679             :   return ARM::AEK_INVALID;
     680             : }
     681             : 
     682          81 : unsigned llvm::ARM::parseFPU(StringRef FPU) {
     683          81 :   StringRef Syn = getFPUSynonym(FPU);
     684        1054 :   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     1244850 : ARM::ArchKind ARM::parseArch(StringRef Arch) {
     693     1244850 :   Arch = getCanonicalArchName(Arch);
     694     1244850 :   StringRef Syn = getArchSynonym(Arch);
     695    40647804 :   for (const auto A : ARCHNames) {
     696             :     if (A.getName().endswith(Syn))
     697             :       return A.ID;
     698             :   }
     699             :   return ARM::ArchKind::INVALID;
     700             : }
     701             : 
     702         136 : unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
     703        1467 :   for (const auto A : ARCHExtNames) {
     704             :     if (ArchExt == A.getName())
     705             :       return A.ID;
     706             :   }
     707             :   return ARM::AEK_INVALID;
     708             : }
     709             : 
     710        4498 : ARM::ArchKind llvm::ARM::parseCPUArch(StringRef CPU) {
     711      234862 :   for (const auto C : CPUNames) {
     712             :     if (CPU == C.getName())
     713             :       return C.ArchID;
     714             :   }
     715             :   return ARM::ArchKind::INVALID;
     716             : }
     717             : 
     718           3 : void llvm::ARM::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
     719         252 :   for (const CpuNames<ARM::ArchKind> &Arch : CPUNames) {
     720         249 :     if (Arch.ArchID != ARM::ArchKind::INVALID)
     721         246 :       Values.push_back(Arch.getName());
     722             :   }
     723           3 : }
     724             : 
     725           2 : void llvm::AArch64::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
     726          44 :   for (const CpuNames<AArch64::ArchKind> &Arch : AArch64CPUNames) {
     727          42 :     if (Arch.ArchID != AArch64::ArchKind::INVALID)
     728          40 :       Values.push_back(Arch.getName());
     729             :   }
     730           2 : }
     731             : 
     732             : // ARM, Thumb, AArch64
     733       38921 : ARM::ISAKind ARM::parseArchISA(StringRef Arch) {
     734       38921 :   return StringSwitch<ARM::ISAKind>(Arch)
     735       38921 :       .StartsWith("aarch64", ARM::ISAKind::AARCH64)
     736       38921 :       .StartsWith("arm64", ARM::ISAKind::AARCH64)
     737       38921 :       .StartsWith("thumb", ARM::ISAKind::THUMB)
     738       38921 :       .StartsWith("arm", ARM::ISAKind::ARM)
     739       38921 :       .Default(ARM::ISAKind::INVALID);
     740             : }
     741             : 
     742             : // Little/Big endian
     743       38287 : 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       37193 :       return ARM::EndianKind::LITTLE;
     753             :   }
     754             : 
     755             :   if (Arch.startswith("aarch64"))
     756           5 :     return ARM::EndianKind::LITTLE;
     757             : 
     758             :   return ARM::EndianKind::INVALID;
     759             : }
     760             : 
     761             : // Profile A/R/M
     762       42108 : ARM::ProfileKind ARM::parseArchProfile(StringRef Arch) {
     763       42108 :   Arch = getCanonicalArchName(Arch);
     764       42108 :   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           0 :   llvm_unreachable("Unhandled architecture");
     805             : }
     806             : 
     807             : // Version number (ex. v7 = 7).
     808       43025 : unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
     809       43025 :   Arch = getCanonicalArchName(Arch);
     810       43025 :   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           0 :   llvm_unreachable("Unhandled architecture");
     855             : }
     856             : 
     857        7527 : StringRef llvm::ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) {
     858             :   StringRef ArchName =
     859        7527 :       CPU.empty() ? TT.getArchName() : ARM::getArchName(ARM::parseCPUArch(CPU));
     860             : 
     861        7527 :   if (TT.isOSBinFormatMachO()) {
     862        3870 :     if (TT.getEnvironment() == Triple::EABI ||
     863        3758 :         TT.getOS() == Triple::UnknownOS ||
     864        1821 :         llvm::ARM::parseArchProfile(ArchName) == ARM::ProfileKind::M)
     865         170 :       return "aapcs";
     866        1767 :     if (TT.isWatchABI())
     867          77 :       return "aapcs16";
     868        1690 :     return "apcs-gnu";
     869        5590 :   } else if (TT.isOSWindows())
     870             :     // FIXME: this is invalid for WindowsCE.
     871         313 :     return "aapcs";
     872             : 
     873             :   // Select the default based on the platform.
     874        5277 :   switch (TT.getEnvironment()) {
     875             :   case Triple::Android:
     876             :   case Triple::GNUEABI:
     877             :   case Triple::GNUEABIHF:
     878             :   case Triple::MuslEABI:
     879             :   case Triple::MuslEABIHF:
     880        1894 :     return "aapcs-linux";
     881             :   case Triple::EABIHF:
     882             :   case Triple::EABI:
     883        2173 :     return "aapcs";
     884             :   default:
     885        1210 :     if (TT.isOSNetBSD())
     886          10 :       return "apcs-gnu";
     887        1200 :     if (TT.isOSOpenBSD())
     888          15 :       return "aapcs-linux";
     889        1185 :     return "aapcs";
     890             :   }
     891             : }
     892             : 
     893         286 : StringRef llvm::AArch64::getCanonicalArchName(StringRef Arch) {
     894         286 :   return ARM::getCanonicalArchName(Arch);
     895             : }
     896             : 
     897           0 : unsigned llvm::AArch64::parseFPU(StringRef FPU) {
     898           0 :   return ARM::parseFPU(FPU);
     899             : }
     900             : 
     901             : // Allows partial match, ex. "v8a" matches "armv8a".
     902         286 : AArch64::ArchKind AArch64::parseArch(StringRef Arch) {
     903         286 :   Arch = getCanonicalArchName(Arch);
     904         286 :   if (checkArchVersion(Arch) < 8)
     905             :     return ArchKind::INVALID;
     906             : 
     907         283 :   StringRef Syn = getArchSynonym(Arch);
     908        1179 :   for (const auto A : AArch64ARCHNames) {
     909             :     if (A.getName().endswith(Syn))
     910             :       return A.ID;
     911             :   }
     912             :   return ArchKind::INVALID;
     913             : }
     914             : 
     915          39 : AArch64::ArchExtKind llvm::AArch64::parseArchExt(StringRef ArchExt) {
     916         538 :   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         668 : AArch64::ArchKind llvm::AArch64::parseCPUArch(StringRef CPU) {
     924        5045 :   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           0 : ARM::ISAKind AArch64::parseArchISA(StringRef Arch) {
     933           0 :   return ARM::parseArchISA(Arch);
     934             : }
     935             : 
     936             : // Little/Big endian
     937           0 : ARM::EndianKind AArch64::parseArchEndian(StringRef Arch) {
     938           0 :   return ARM::parseArchEndian(Arch);
     939             : }
     940             : 
     941             : // Profile A/R/M
     942           0 : ARM::ProfileKind AArch64::parseArchProfile(StringRef Arch) {
     943           0 :   return ARM::parseArchProfile(Arch);
     944             : }
     945             : 
     946             : // Version number (ex. v8 = 8).
     947           0 : unsigned llvm::AArch64::parseArchVersion(StringRef Arch) {
     948           0 :   return ARM::parseArchVersion(Arch);
     949             : }
     950             : 
     951        1574 : bool llvm::AArch64::isX18ReservedByDefault(const Triple &TT) {
     952        2762 :   return TT.isAndroid() || TT.isOSDarwin() || TT.isOSFuchsia() ||
     953        1574 :          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[32] = {
     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             : };
    1034             : 
    1035         514 : const GPUInfo *getArchEntry(AMDGPU::GPUKind AK, ArrayRef<GPUInfo> Table) {
    1036             :   GPUInfo Search = { {""}, {""}, AK, AMDGPU::FEATURE_NONE };
    1037             : 
    1038             :   auto I = std::lower_bound(Table.begin(), Table.end(), Search,
    1039             :     [](const GPUInfo &A, const GPUInfo &B) {
    1040           0 :       return A.Kind < B.Kind;
    1041             :     });
    1042             : 
    1043         514 :   if (I == Table.end())
    1044           0 :     return nullptr;
    1045             :   return I;
    1046             : }
    1047             : 
    1048             : } // namespace
    1049             : 
    1050          77 : StringRef llvm::AMDGPU::getArchNameAMDGCN(GPUKind AK) {
    1051          77 :   if (const auto *Entry = getArchEntry(AK, AMDGCNGPUs))
    1052          77 :     return Entry->CanonicalName;
    1053           0 :   return "";
    1054             : }
    1055             : 
    1056          60 : StringRef llvm::AMDGPU::getArchNameR600(GPUKind AK) {
    1057          60 :   if (const auto *Entry = getArchEntry(AK, R600GPUs))
    1058          60 :     return Entry->CanonicalName;
    1059           0 :   return "";
    1060             : }
    1061             : 
    1062     1139922 : AMDGPU::GPUKind llvm::AMDGPU::parseArchAMDGCN(StringRef CPU) {
    1063    22412584 :   for (const auto C : AMDGCNGPUs) {
    1064             :     if (CPU == C.Name)
    1065             :       return C.Kind;
    1066             :   }
    1067             : 
    1068             :   return AMDGPU::GPUKind::GK_NONE;
    1069             : }
    1070             : 
    1071         226 : AMDGPU::GPUKind llvm::AMDGPU::parseArchR600(StringRef CPU) {
    1072        3736 :   for (const auto C : R600GPUs) {
    1073             :     if (CPU == C.Name)
    1074             :       return C.Kind;
    1075             :   }
    1076             : 
    1077             :   return AMDGPU::GPUKind::GK_NONE;
    1078             : }
    1079             : 
    1080         249 : unsigned AMDGPU::getArchAttrAMDGCN(GPUKind AK) {
    1081         249 :   if (const auto *Entry = getArchEntry(AK, AMDGCNGPUs))
    1082         249 :     return Entry->Features;
    1083             :   return FEATURE_NONE;
    1084             : }
    1085             : 
    1086         128 : unsigned AMDGPU::getArchAttrR600(GPUKind AK) {
    1087         128 :   if (const auto *Entry = getArchEntry(AK, R600GPUs))
    1088         128 :     return Entry->Features;
    1089             :   return FEATURE_NONE;
    1090             : }
    1091             : 
    1092           1 : void AMDGPU::fillValidArchListAMDGCN(SmallVectorImpl<StringRef> &Values) {
    1093             :   // XXX: Should this only report unique canonical names?
    1094          33 :   for (const auto C : AMDGCNGPUs)
    1095          32 :     Values.push_back(C.Name);
    1096           1 : }
    1097             : 
    1098           1 : void AMDGPU::fillValidArchListR600(SmallVectorImpl<StringRef> &Values) {
    1099          27 :   for (const auto C : R600GPUs)
    1100          26 :     Values.push_back(C.Name);
    1101           1 : }
    1102             : 
    1103     1433157 : AMDGPU::IsaVersion AMDGPU::getIsaVersion(StringRef GPU) {
    1104             :   if (GPU == "generic")
    1105      293883 :     return {7, 0, 0};
    1106             : 
    1107     1139274 :   AMDGPU::GPUKind AK = parseArchAMDGCN(GPU);
    1108     1139274 :   if (AK == AMDGPU::GPUKind::GK_NONE)
    1109         487 :     return {0, 0, 0};
    1110             : 
    1111     1138787 :   switch (AK) {
    1112       94749 :   case GK_GFX600: return {6, 0, 0};
    1113       86755 :   case GK_GFX601: return {6, 0, 1};
    1114       68994 :   case GK_GFX700: return {7, 0, 0};
    1115       45259 :   case GK_GFX701: return {7, 0, 1};
    1116         128 :   case GK_GFX702: return {7, 0, 2};
    1117         763 :   case GK_GFX703: return {7, 0, 3};
    1118       77787 :   case GK_GFX704: return {7, 0, 4};
    1119       21374 :   case GK_GFX801: return {8, 0, 1};
    1120      269241 :   case GK_GFX802: return {8, 0, 2};
    1121      178894 :   case GK_GFX803: return {8, 0, 3};
    1122        6624 :   case GK_GFX810: return {8, 1, 0};
    1123      270479 :   case GK_GFX900: return {9, 0, 0};
    1124        2110 :   case GK_GFX902: return {9, 0, 2};
    1125         130 :   case GK_GFX904: return {9, 0, 4};
    1126       15500 :   case GK_GFX906: return {9, 0, 6};
    1127           0 :   default:        return {0, 0, 0};
    1128             :   }
    1129             : }

Generated by: LCOV version 1.13