LCOV - code coverage report
Current view: top level - lib/Support - TargetParser.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 298 331 90.0 %
Date: 2018-07-13 00:08:38 Functions: 49 60 81.7 %
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/StringSwitch.h"
      18             : #include "llvm/ADT/Twine.h"
      19             : #include <cctype>
      20             : 
      21             : using namespace llvm;
      22             : using namespace ARM;
      23             : using namespace AArch64;
      24             : 
      25             : namespace {
      26             : 
      27             : // List of canonical FPU names (use getFPUSynonym) and which architectural
      28             : // features they correspond to (use getFPUFeatures).
      29             : // FIXME: TableGen this.
      30             : // The entries must appear in the order listed in ARM::FPUKind for correct indexing
      31             : static const struct {
      32             :   const char *NameCStr;
      33             :   size_t NameLength;
      34             :   ARM::FPUKind ID;
      35             :   ARM::FPUVersion FPUVersion;
      36             :   ARM::NeonSupportLevel NeonSupport;
      37             :   ARM::FPURestriction Restriction;
      38             : 
      39             :   StringRef getName() const { return StringRef(NameCStr, NameLength); }
      40             : } FPUNames[] = {
      41             : #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
      42             :   { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION },
      43             : #include "llvm/Support/ARMTargetParser.def"
      44             : };
      45             : 
      46             : // List of canonical arch names (use getArchSynonym).
      47             : // This table also provides the build attribute fields for CPU arch
      48             : // and Arch ID, according to the Addenda to the ARM ABI, chapters
      49             : // 2.4 and 2.3.5.2 respectively.
      50             : // FIXME: SubArch values were simplified to fit into the expectations
      51             : // of the triples and are not conforming with their official names.
      52             : // Check to see if the expectation should be changed.
      53             : // FIXME: TableGen this.
      54             : template <typename T> struct ArchNames {
      55             :   const char *NameCStr;
      56             :   size_t NameLength;
      57             :   const char *CPUAttrCStr;
      58             :   size_t CPUAttrLength;
      59             :   const char *SubArchCStr;
      60             :   size_t SubArchLength;
      61             :   unsigned DefaultFPU;
      62             :   unsigned ArchBaseExtensions;
      63             :   T ID;
      64             :   ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
      65             : 
      66             :   StringRef getName() const { return StringRef(NameCStr, NameLength); }
      67             : 
      68             :   // CPU class in build attributes.
      69             :   StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
      70             : 
      71             :   // Sub-Arch name.
      72             :   StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
      73             : };
      74             : ArchNames<ARM::ArchKind> ARCHNames[] = {
      75             : #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT)       \
      76             :   {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH,       \
      77             :    sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ARM::ArchKind::ID, ARCH_ATTR},
      78             : #include "llvm/Support/ARMTargetParser.def"
      79             : };
      80             : 
      81             : ArchNames<AArch64::ArchKind> AArch64ARCHNames[] = {
      82             :  #define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT)       \
      83             :    {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH,       \
      84             :     sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, AArch64::ArchKind::ID, ARCH_ATTR},
      85             :  #include "llvm/Support/AArch64TargetParser.def"
      86             :  };
      87             : 
      88             : 
      89             : // List of Arch Extension names.
      90             : // FIXME: TableGen this.
      91             : static const struct {
      92             :   const char *NameCStr;
      93             :   size_t NameLength;
      94             :   unsigned ID;
      95             :   const char *Feature;
      96             :   const char *NegFeature;
      97             : 
      98             :   StringRef getName() const { return StringRef(NameCStr, NameLength); }
      99             : } ARCHExtNames[] = {
     100             : #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
     101             :   { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
     102             : #include "llvm/Support/ARMTargetParser.def"
     103             : },AArch64ARCHExtNames[] = {
     104             : #define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
     105             :   { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
     106             : #include "llvm/Support/AArch64TargetParser.def"
     107             : };
     108             : 
     109             : // List of HWDiv names (use getHWDivSynonym) and which architectural
     110             : // features they correspond to (use getHWDivFeatures).
     111             : // FIXME: TableGen this.
     112             : static const struct {
     113             :   const char *NameCStr;
     114             :   size_t NameLength;
     115             :   unsigned ID;
     116             : 
     117             :   StringRef getName() const { return StringRef(NameCStr, NameLength); }
     118             : } HWDivNames[] = {
     119             : #define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
     120             : #include "llvm/Support/ARMTargetParser.def"
     121             : };
     122             : 
     123             : // List of CPU names and their arches.
     124             : // The same CPU can have multiple arches and can be default on multiple arches.
     125             : // When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
     126             : // When this becomes table-generated, we'd probably need two tables.
     127             : // FIXME: TableGen this.
     128             : template <typename T> struct CpuNames {
     129             :   const char *NameCStr;
     130             :   size_t NameLength;
     131             :   T ArchID;
     132             :   bool Default; // is $Name the default CPU for $ArchID ?
     133             :   unsigned DefaultExtensions;
     134             : 
     135             :   StringRef getName() const { return StringRef(NameCStr, NameLength); }
     136             : };
     137             : CpuNames<ARM::ArchKind> CPUNames[] = {
     138             : #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
     139             :   { NAME, sizeof(NAME) - 1, ARM::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
     140             : #include "llvm/Support/ARMTargetParser.def"
     141             : };
     142             : 
     143             : CpuNames<AArch64::ArchKind> AArch64CPUNames[] = {
     144             :  #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
     145             :    { NAME, sizeof(NAME) - 1, AArch64::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
     146             :  #include "llvm/Support/AArch64TargetParser.def"
     147             :  };
     148             : 
     149             : } // namespace
     150             : 
     151             : // ======================================================= //
     152             : // Information by ID
     153             : // ======================================================= //
     154             : 
     155        1287 : StringRef ARM::getFPUName(unsigned FPUKind) {
     156        1287 :   if (FPUKind >= ARM::FK_LAST)
     157           0 :     return StringRef();
     158        1287 :   return FPUNames[FPUKind].getName();
     159             : }
     160             : 
     161          23 : FPUVersion ARM::getFPUVersion(unsigned FPUKind) {
     162          23 :   if (FPUKind >= ARM::FK_LAST)
     163             :     return FPUVersion::NONE;
     164          22 :   return FPUNames[FPUKind].FPUVersion;
     165             : }
     166             : 
     167          23 : ARM::NeonSupportLevel ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
     168          23 :   if (FPUKind >= ARM::FK_LAST)
     169             :     return ARM::NeonSupportLevel::None;
     170          22 :   return FPUNames[FPUKind].NeonSupport;
     171             : }
     172             : 
     173          23 : ARM::FPURestriction ARM::getFPURestriction(unsigned FPUKind) {
     174          23 :   if (FPUKind >= ARM::FK_LAST)
     175             :     return ARM::FPURestriction::None;
     176          22 :   return FPUNames[FPUKind].Restriction;
     177             : }
     178             : 
     179         713 : unsigned llvm::ARM::getDefaultFPU(StringRef CPU, ArchKind AK) {
     180             :   if (CPU == "generic")
     181          34 :     return ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
     182             : 
     183         679 :   return StringSwitch<unsigned>(CPU)
     184             : #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
     185             :     .Case(NAME, DEFAULT_FPU)
     186             : #include "llvm/Support/ARMTargetParser.def"
     187             :     .Default(ARM::FK_INVALID);
     188             : }
     189             : 
     190         814 : unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, ArchKind AK) {
     191             :   if (CPU == "generic")
     192          63 :     return ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
     193             : 
     194         751 :   return StringSwitch<unsigned>(CPU)
     195             : #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
     196             :     .Case(NAME, ARCHNames[static_cast<unsigned>(ARM::ArchKind::ID)]\
     197             :             .ArchBaseExtensions | DEFAULT_EXT)
     198             : #include "llvm/Support/ARMTargetParser.def"
     199             :     .Default(ARM::AEK_INVALID);
     200             : }
     201             : 
     202        6237 : bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
     203             :                                  std::vector<StringRef> &Features) {
     204             : 
     205        6237 :   if (HWDivKind == ARM::AEK_INVALID)
     206             :     return false;
     207             : 
     208        6237 :   if (HWDivKind & ARM::AEK_HWDIVARM)
     209        3075 :     Features.push_back("+hwdiv-arm");
     210             :   else
     211        3162 :     Features.push_back("-hwdiv-arm");
     212             : 
     213        6237 :   if (HWDivKind & ARM::AEK_HWDIVTHUMB)
     214        3100 :     Features.push_back("+hwdiv");
     215             :   else
     216        3137 :     Features.push_back("-hwdiv");
     217             : 
     218             :   return true;
     219             : }
     220             : 
     221        6686 : bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
     222             :                                      std::vector<StringRef> &Features) {
     223             : 
     224        6686 :   if (Extensions == ARM::AEK_INVALID)
     225             :     return false;
     226             : 
     227        6226 :   if (Extensions & ARM::AEK_CRC)
     228        3033 :     Features.push_back("+crc");
     229             :   else
     230        3193 :     Features.push_back("-crc");
     231             : 
     232        6226 :   if (Extensions & ARM::AEK_DSP)
     233        3106 :     Features.push_back("+dsp");
     234             :   else
     235        3120 :     Features.push_back("-dsp");
     236             : 
     237        6226 :   if (Extensions & ARM::AEK_RAS)
     238        1914 :     Features.push_back("+ras");
     239             :   else
     240        4312 :     Features.push_back("-ras");
     241             : 
     242        6226 :   if (Extensions & ARM::AEK_DOTPROD)
     243           3 :     Features.push_back("+dotprod");
     244             :   else
     245        6223 :     Features.push_back("-dotprod");
     246             : 
     247        6226 :   return getHWDivFeatures(Extensions, Features);
     248             : }
     249             : 
     250        1311 : bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
     251             :                                std::vector<StringRef> &Features) {
     252             : 
     253        1311 :   if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
     254             :     return false;
     255             : 
     256             :   // fp-only-sp and d16 subtarget features are independent of each other, so we
     257             :   // must enable/disable both.
     258         856 :   switch (FPUNames[FPUKind].Restriction) {
     259             :   case ARM::FPURestriction::SP_D16:
     260          15 :     Features.push_back("+fp-only-sp");
     261          15 :     Features.push_back("+d16");
     262          15 :     break;
     263             :   case ARM::FPURestriction::D16:
     264          20 :     Features.push_back("-fp-only-sp");
     265          20 :     Features.push_back("+d16");
     266          20 :     break;
     267             :   case ARM::FPURestriction::None:
     268         821 :     Features.push_back("-fp-only-sp");
     269         821 :     Features.push_back("-d16");
     270         821 :     break;
     271             :   }
     272             : 
     273             :   // FPU version subtarget features are inclusive of lower-numbered ones, so
     274             :   // enable the one corresponding to this version and disable all that are
     275             :   // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
     276             :   // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
     277         856 :   switch (FPUNames[FPUKind].FPUVersion) {
     278             :   case ARM::FPUVersion::VFPV5:
     279          41 :     Features.push_back("+fp-armv8");
     280          41 :     break;
     281             :   case ARM::FPUVersion::VFPV4:
     282          44 :     Features.push_back("+vfp4");
     283          44 :     Features.push_back("-fp-armv8");
     284          44 :     break;
     285             :   case ARM::FPUVersion::VFPV3_FP16:
     286          17 :     Features.push_back("+vfp3");
     287          17 :     Features.push_back("+fp16");
     288          17 :     Features.push_back("-vfp4");
     289          17 :     Features.push_back("-fp-armv8");
     290          17 :     break;
     291             :   case ARM::FPUVersion::VFPV3:
     292          89 :     Features.push_back("+vfp3");
     293          89 :     Features.push_back("-fp16");
     294          89 :     Features.push_back("-vfp4");
     295          89 :     Features.push_back("-fp-armv8");
     296          89 :     break;
     297             :   case ARM::FPUVersion::VFPV2:
     298          13 :     Features.push_back("+vfp2");
     299          13 :     Features.push_back("-vfp3");
     300          13 :     Features.push_back("-fp16");
     301          13 :     Features.push_back("-vfp4");
     302          13 :     Features.push_back("-fp-armv8");
     303          13 :     break;
     304             :   case ARM::FPUVersion::NONE:
     305         652 :     Features.push_back("-vfp2");
     306         652 :     Features.push_back("-vfp3");
     307         652 :     Features.push_back("-fp16");
     308         652 :     Features.push_back("-vfp4");
     309         652 :     Features.push_back("-fp-armv8");
     310         652 :     break;
     311             :   }
     312             : 
     313             :   // crypto includes neon, so we handle this similarly to FPU version.
     314         856 :   switch (FPUNames[FPUKind].NeonSupport) {
     315             :   case ARM::NeonSupportLevel::Crypto:
     316          27 :     Features.push_back("+neon");
     317          27 :     Features.push_back("+crypto");
     318          27 :     break;
     319             :   case ARM::NeonSupportLevel::Neon:
     320         112 :     Features.push_back("+neon");
     321         112 :     Features.push_back("-crypto");
     322         112 :     break;
     323             :   case ARM::NeonSupportLevel::None:
     324         717 :     Features.push_back("-neon");
     325         717 :     Features.push_back("-crypto");
     326         717 :     break;
     327             :   }
     328             : 
     329             :   return true;
     330             : }
     331             : 
     332        8744 : StringRef llvm::ARM::getArchName(ArchKind AK) {
     333        8744 :   return ARCHNames[static_cast<unsigned>(AK)].getName();
     334             : }
     335             : 
     336         364 : StringRef llvm::ARM::getCPUAttr(ArchKind AK) {
     337         364 :   return ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
     338             : }
     339             : 
     340        2243 : StringRef llvm::ARM::getSubArch(ArchKind AK) {
     341        2243 :   return ARCHNames[static_cast<unsigned>(AK)].getSubArch();
     342             : }
     343             : 
     344          70 : unsigned llvm::ARM::getArchAttr(ArchKind AK) {
     345          70 :   return ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
     346             : }
     347             : 
     348           3 : StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
     349          57 :   for (const auto AE : ARCHExtNames) {
     350          30 :     if (ArchExtKind == AE.ID)
     351             :       return AE.getName();
     352             :   }
     353           0 :   return StringRef();
     354             : }
     355             : 
     356          43 : StringRef llvm::ARM::getArchExtFeature(StringRef ArchExt) {
     357             :   if (ArchExt.startswith("no")) {
     358             :     StringRef ArchExtBase(ArchExt.substr(2));
     359         592 :     for (const auto AE : ARCHExtNames) {
     360         295 :       if (AE.NegFeature && ArchExtBase == AE.getName())
     361           8 :         return StringRef(AE.NegFeature);
     362             :     }
     363             :   }
     364        1167 :   for (const auto AE : ARCHExtNames) {
     365         579 :     if (AE.Feature && ArchExt == AE.getName())
     366          13 :       return StringRef(AE.Feature);
     367             :   }
     368             : 
     369          22 :   return StringRef();
     370             : }
     371             : 
     372           0 : StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
     373           0 :   for (const auto D : HWDivNames) {
     374           0 :     if (HWDivKind == D.ID)
     375             :       return D.getName();
     376             :   }
     377           0 :   return StringRef();
     378             : }
     379             : 
     380        3128 : StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
     381        3128 :   ArchKind AK = parseArch(Arch);
     382        3128 :   if (AK == ARM::ArchKind::INVALID)
     383         546 :     return StringRef();
     384             : 
     385             :   // Look for multiple AKs to find the default for pair AK+Name.
     386      318876 :   for (const auto CPU : CPUNames) {
     387      159276 :     if (CPU.ArchID == AK && CPU.Default)
     388             :       return CPU.getName();
     389             :   }
     390             : 
     391             :   // If we can't find a default then target the architecture instead
     392        1453 :   return "generic";
     393             : }
     394             : 
     395          21 : StringRef llvm::AArch64::getFPUName(unsigned FPUKind) {
     396          21 :   return ARM::getFPUName(FPUKind);
     397             : }
     398             : 
     399           0 : ARM::FPUVersion AArch64::getFPUVersion(unsigned FPUKind) {
     400           0 :   return ARM::getFPUVersion(FPUKind);
     401             : }
     402             : 
     403           0 : ARM::NeonSupportLevel AArch64::getFPUNeonSupportLevel(unsigned FPUKind) {
     404           0 :   return ARM::getFPUNeonSupportLevel( FPUKind);
     405             : }
     406             : 
     407           0 : ARM::FPURestriction AArch64::getFPURestriction(unsigned FPUKind) {
     408           0 :   return ARM::getFPURestriction(FPUKind);
     409             : }
     410             : 
     411          21 : unsigned llvm::AArch64::getDefaultFPU(StringRef CPU, ArchKind AK) {
     412             :   if (CPU == "generic")
     413           1 :     return AArch64ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
     414             : 
     415          20 :   return StringSwitch<unsigned>(CPU)
     416             : #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
     417             :     .Case(NAME, DEFAULT_FPU)
     418             : #include "llvm/Support/AArch64TargetParser.def"
     419             :     .Default(ARM::FK_INVALID);
     420             : }
     421             : 
     422         661 : unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, ArchKind AK) {
     423             :   if (CPU == "generic")
     424          15 :     return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
     425             : 
     426         646 :   return StringSwitch<unsigned>(CPU)
     427             : #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)       \
     428             :   .Case(NAME,                                                                  \
     429             :         AArch64ARCHNames[static_cast<unsigned>(AArch64::ArchKind::ID)] \
     430             :             .ArchBaseExtensions | \
     431             :             DEFAULT_EXT)
     432             : #include "llvm/Support/AArch64TargetParser.def"
     433             :     .Default(AArch64::AEK_INVALID);
     434             : }
     435             : 
     436        8802 : bool llvm::AArch64::getExtensionFeatures(unsigned Extensions,
     437             :                                      std::vector<StringRef> &Features) {
     438             : 
     439        8802 :   if (Extensions == AArch64::AEK_INVALID)
     440             :     return false;
     441             : 
     442        8801 :   if (Extensions & AArch64::AEK_FP)
     443        4706 :     Features.push_back("+fp-armv8");
     444        8801 :   if (Extensions & AArch64::AEK_SIMD)
     445        4706 :     Features.push_back("+neon");
     446        8801 :   if (Extensions & AArch64::AEK_CRC)
     447        4625 :     Features.push_back("+crc");
     448        8801 :   if (Extensions & AArch64::AEK_CRYPTO)
     449        4706 :     Features.push_back("+crypto");
     450        8801 :   if (Extensions & AArch64::AEK_DOTPROD)
     451        4170 :     Features.push_back("+dotprod");
     452        8801 :   if (Extensions & AArch64::AEK_FP16)
     453        4170 :     Features.push_back("+fullfp16");
     454        8801 :   if (Extensions & AArch64::AEK_PROFILE)
     455        4095 :     Features.push_back("+spe");
     456        8801 :   if (Extensions & AArch64::AEK_RAS)
     457        4170 :     Features.push_back("+ras");
     458        8801 :   if (Extensions & AArch64::AEK_LSE)
     459        4213 :     Features.push_back("+lse");
     460        8801 :   if (Extensions & AArch64::AEK_RDM)
     461        4232 :     Features.push_back("+rdm");
     462        8801 :   if (Extensions & AArch64::AEK_SVE)
     463        4095 :     Features.push_back("+sve");
     464        8801 :   if (Extensions & AArch64::AEK_RCPC)
     465        4170 :     Features.push_back("+rcpc");
     466             : 
     467             :   return true;
     468             : }
     469             : 
     470           0 : bool llvm::AArch64::getFPUFeatures(unsigned FPUKind,
     471             :                                std::vector<StringRef> &Features) {
     472           0 :   return ARM::getFPUFeatures(FPUKind, Features);
     473             : }
     474             : 
     475         694 : bool llvm::AArch64::getArchFeatures(AArch64::ArchKind AK,
     476             :                                     std::vector<StringRef> &Features) {
     477         694 :   if (AK == AArch64::ArchKind::ARMV8_1A)
     478          75 :     Features.push_back("+v8.1a");
     479         694 :   if (AK == AArch64::ArchKind::ARMV8_2A)
     480          93 :     Features.push_back("+v8.2a");
     481         694 :   if (AK == AArch64::ArchKind::ARMV8_3A)
     482           4 :     Features.push_back("+v8.3a");
     483         694 :   if (AK == AArch64::ArchKind::ARMV8_4A)
     484           1 :     Features.push_back("+v8.4a");
     485             : 
     486         694 :   return AK != AArch64::ArchKind::INVALID;
     487             : }
     488             : 
     489          21 : StringRef llvm::AArch64::getArchName(ArchKind AK) {
     490          21 :   return AArch64ARCHNames[static_cast<unsigned>(AK)].getName();
     491             : }
     492             : 
     493          21 : StringRef llvm::AArch64::getCPUAttr(ArchKind AK) {
     494          21 :   return AArch64ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
     495             : }
     496             : 
     497           4 : StringRef llvm::AArch64::getSubArch(ArchKind AK) {
     498           4 :   return AArch64ARCHNames[static_cast<unsigned>(AK)].getSubArch();
     499             : }
     500             : 
     501           4 : unsigned llvm::AArch64::getArchAttr(ArchKind AK) {
     502           4 :   return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
     503             : }
     504             : 
     505           0 : StringRef llvm::AArch64::getArchExtName(unsigned ArchExtKind) {
     506           0 :   for (const auto &AE : AArch64ARCHExtNames)
     507           0 :     if (ArchExtKind == AE.ID)
     508           0 :       return AE.getName();
     509           0 :   return StringRef();
     510             : }
     511             : 
     512         128 : StringRef llvm::AArch64::getArchExtFeature(StringRef ArchExt) {
     513             :   if (ArchExt.startswith("no")) {
     514             :     StringRef ArchExtBase(ArchExt.substr(2));
     515        1181 :     for (const auto &AE : AArch64ARCHExtNames) {
     516         619 :       if (AE.NegFeature && ArchExtBase == AE.getName())
     517          60 :         return StringRef(AE.NegFeature);
     518             :     }
     519             :   }
     520             : 
     521        1310 :   for (const auto &AE : AArch64ARCHExtNames)
     522         683 :     if (AE.Feature && ArchExt == AE.getName())
     523          62 :       return StringRef(AE.Feature);
     524           6 :   return StringRef();
     525             : }
     526             : 
     527           4 : StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) {
     528           4 :   AArch64::ArchKind AK = parseArch(Arch);
     529           4 :   if (AK == ArchKind::INVALID)
     530           0 :     return StringRef();
     531             : 
     532             :   // Look for multiple AKs to find the default for pair AK+Name.
     533         132 :   for (const auto &CPU : AArch64CPUNames)
     534          65 :     if (CPU.ArchID == AK && CPU.Default)
     535           1 :       return CPU.getName();
     536             : 
     537             :   // If we can't find a default then target the architecture instead
     538           3 :   return "generic";
     539             : }
     540             : 
     541          98 : unsigned llvm::AArch64::checkArchVersion(StringRef Arch) {
     542         291 :   if (Arch.size() >= 2 && Arch[0] == 'v' && std::isdigit(Arch[1]))
     543          95 :     return (Arch[1] - 48);
     544             :   return 0;
     545             : }
     546             : 
     547             : // ======================================================= //
     548             : // Parsers
     549             : // ======================================================= //
     550             : 
     551          15 : static StringRef getHWDivSynonym(StringRef HWDiv) {
     552          15 :   return StringSwitch<StringRef>(HWDiv)
     553             :       .Case("thumb,arm", "arm,thumb")
     554          15 :       .Default(HWDiv);
     555             : }
     556             : 
     557          67 : static StringRef getFPUSynonym(StringRef FPU) {
     558          67 :   return StringSwitch<StringRef>(FPU)
     559             :       .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
     560             :       .Case("vfp2", "vfpv2")
     561             :       .Case("vfp3", "vfpv3")
     562             :       .Case("vfp4", "vfpv4")
     563             :       .Case("vfp3-d16", "vfpv3-d16")
     564             :       .Case("vfp4-d16", "vfpv4-d16")
     565             :       .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
     566             :       .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
     567             :       .Case("fp5-sp-d16", "fpv5-sp-d16")
     568             :       .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
     569             :       // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
     570             :       .Case("neon-vfpv3", "neon")
     571          67 :       .Default(FPU);
     572             : }
     573             : 
     574     1044523 : static StringRef getArchSynonym(StringRef Arch) {
     575     1044525 :   return StringSwitch<StringRef>(Arch)
     576             :       .Case("v5", "v5t")
     577             :       .Case("v5e", "v5te")
     578             :       .Case("v6j", "v6")
     579             :       .Case("v6hl", "v6k")
     580             :       .Cases("v6m", "v6sm", "v6s-m", "v6-m")
     581             :       .Cases("v6z", "v6zk", "v6kz")
     582             :       .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
     583             :       .Case("v7r", "v7-r")
     584             :       .Case("v7m", "v7-m")
     585             :       .Case("v7em", "v7e-m")
     586             :       .Cases("v8", "v8a", "v8l", "aarch64", "arm64", "v8-a")
     587             :       .Case("v8.1a", "v8.1-a")
     588             :       .Case("v8.2a", "v8.2-a")
     589             :       .Case("v8.3a", "v8.3-a")
     590             :       .Case("v8.4a", "v8.4-a")
     591             :       .Case("v8r", "v8-r")
     592             :       .Case("v8m.base", "v8-m.base")
     593             :       .Case("v8m.main", "v8-m.main")
     594     1044525 :       .Default(Arch);
     595             : }
     596             : 
     597             : // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
     598             : // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
     599             : // "v.+", if the latter, return unmodified string, minus 'eb'.
     600             : // If invalid, return empty string.
     601     2192195 : StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
     602             :   size_t offset = StringRef::npos;
     603     2192195 :   StringRef A = Arch;
     604             :   StringRef Error = "";
     605             : 
     606             :   // Begins with "arm" / "thumb", move past it.
     607             :   if (A.startswith("arm64"))
     608             :     offset = 5;
     609             :   else if (A.startswith("arm"))
     610             :     offset = 3;
     611             :   else if (A.startswith("thumb"))
     612             :     offset = 5;
     613             :   else if (A.startswith("aarch64")) {
     614             :     offset = 7;
     615             :     // AArch64 uses "_be", not "eb" suffix.
     616       48131 :     if (A.find("eb") != StringRef::npos)
     617           0 :       return Error;
     618             :     if (A.substr(offset, 3) == "_be")
     619             :       offset += 3;
     620             :   }
     621             : 
     622             :   // Ex. "armebv7", move past the "eb".
     623             :   if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
     624        2794 :     offset += 2;
     625             :   // Or, if it ends with eb ("armv7eb"), chop it off.
     626             :   else if (A.endswith("eb"))
     627         936 :     A = A.substr(0, A.size() - 2);
     628             :   // Trim the head
     629     2192196 :   if (offset != StringRef::npos)
     630      180599 :     A = A.substr(offset);
     631             : 
     632             :   // Empty string means offset reached the end, which means it's valid.
     633     2192196 :   if (A.empty())
     634      176048 :     return Arch;
     635             : 
     636             :   // Only match non-marketing names
     637     2016148 :   if (offset != StringRef::npos) {
     638             :     // Must start with 'vN'.
     639      259930 :     if (A.size() >= 2 && (A[0] != 'v' || !std::isdigit(A[1])))
     640          42 :       return Error;
     641             :     // Can't have an extra 'eb'.
     642       86638 :     if (A.find("eb") != StringRef::npos)
     643           3 :       return Error;
     644             :   }
     645             : 
     646             :   // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
     647     2016103 :   return A;
     648             : }
     649             : 
     650          15 : unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
     651          15 :   StringRef Syn = getHWDivSynonym(HWDiv);
     652         101 :   for (const auto D : HWDivNames) {
     653             :     if (Syn == D.getName())
     654             :       return D.ID;
     655             :   }
     656             :   return ARM::AEK_INVALID;
     657             : }
     658             : 
     659          67 : unsigned llvm::ARM::parseFPU(StringRef FPU) {
     660          67 :   StringRef Syn = getFPUSynonym(FPU);
     661        1725 :   for (const auto F : FPUNames) {
     662             :     if (Syn == F.getName())
     663             :       return F.ID;
     664             :   }
     665             :   return ARM::FK_INVALID;
     666             : }
     667             : 
     668             : // Allows partial match, ex. "v7a" matches "armv7a".
     669     1044427 : ARM::ArchKind ARM::parseArch(StringRef Arch) {
     670     1044427 :   Arch = getCanonicalArchName(Arch);
     671     1044429 :   StringRef Syn = getArchSynonym(Arch);
     672    64753773 :   for (const auto A : ARCHNames) {
     673             :     if (A.getName().endswith(Syn))
     674             :       return A.ID;
     675             :   }
     676             :   return ARM::ArchKind::INVALID;
     677             : }
     678             : 
     679         125 : unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
     680        2389 :   for (const auto A : ARCHExtNames) {
     681             :     if (ArchExt == A.getName())
     682             :       return A.ID;
     683             :   }
     684             :   return ARM::AEK_INVALID;
     685             : }
     686             : 
     687        4269 : ARM::ArchKind llvm::ARM::parseCPUArch(StringRef CPU) {
     688      442449 :   for (const auto C : CPUNames) {
     689             :     if (CPU == C.getName())
     690             :       return C.ArchID;
     691             :   }
     692             :   return ARM::ArchKind::INVALID;
     693             : }
     694             : 
     695           3 : void llvm::ARM::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
     696         507 :   for (const CpuNames<ARM::ArchKind> &Arch : CPUNames) {
     697         252 :     if (Arch.ArchID != ARM::ArchKind::INVALID)
     698         249 :       Values.push_back(Arch.getName());
     699             :   }
     700           3 : }
     701             : 
     702           2 : void llvm::AArch64::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
     703          86 :   for (const CpuNames<AArch64::ArchKind> &Arch : AArch64CPUNames) {
     704          42 :     if (Arch.ArchID != AArch64::ArchKind::INVALID)
     705          40 :       Values.push_back(Arch.getName());
     706             :   }
     707           2 : }
     708             : 
     709             : // ARM, Thumb, AArch64
     710       38287 : ARM::ISAKind ARM::parseArchISA(StringRef Arch) {
     711       38287 :   return StringSwitch<ARM::ISAKind>(Arch)
     712             :       .StartsWith("aarch64", ARM::ISAKind::AARCH64)
     713             :       .StartsWith("arm64", ARM::ISAKind::AARCH64)
     714             :       .StartsWith("thumb", ARM::ISAKind::THUMB)
     715             :       .StartsWith("arm", ARM::ISAKind::ARM)
     716       38287 :       .Default(ARM::ISAKind::INVALID);
     717             : }
     718             : 
     719             : // Little/Big endian
     720       37678 : ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
     721             :   if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
     722             :       Arch.startswith("aarch64_be"))
     723             :     return ARM::EndianKind::BIG;
     724             : 
     725             :   if (Arch.startswith("arm") || Arch.startswith("thumb")) {
     726             :     if (Arch.endswith("eb"))
     727             :       return ARM::EndianKind::BIG;
     728             :     else
     729             :       return ARM::EndianKind::LITTLE;
     730             :   }
     731             : 
     732             :   if (Arch.startswith("aarch64"))
     733             :     return ARM::EndianKind::LITTLE;
     734             : 
     735             :   return ARM::EndianKind::INVALID;
     736             : }
     737             : 
     738             : // Profile A/R/M
     739       41398 : ARM::ProfileKind ARM::parseArchProfile(StringRef Arch) {
     740       41398 :   Arch = getCanonicalArchName(Arch);
     741       41398 :   switch (parseArch(Arch)) {
     742             :   case ARM::ArchKind::ARMV6M:
     743             :   case ARM::ArchKind::ARMV7M:
     744             :   case ARM::ArchKind::ARMV7EM:
     745             :   case ARM::ArchKind::ARMV8MMainline:
     746             :   case ARM::ArchKind::ARMV8MBaseline:
     747             :     return ARM::ProfileKind::M;
     748         352 :   case ARM::ArchKind::ARMV7R:
     749             :   case ARM::ArchKind::ARMV8R:
     750         352 :     return ARM::ProfileKind::R;
     751       29850 :   case ARM::ArchKind::ARMV7A:
     752             :   case ARM::ArchKind::ARMV7VE:
     753             :   case ARM::ArchKind::ARMV7K:
     754             :   case ARM::ArchKind::ARMV8A:
     755             :   case ARM::ArchKind::ARMV8_1A:
     756             :   case ARM::ArchKind::ARMV8_2A:
     757             :   case ARM::ArchKind::ARMV8_3A:
     758             :   case ARM::ArchKind::ARMV8_4A:
     759       29850 :     return ARM::ProfileKind::A;
     760        7013 :   case ARM::ArchKind::ARMV2:
     761             :   case ARM::ArchKind::ARMV2A:
     762             :   case ARM::ArchKind::ARMV3:
     763             :   case ARM::ArchKind::ARMV3M:
     764             :   case ARM::ArchKind::ARMV4:
     765             :   case ARM::ArchKind::ARMV4T:
     766             :   case ARM::ArchKind::ARMV5T:
     767             :   case ARM::ArchKind::ARMV5TE:
     768             :   case ARM::ArchKind::ARMV5TEJ:
     769             :   case ARM::ArchKind::ARMV6:
     770             :   case ARM::ArchKind::ARMV6K:
     771             :   case ARM::ArchKind::ARMV6T2:
     772             :   case ARM::ArchKind::ARMV6KZ:
     773             :   case ARM::ArchKind::ARMV7S:
     774             :   case ARM::ArchKind::IWMMXT:
     775             :   case ARM::ArchKind::IWMMXT2:
     776             :   case ARM::ArchKind::XSCALE:
     777             :   case ARM::ArchKind::INVALID:
     778        7013 :     return ARM::ProfileKind::INVALID;
     779             :   }
     780           0 :   llvm_unreachable("Unhandled architecture");
     781             : }
     782             : 
     783             : // Version number (ex. v7 = 7).
     784       42048 : unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
     785       42048 :   Arch = getCanonicalArchName(Arch);
     786       42048 :   switch (parseArch(Arch)) {
     787             :   case ARM::ArchKind::ARMV2:
     788             :   case ARM::ArchKind::ARMV2A:
     789             :     return 2;
     790           2 :   case ARM::ArchKind::ARMV3:
     791             :   case ARM::ArchKind::ARMV3M:
     792           2 :     return 3;
     793        2613 :   case ARM::ArchKind::ARMV4:
     794             :   case ARM::ArchKind::ARMV4T:
     795        2613 :     return 4;
     796        1039 :   case ARM::ArchKind::ARMV5T:
     797             :   case ARM::ArchKind::ARMV5TE:
     798             :   case ARM::ArchKind::IWMMXT:
     799             :   case ARM::ArchKind::IWMMXT2:
     800             :   case ARM::ArchKind::XSCALE:
     801             :   case ARM::ArchKind::ARMV5TEJ:
     802        1039 :     return 5;
     803        4147 :   case ARM::ArchKind::ARMV6:
     804             :   case ARM::ArchKind::ARMV6K:
     805             :   case ARM::ArchKind::ARMV6T2:
     806             :   case ARM::ArchKind::ARMV6KZ:
     807             :   case ARM::ArchKind::ARMV6M:
     808        4147 :     return 6;
     809       29141 :   case ARM::ArchKind::ARMV7A:
     810             :   case ARM::ArchKind::ARMV7VE:
     811             :   case ARM::ArchKind::ARMV7R:
     812             :   case ARM::ArchKind::ARMV7M:
     813             :   case ARM::ArchKind::ARMV7S:
     814             :   case ARM::ArchKind::ARMV7EM:
     815             :   case ARM::ArchKind::ARMV7K:
     816       29141 :     return 7;
     817        5031 :   case ARM::ArchKind::ARMV8A:
     818             :   case ARM::ArchKind::ARMV8_1A:
     819             :   case ARM::ArchKind::ARMV8_2A:
     820             :   case ARM::ArchKind::ARMV8_3A:
     821             :   case ARM::ArchKind::ARMV8_4A:
     822             :   case ARM::ArchKind::ARMV8R:
     823             :   case ARM::ArchKind::ARMV8MBaseline:
     824             :   case ARM::ArchKind::ARMV8MMainline:
     825        5031 :     return 8;
     826          73 :   case ARM::ArchKind::INVALID:
     827          73 :     return 0;
     828             :   }
     829           0 :   llvm_unreachable("Unhandled architecture");
     830             : }
     831             : 
     832        7211 : StringRef llvm::ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) {
     833             :   StringRef ArchName =
     834        7211 :       CPU.empty() ? TT.getArchName() : ARM::getArchName(ARM::parseCPUArch(CPU));
     835             : 
     836        7211 :   if (TT.isOSBinFormatMachO()) {
     837        3848 :     if (TT.getEnvironment() == Triple::EABI ||
     838        3742 :         TT.getOS() == Triple::UnknownOS ||
     839        1816 :         llvm::ARM::parseArchProfile(ArchName) == ARM::ProfileKind::M)
     840         164 :       return "aapcs";
     841        1762 :     if (TT.isWatchABI())
     842          77 :       return "aapcs16";
     843        1685 :     return "apcs-gnu";
     844        5285 :   } else if (TT.isOSWindows())
     845             :     // FIXME: this is invalid for WindowsCE.
     846         307 :     return "aapcs";
     847             : 
     848             :   // Select the default based on the platform.
     849        4978 :   switch (TT.getEnvironment()) {
     850             :   case Triple::Android:
     851             :   case Triple::GNUEABI:
     852             :   case Triple::GNUEABIHF:
     853             :   case Triple::MuslEABI:
     854             :   case Triple::MuslEABIHF:
     855        1832 :     return "aapcs-linux";
     856             :   case Triple::EABIHF:
     857             :   case Triple::EABI:
     858        2067 :     return "aapcs";
     859             :   default:
     860        1079 :     if (TT.isOSNetBSD())
     861          10 :       return "apcs-gnu";
     862        1069 :     if (TT.isOSOpenBSD())
     863          13 :       return "aapcs-linux";
     864        1056 :     return "aapcs";
     865             :   }
     866             : }
     867             : 
     868          98 : StringRef llvm::AArch64::getCanonicalArchName(StringRef Arch) {
     869          98 :   return ARM::getCanonicalArchName(Arch);
     870             : }
     871             : 
     872           0 : unsigned llvm::AArch64::parseFPU(StringRef FPU) {
     873           0 :   return ARM::parseFPU(FPU);
     874             : }
     875             : 
     876             : // Allows partial match, ex. "v8a" matches "armv8a".
     877          98 : AArch64::ArchKind AArch64::parseArch(StringRef Arch) {
     878          98 :   Arch = getCanonicalArchName(Arch);
     879          98 :   if (checkArchVersion(Arch) < 8)
     880             :     return ArchKind::INVALID;
     881             : 
     882          95 :   StringRef Syn = getArchSynonym(Arch);
     883         463 :   for (const auto A : AArch64ARCHNames) {
     884             :     if (A.getName().endswith(Syn))
     885             :       return A.ID;
     886             :   }
     887             :   return ArchKind::INVALID;
     888             : }
     889             : 
     890          29 : AArch64::ArchExtKind llvm::AArch64::parseArchExt(StringRef ArchExt) {
     891         723 :   for (const auto A : AArch64ARCHExtNames) {
     892             :     if (ArchExt == A.getName())
     893             :       return static_cast<ArchExtKind>(A.ID);
     894             :   }
     895             :   return AArch64::AEK_INVALID;
     896             : }
     897             : 
     898         664 : AArch64::ArchKind llvm::AArch64::parseCPUArch(StringRef CPU) {
     899        9410 :   for (const auto C : AArch64CPUNames) {
     900             :     if (CPU == C.getName())
     901             :       return C.ArchID;
     902             :   }
     903             :   return ArchKind::INVALID;
     904             : }
     905             : 
     906             : // ARM, Thumb, AArch64
     907           0 : ARM::ISAKind AArch64::parseArchISA(StringRef Arch) {
     908           0 :   return ARM::parseArchISA(Arch);
     909             : }
     910             : 
     911             : // Little/Big endian
     912           0 : ARM::EndianKind AArch64::parseArchEndian(StringRef Arch) {
     913           0 :   return ARM::parseArchEndian(Arch);
     914             : }
     915             : 
     916             : // Profile A/R/M
     917           0 : ARM::ProfileKind AArch64::parseArchProfile(StringRef Arch) {
     918           0 :   return ARM::parseArchProfile(Arch);
     919             : }
     920             : 
     921             : // Version number (ex. v8 = 8).
     922           0 : unsigned llvm::AArch64::parseArchVersion(StringRef Arch) {
     923           0 :   return ARM::parseArchVersion(Arch);
     924             : }
     925             : 
     926        1441 : bool llvm::AArch64::isX18ReservedByDefault(const Triple &TT) {
     927        1079 :   return TT.isOSDarwin() || TT.isOSFuchsia() || TT.isOSWindows();
     928             : }

Generated by: LCOV version 1.13