LCOV - code coverage report
Current view: top level - lib/Support - TargetParser.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 319 352 90.6 %
Date: 2018-02-21 06:32:55 Functions: 48 59 81.4 %
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        1252 : StringRef ARM::getFPUName(unsigned FPUKind) {
     156        1252 :   if (FPUKind >= ARM::FK_LAST)
     157           0 :     return StringRef();
     158        1252 :   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         678 : unsigned llvm::ARM::getDefaultFPU(StringRef CPU, ArchKind AK) {
     180             :   if (CPU == "generic")
     181          34 :     return ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
     182             : 
     183             :   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         778 : unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, ArchKind AK) {
     191             :   if (CPU == "generic")
     192          63 :     return ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
     193             : 
     194             :   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        6231 : bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
     203             :                                  std::vector<StringRef> &Features) {
     204             : 
     205        6231 :   if (HWDivKind == ARM::AEK_INVALID)
     206             :     return false;
     207             : 
     208        6231 :   if (HWDivKind & ARM::AEK_HWDIVARM)
     209        3073 :     Features.push_back("+hwdiv-arm");
     210             :   else
     211        3158 :     Features.push_back("-hwdiv-arm");
     212             : 
     213        6231 :   if (HWDivKind & ARM::AEK_HWDIVTHUMB)
     214        3095 :     Features.push_back("+hwdiv");
     215             :   else
     216        3136 :     Features.push_back("-hwdiv");
     217             : 
     218             :   return true;
     219             : }
     220             : 
     221        6651 : bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
     222             :                                      std::vector<StringRef> &Features) {
     223             : 
     224        6651 :   if (Extensions == ARM::AEK_INVALID)
     225             :     return false;
     226             : 
     227        6220 :   if (Extensions & ARM::AEK_CRC)
     228        3031 :     Features.push_back("+crc");
     229             :   else
     230        3189 :     Features.push_back("-crc");
     231             : 
     232        6220 :   if (Extensions & ARM::AEK_DSP)
     233        3103 :     Features.push_back("+dsp");
     234             :   else
     235        3117 :     Features.push_back("-dsp");
     236             : 
     237        6220 :   if (Extensions & ARM::AEK_RAS)
     238        1913 :     Features.push_back("+ras");
     239             :   else
     240        4307 :     Features.push_back("-ras");
     241             : 
     242        6220 :   if (Extensions & ARM::AEK_DOTPROD)
     243           2 :     Features.push_back("+dotprod");
     244             :   else
     245        6218 :     Features.push_back("-dotprod");
     246             : 
     247        6220 :   return getHWDivFeatures(Extensions, Features);
     248             : }
     249             : 
     250        1268 : bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
     251             :                                std::vector<StringRef> &Features) {
     252             : 
     253        1268 :   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         842 :   switch (FPUNames[FPUKind].Restriction) {
     259             :   case ARM::FPURestriction::SP_D16:
     260          14 :     Features.push_back("+fp-only-sp");
     261          14 :     Features.push_back("+d16");
     262          14 :     break;
     263             :   case ARM::FPURestriction::D16:
     264          19 :     Features.push_back("-fp-only-sp");
     265          19 :     Features.push_back("+d16");
     266          19 :     break;
     267             :   case ARM::FPURestriction::None:
     268         809 :     Features.push_back("-fp-only-sp");
     269         809 :     Features.push_back("-d16");
     270         809 :     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         842 :   switch (FPUNames[FPUKind].FPUVersion) {
     278             :   case ARM::FPUVersion::VFPV5:
     279          38 :     Features.push_back("+fp-armv8");
     280          38 :     break;
     281             :   case ARM::FPUVersion::VFPV4:
     282          42 :     Features.push_back("+vfp4");
     283          42 :     Features.push_back("-fp-armv8");
     284          42 :     break;
     285             :   case ARM::FPUVersion::VFPV3_FP16:
     286          19 :     Features.push_back("+vfp3");
     287          19 :     Features.push_back("+fp16");
     288          19 :     Features.push_back("-vfp4");
     289          19 :     Features.push_back("-fp-armv8");
     290          19 :     break;
     291             :   case ARM::FPUVersion::VFPV3:
     292          90 :     Features.push_back("+vfp3");
     293          90 :     Features.push_back("-fp16");
     294          90 :     Features.push_back("-vfp4");
     295          90 :     Features.push_back("-fp-armv8");
     296          90 :     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         640 :     Features.push_back("-vfp2");
     306         640 :     Features.push_back("-vfp3");
     307         640 :     Features.push_back("-fp16");
     308         640 :     Features.push_back("-vfp4");
     309         640 :     Features.push_back("-fp-armv8");
     310         640 :     break;
     311             :   }
     312             : 
     313             :   // crypto includes neon, so we handle this similarly to FPU version.
     314         842 :   switch (FPUNames[FPUKind].NeonSupport) {
     315             :   case ARM::NeonSupportLevel::Crypto:
     316          25 :     Features.push_back("+neon");
     317          25 :     Features.push_back("+crypto");
     318          25 :     break;
     319             :   case ARM::NeonSupportLevel::Neon:
     320         114 :     Features.push_back("+neon");
     321         114 :     Features.push_back("-crypto");
     322         114 :     break;
     323             :   case ARM::NeonSupportLevel::None:
     324         703 :     Features.push_back("-neon");
     325         703 :     Features.push_back("-crypto");
     326         703 :     break;
     327             :   }
     328             : 
     329             :   return true;
     330             : }
     331             : 
     332        7962 : StringRef llvm::ARM::getArchName(ArchKind AK) {
     333        7962 :   return ARCHNames[static_cast<unsigned>(AK)].getName();
     334             : }
     335             : 
     336         342 : StringRef llvm::ARM::getCPUAttr(ArchKind AK) {
     337         342 :   return ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
     338             : }
     339             : 
     340        2189 : StringRef llvm::ARM::getSubArch(ArchKind AK) {
     341        2189 :   return ARCHNames[static_cast<unsigned>(AK)].getSubArch();
     342             : }
     343             : 
     344          68 : unsigned llvm::ARM::getArchAttr(ArchKind AK) {
     345          68 :   return ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
     346             : }
     347             : 
     348           3 : StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
     349          45 :   for (const auto AE : ARCHExtNames) {
     350          24 :     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         528 :     for (const auto AE : ARCHExtNames) {
     360         263 :       if (AE.NegFeature && ArchExtBase == AE.getName())
     361           8 :         return StringRef(AE.NegFeature);
     362             :     }
     363             :   }
     364        1047 :   for (const auto AE : ARCHExtNames) {
     365         519 :     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        3066 : StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
     381        3066 :   ArchKind AK = parseArch(Arch);
     382        3066 :   if (AK == ARM::ArchKind::INVALID)
     383         523 :     return StringRef();
     384             : 
     385             :   // Look for multiple AKs to find the default for pair AK+Name.
     386      312179 :   for (const auto CPU : CPUNames) {
     387      155925 :     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        1436 :   return "generic";
     393             : }
     394             : 
     395          20 : StringRef llvm::AArch64::getFPUName(unsigned FPUKind) {
     396          20 :   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          20 : unsigned llvm::AArch64::getDefaultFPU(StringRef CPU, ArchKind AK) {
     412             :   if (CPU == "generic")
     413           1 :     return AArch64ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
     414             : 
     415             :   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         619 : unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, ArchKind AK) {
     423             :   if (CPU == "generic")
     424          13 :     return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
     425             : 
     426             :   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        8762 : bool llvm::AArch64::getExtensionFeatures(unsigned Extensions,
     437             :                                      std::vector<StringRef> &Features) {
     438             : 
     439        8762 :   if (Extensions == AArch64::AEK_INVALID)
     440             :     return false;
     441             : 
     442        8761 :   if (Extensions & AArch64::AEK_FP)
     443        4666 :     Features.push_back("+fp-armv8");
     444        8761 :   if (Extensions & AArch64::AEK_SIMD)
     445        4666 :     Features.push_back("+neon");
     446        8761 :   if (Extensions & AArch64::AEK_CRC)
     447        4586 :     Features.push_back("+crc");
     448        8761 :   if (Extensions & AArch64::AEK_CRYPTO)
     449        4666 :     Features.push_back("+crypto");
     450        8761 :   if (Extensions & AArch64::AEK_DOTPROD)
     451        4170 :     Features.push_back("+dotprod");
     452        8761 :   if (Extensions & AArch64::AEK_FP16)
     453        4170 :     Features.push_back("+fullfp16");
     454        8761 :   if (Extensions & AArch64::AEK_PROFILE)
     455        4095 :     Features.push_back("+spe");
     456        8761 :   if (Extensions & AArch64::AEK_RAS)
     457        4170 :     Features.push_back("+ras");
     458        8761 :   if (Extensions & AArch64::AEK_LSE)
     459        4212 :     Features.push_back("+lse");
     460        8761 :   if (Extensions & AArch64::AEK_RDM)
     461        4231 :     Features.push_back("+rdm");
     462        8761 :   if (Extensions & AArch64::AEK_SVE)
     463        4095 :     Features.push_back("+sve");
     464        8761 :   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         649 : bool llvm::AArch64::getArchFeatures(AArch64::ArchKind AK,
     476             :                                     std::vector<StringRef> &Features) {
     477         649 :   if (AK == AArch64::ArchKind::ARMV8_1A)
     478          74 :     Features.push_back("+v8.1a");
     479         649 :   if (AK == AArch64::ArchKind::ARMV8_2A)
     480          90 :     Features.push_back("+v8.2a");
     481         649 :   if (AK == AArch64::ArchKind::ARMV8_3A)
     482           4 :     Features.push_back("+v8.3a");
     483             : 
     484         649 :   return AK != AArch64::ArchKind::INVALID;
     485             : }
     486             : 
     487          20 : StringRef llvm::AArch64::getArchName(ArchKind AK) {
     488          20 :   return AArch64ARCHNames[static_cast<unsigned>(AK)].getName();
     489             : }
     490             : 
     491          20 : StringRef llvm::AArch64::getCPUAttr(ArchKind AK) {
     492          20 :   return AArch64ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
     493             : }
     494             : 
     495           4 : StringRef llvm::AArch64::getSubArch(ArchKind AK) {
     496           4 :   return AArch64ARCHNames[static_cast<unsigned>(AK)].getSubArch();
     497             : }
     498             : 
     499           4 : unsigned llvm::AArch64::getArchAttr(ArchKind AK) {
     500           4 :   return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
     501             : }
     502             : 
     503           0 : StringRef llvm::AArch64::getArchExtName(unsigned ArchExtKind) {
     504           0 :   for (const auto &AE : AArch64ARCHExtNames)
     505           0 :     if (ArchExtKind == AE.ID)
     506           0 :       return AE.getName();
     507           0 :   return StringRef();
     508             : }
     509             : 
     510         124 : StringRef llvm::AArch64::getArchExtFeature(StringRef ArchExt) {
     511             :   if (ArchExt.startswith("no")) {
     512             :     StringRef ArchExtBase(ArchExt.substr(2));
     513         908 :     for (const auto &AE : AArch64ARCHExtNames) {
     514         482 :       if (AE.NegFeature && ArchExtBase == AE.getName())
     515          59 :         return StringRef(AE.NegFeature);
     516             :     }
     517             :   }
     518             : 
     519         963 :   for (const auto &AE : AArch64ARCHExtNames)
     520         508 :     if (AE.Feature && ArchExt == AE.getName())
     521          59 :       return StringRef(AE.Feature);
     522           6 :   return StringRef();
     523             : }
     524             : 
     525           4 : StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) {
     526           4 :   AArch64::ArchKind AK = parseArch(Arch);
     527           4 :   if (AK == ArchKind::INVALID)
     528           0 :     return StringRef();
     529             : 
     530             :   // Look for multiple AKs to find the default for pair AK+Name.
     531         126 :   for (const auto &CPU : AArch64CPUNames)
     532          62 :     if (CPU.ArchID == AK && CPU.Default)
     533           1 :       return CPU.getName();
     534             : 
     535             :   // If we can't find a default then target the architecture instead
     536           3 :   return "generic";
     537             : }
     538             : 
     539          93 : unsigned llvm::AArch64::checkArchVersion(StringRef Arch) {
     540         276 :   if (Arch.size() >= 2 && Arch[0] == 'v' && std::isdigit(Arch[1]))
     541          90 :     return (Arch[1] - 48);
     542             :   return 0;
     543             : }
     544             : 
     545             : // ======================================================= //
     546             : // Parsers
     547             : // ======================================================= //
     548             : 
     549          15 : static StringRef getHWDivSynonym(StringRef HWDiv) {
     550             :   return StringSwitch<StringRef>(HWDiv)
     551          15 :       .Case("thumb,arm", "arm,thumb")
     552          15 :       .Default(HWDiv);
     553             : }
     554             : 
     555          66 : static StringRef getFPUSynonym(StringRef FPU) {
     556             :   return StringSwitch<StringRef>(FPU)
     557          66 :       .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
     558          66 :       .Case("vfp2", "vfpv2")
     559          66 :       .Case("vfp3", "vfpv3")
     560          66 :       .Case("vfp4", "vfpv4")
     561          66 :       .Case("vfp3-d16", "vfpv3-d16")
     562          66 :       .Case("vfp4-d16", "vfpv4-d16")
     563          66 :       .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
     564          66 :       .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
     565          66 :       .Case("fp5-sp-d16", "fpv5-sp-d16")
     566          66 :       .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
     567             :       // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
     568          66 :       .Case("neon-vfpv3", "neon")
     569          66 :       .Default(FPU);
     570             : }
     571             : 
     572      772531 : static StringRef getArchSynonym(StringRef Arch) {
     573             :   return StringSwitch<StringRef>(Arch)
     574      772531 :       .Case("v5", "v5t")
     575      772531 :       .Case("v5e", "v5te")
     576      772531 :       .Case("v6j", "v6")
     577      772531 :       .Case("v6hl", "v6k")
     578      772531 :       .Cases("v6m", "v6sm", "v6s-m", "v6-m")
     579      772531 :       .Cases("v6z", "v6zk", "v6kz")
     580      772531 :       .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
     581      772531 :       .Case("v7r", "v7-r")
     582      772531 :       .Case("v7m", "v7-m")
     583      772531 :       .Case("v7em", "v7e-m")
     584      772531 :       .Cases("v8", "v8a", "v8l", "aarch64", "arm64", "v8-a")
     585      772531 :       .Case("v8.1a", "v8.1-a")
     586      772531 :       .Case("v8.2a", "v8.2-a")
     587      772531 :       .Case("v8.3a", "v8.3-a")
     588      772531 :       .Case("v8r", "v8-r")
     589      772531 :       .Case("v8m.base", "v8-m.base")
     590      772531 :       .Case("v8m.main", "v8-m.main")
     591      772531 :       .Default(Arch);
     592             : }
     593             : 
     594             : // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
     595             : // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
     596             : // "v.+", if the latter, return unmodified string, minus 'eb'.
     597             : // If invalid, return empty string.
     598     1625534 : StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
     599             :   size_t offset = StringRef::npos;
     600     1625534 :   StringRef A = Arch;
     601             :   StringRef Error = "";
     602             : 
     603             :   // Begins with "arm" / "thumb", move past it.
     604             :   if (A.startswith("arm64"))
     605             :     offset = 5;
     606             :   else if (A.startswith("arm"))
     607             :     offset = 3;
     608             :   else if (A.startswith("thumb"))
     609             :     offset = 5;
     610             :   else if (A.startswith("aarch64")) {
     611             :     offset = 7;
     612             :     // AArch64 uses "_be", not "eb" suffix.
     613       24395 :     if (A.find("eb") != StringRef::npos)
     614           0 :       return Error;
     615             :     if (A.substr(offset, 3) == "_be")
     616             :       offset += 3;
     617             :   }
     618             : 
     619             :   // Ex. "armebv7", move past the "eb".
     620             :   if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
     621        2754 :     offset += 2;
     622             :   // Or, if it ends with eb ("armv7eb"), chop it off.
     623             :   else if (A.endswith("eb"))
     624         904 :     A = A.substr(0, A.size() - 2);
     625             :   // Trim the head
     626     1625536 :   if (offset != StringRef::npos)
     627      152896 :     A = A.substr(offset);
     628             : 
     629             :   // Empty string means offset reached the end, which means it's valid.
     630     1625536 :   if (A.empty())
     631      128470 :     return Arch;
     632             : 
     633             :   // Only match non-marketing names
     634     1497066 :   if (offset != StringRef::npos) {
     635             :     // Must start with 'vN'.
     636      252952 :     if (A.size() >= 2 && (A[0] != 'v' || !std::isdigit(A[1])))
     637          42 :       return Error;
     638             :     // Can't have an extra 'eb'.
     639       84312 :     if (A.find("eb") != StringRef::npos)
     640           3 :       return Error;
     641             :   }
     642             : 
     643             :   // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
     644     1497021 :   return A;
     645             : }
     646             : 
     647          15 : unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
     648          15 :   StringRef Syn = getHWDivSynonym(HWDiv);
     649         101 :   for (const auto D : HWDivNames) {
     650             :     if (Syn == D.getName())
     651             :       return D.ID;
     652             :   }
     653             :   return ARM::AEK_INVALID;
     654             : }
     655             : 
     656          66 : unsigned llvm::ARM::parseFPU(StringRef FPU) {
     657          66 :   StringRef Syn = getFPUSynonym(FPU);
     658        1702 :   for (const auto F : FPUNames) {
     659             :     if (Syn == F.getName())
     660             :       return F.ID;
     661             :   }
     662             :   return ARM::FK_INVALID;
     663             : }
     664             : 
     665             : // Allows partial match, ex. "v7a" matches "armv7a".
     666      772441 : ARM::ArchKind ARM::parseArch(StringRef Arch) {
     667      772441 :   Arch = getCanonicalArchName(Arch);
     668      772441 :   StringRef Syn = getArchSynonym(Arch);
     669    45684675 :   for (const auto A : ARCHNames) {
     670             :     if (A.getName().endswith(Syn))
     671             :       return A.ID;
     672             :   }
     673             :   return ARM::ArchKind::INVALID;
     674             : }
     675             : 
     676         125 : unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
     677        2045 :   for (const auto A : ARCHExtNames) {
     678             :     if (ArchExt == A.getName())
     679             :       return A.ID;
     680             :   }
     681             :   return ARM::AEK_INVALID;
     682             : }
     683             : 
     684        3551 : ARM::ArchKind llvm::ARM::parseCPUArch(StringRef CPU) {
     685      336665 :   for (const auto C : CPUNames) {
     686             :     if (CPU == C.getName())
     687             :       return C.ArchID;
     688             :   }
     689             :   return ARM::ArchKind::INVALID;
     690             : }
     691             : 
     692           3 : void llvm::ARM::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
     693         501 :   for (const CpuNames<ARM::ArchKind> &Arch : CPUNames) {
     694         249 :     if (Arch.ArchID != ARM::ArchKind::INVALID)
     695         246 :       Values.push_back(Arch.getName());
     696             :   }
     697           3 : }
     698             : 
     699           2 : void llvm::AArch64::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
     700          82 :   for (const CpuNames<AArch64::ArchKind> &Arch : AArch64CPUNames) {
     701          40 :     if (Arch.ArchID != AArch64::ArchKind::INVALID)
     702          38 :       Values.push_back(Arch.getName());
     703             :   }
     704           2 : }
     705             : 
     706             : // ARM, Thumb, AArch64
     707       37237 : ARM::ISAKind ARM::parseArchISA(StringRef Arch) {
     708             :   return StringSwitch<ARM::ISAKind>(Arch)
     709       74474 :       .StartsWith("aarch64", ARM::ISAKind::AARCH64)
     710       74474 :       .StartsWith("arm64", ARM::ISAKind::AARCH64)
     711       74474 :       .StartsWith("thumb", ARM::ISAKind::THUMB)
     712       74474 :       .StartsWith("arm", ARM::ISAKind::ARM)
     713       37237 :       .Default(ARM::ISAKind::INVALID);
     714             : }
     715             : 
     716             : // Little/Big endian
     717       36663 : ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
     718             :   if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
     719             :       Arch.startswith("aarch64_be"))
     720             :     return ARM::EndianKind::BIG;
     721             : 
     722             :   if (Arch.startswith("arm") || Arch.startswith("thumb")) {
     723             :     if (Arch.endswith("eb"))
     724             :       return ARM::EndianKind::BIG;
     725             :     else
     726             :       return ARM::EndianKind::LITTLE;
     727             :   }
     728             : 
     729             :   if (Arch.startswith("aarch64"))
     730             :     return ARM::EndianKind::LITTLE;
     731             : 
     732             :   return ARM::EndianKind::INVALID;
     733             : }
     734             : 
     735             : // Profile A/R/M
     736       40323 : ARM::ProfileKind ARM::parseArchProfile(StringRef Arch) {
     737       40323 :   Arch = getCanonicalArchName(Arch);
     738       40323 :   switch (parseArch(Arch)) {
     739             :   case ARM::ArchKind::ARMV6M:
     740             :   case ARM::ArchKind::ARMV7M:
     741             :   case ARM::ArchKind::ARMV7EM:
     742             :   case ARM::ArchKind::ARMV8MMainline:
     743             :   case ARM::ArchKind::ARMV8MBaseline:
     744             :     return ARM::ProfileKind::M;
     745         334 :   case ARM::ArchKind::ARMV7R:
     746             :   case ARM::ArchKind::ARMV8R:
     747         334 :     return ARM::ProfileKind::R;
     748       29178 :   case ARM::ArchKind::ARMV7A:
     749             :   case ARM::ArchKind::ARMV7VE:
     750             :   case ARM::ArchKind::ARMV7K:
     751             :   case ARM::ArchKind::ARMV8A:
     752             :   case ARM::ArchKind::ARMV8_1A:
     753             :   case ARM::ArchKind::ARMV8_2A:
     754             :   case ARM::ArchKind::ARMV8_3A:
     755       29178 :     return ARM::ProfileKind::A;
     756        6847 :   case ARM::ArchKind::ARMV2:
     757             :   case ARM::ArchKind::ARMV2A:
     758             :   case ARM::ArchKind::ARMV3:
     759             :   case ARM::ArchKind::ARMV3M:
     760             :   case ARM::ArchKind::ARMV4:
     761             :   case ARM::ArchKind::ARMV4T:
     762             :   case ARM::ArchKind::ARMV5T:
     763             :   case ARM::ArchKind::ARMV5TE:
     764             :   case ARM::ArchKind::ARMV5TEJ:
     765             :   case ARM::ArchKind::ARMV6:
     766             :   case ARM::ArchKind::ARMV6K:
     767             :   case ARM::ArchKind::ARMV6T2:
     768             :   case ARM::ArchKind::ARMV6KZ:
     769             :   case ARM::ArchKind::ARMV7S:
     770             :   case ARM::ArchKind::IWMMXT:
     771             :   case ARM::ArchKind::IWMMXT2:
     772             :   case ARM::ArchKind::XSCALE:
     773             :   case ARM::ArchKind::INVALID:
     774        6847 :     return ARM::ProfileKind::INVALID;
     775             :   }
     776           0 :   llvm_unreachable("Unhandled architecture");
     777             : }
     778             : 
     779             : // Version number (ex. v7 = 7).
     780       40952 : unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
     781       40952 :   Arch = getCanonicalArchName(Arch);
     782       40952 :   switch (parseArch(Arch)) {
     783             :   case ARM::ArchKind::ARMV2:
     784             :   case ARM::ArchKind::ARMV2A:
     785             :     return 2;
     786           2 :   case ARM::ArchKind::ARMV3:
     787             :   case ARM::ArchKind::ARMV3M:
     788           2 :     return 3;
     789        2505 :   case ARM::ArchKind::ARMV4:
     790             :   case ARM::ArchKind::ARMV4T:
     791        2505 :     return 4;
     792        1025 :   case ARM::ArchKind::ARMV5T:
     793             :   case ARM::ArchKind::ARMV5TE:
     794             :   case ARM::ArchKind::IWMMXT:
     795             :   case ARM::ArchKind::IWMMXT2:
     796             :   case ARM::ArchKind::XSCALE:
     797             :   case ARM::ArchKind::ARMV5TEJ:
     798        1025 :     return 5;
     799        4016 :   case ARM::ArchKind::ARMV6:
     800             :   case ARM::ArchKind::ARMV6K:
     801             :   case ARM::ArchKind::ARMV6T2:
     802             :   case ARM::ArchKind::ARMV6KZ:
     803             :   case ARM::ArchKind::ARMV6M:
     804        4016 :     return 6;
     805       28610 :   case ARM::ArchKind::ARMV7A:
     806             :   case ARM::ArchKind::ARMV7VE:
     807             :   case ARM::ArchKind::ARMV7R:
     808             :   case ARM::ArchKind::ARMV7M:
     809             :   case ARM::ArchKind::ARMV7S:
     810             :   case ARM::ArchKind::ARMV7EM:
     811             :   case ARM::ArchKind::ARMV7K:
     812       28610 :     return 7;
     813        4732 :   case ARM::ArchKind::ARMV8A:
     814             :   case ARM::ArchKind::ARMV8_1A:
     815             :   case ARM::ArchKind::ARMV8_2A:
     816             :   case ARM::ArchKind::ARMV8_3A:
     817             :   case ARM::ArchKind::ARMV8R:
     818             :   case ARM::ArchKind::ARMV8MBaseline:
     819             :   case ARM::ArchKind::ARMV8MMainline:
     820        4732 :     return 8;
     821          60 :   case ARM::ArchKind::INVALID:
     822          60 :     return 0;
     823             :   }
     824           0 :   llvm_unreachable("Unhandled architecture");
     825             : }
     826             : 
     827        6974 : StringRef llvm::ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) {
     828             :   StringRef ArchName =
     829        6974 :       CPU.empty() ? TT.getArchName() : ARM::getArchName(ARM::parseCPUArch(CPU));
     830             : 
     831        6974 :   if (TT.isOSBinFormatMachO()) {
     832        3818 :     if (TT.getEnvironment() == Triple::EABI ||
     833        3720 :         TT.getOS() == Triple::UnknownOS ||
     834        1809 :         llvm::ARM::parseArchProfile(ArchName) == ARM::ProfileKind::M)
     835         156 :       return "aapcs";
     836        1755 :     if (TT.isWatchABI())
     837          76 :       return "aapcs16";
     838        1679 :     return "apcs-gnu";
     839        5063 :   } else if (TT.isOSWindows())
     840             :     // FIXME: this is invalid for WindowsCE.
     841         297 :     return "aapcs";
     842             : 
     843             :   // Select the default based on the platform.
     844        4766 :   switch (TT.getEnvironment()) {
     845             :   case Triple::Android:
     846             :   case Triple::GNUEABI:
     847             :   case Triple::GNUEABIHF:
     848             :   case Triple::MuslEABI:
     849             :   case Triple::MuslEABIHF:
     850        1744 :     return "aapcs-linux";
     851             :   case Triple::EABIHF:
     852             :   case Triple::EABI:
     853        1980 :     return "aapcs";
     854             :   default:
     855        1042 :     if (TT.isOSNetBSD())
     856          10 :       return "apcs-gnu";
     857        1032 :     if (TT.isOSOpenBSD())
     858          13 :       return "aapcs-linux";
     859        1019 :     return "aapcs";
     860             :   }
     861             : }
     862             : 
     863          93 : StringRef llvm::AArch64::getCanonicalArchName(StringRef Arch) {
     864          93 :   return ARM::getCanonicalArchName(Arch);
     865             : }
     866             : 
     867           0 : unsigned llvm::AArch64::parseFPU(StringRef FPU) {
     868           0 :   return ARM::parseFPU(FPU);
     869             : }
     870             : 
     871             : // Allows partial match, ex. "v8a" matches "armv8a".
     872          93 : AArch64::ArchKind AArch64::parseArch(StringRef Arch) {
     873          93 :   Arch = getCanonicalArchName(Arch);
     874          93 :   if (checkArchVersion(Arch) < 8)
     875             :     return ArchKind::INVALID;
     876             : 
     877          90 :   StringRef Syn = getArchSynonym(Arch);
     878         434 :   for (const auto A : AArch64ARCHNames) {
     879             :     if (A.getName().endswith(Syn))
     880             :       return A.ID;
     881             :   }
     882             :   return ArchKind::INVALID;
     883             : }
     884             : 
     885          28 : AArch64::ArchExtKind llvm::AArch64::parseArchExt(StringRef ArchExt) {
     886         532 :   for (const auto A : AArch64ARCHExtNames) {
     887             :     if (ArchExt == A.getName())
     888             :       return static_cast<ArchExtKind>(A.ID);
     889             :   }
     890             :   return AArch64::AEK_INVALID;
     891             : }
     892             : 
     893         623 : AArch64::ArchKind llvm::AArch64::parseCPUArch(StringRef CPU) {
     894        8305 :   for (const auto C : AArch64CPUNames) {
     895             :     if (CPU == C.getName())
     896             :       return C.ArchID;
     897             :   }
     898             :   return ArchKind::INVALID;
     899             : }
     900             : 
     901             : // ARM, Thumb, AArch64
     902           0 : ARM::ISAKind AArch64::parseArchISA(StringRef Arch) {
     903           0 :   return ARM::parseArchISA(Arch);
     904             : }
     905             : 
     906             : // Little/Big endian
     907           0 : ARM::EndianKind AArch64::parseArchEndian(StringRef Arch) {
     908           0 :   return ARM::parseArchEndian(Arch);
     909             : }
     910             : 
     911             : // Profile A/R/M
     912           0 : ARM::ProfileKind AArch64::parseArchProfile(StringRef Arch) {
     913           0 :   return ARM::parseArchProfile(Arch);
     914             : }
     915             : 
     916             : // Version number (ex. v8 = 8).
     917           0 : unsigned llvm::AArch64::parseArchVersion(StringRef Arch) {
     918           0 :   return ARM::parseArchVersion(Arch);
     919             : }

Generated by: LCOV version 1.13