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

Generated by: LCOV version 1.13