1f5f373fcSRenato Golin //===-- TargetParser - Parser for target features ---------------*- C++ -*-===// 2f5f373fcSRenato Golin // 3f5f373fcSRenato Golin // The LLVM Compiler Infrastructure 4f5f373fcSRenato Golin // 5f5f373fcSRenato Golin // This file is distributed under the University of Illinois Open Source 6f5f373fcSRenato Golin // License. See LICENSE.TXT for details. 7f5f373fcSRenato Golin // 8f5f373fcSRenato Golin //===----------------------------------------------------------------------===// 9f5f373fcSRenato Golin // 10f5f373fcSRenato Golin // This file implements a target parser to recognise hardware features such as 11f5f373fcSRenato Golin // FPU/CPU/ARCH names as well as specific support such as HDIV, etc. 12f5f373fcSRenato Golin // 13f5f373fcSRenato Golin //===----------------------------------------------------------------------===// 14f5f373fcSRenato Golin 15f5f373fcSRenato Golin #include "llvm/Support/ARMBuildAttributes.h" 16f5f373fcSRenato Golin #include "llvm/Support/TargetParser.h" 17f5f373fcSRenato Golin #include "llvm/ADT/StringExtras.h" 18f5f373fcSRenato Golin #include "llvm/ADT/StringSwitch.h" 19ebdd12cbSRenato Golin #include <cctype> 20f5f373fcSRenato Golin 21f5f373fcSRenato Golin using namespace llvm; 22*799e880eSChandler Carruth using namespace ARM; 23f5f373fcSRenato Golin 24f5f373fcSRenato Golin namespace { 25f5f373fcSRenato Golin 26d03d2292SJohn Brawn // List of canonical FPU names (use getFPUSynonym) and which architectural 27d03d2292SJohn Brawn // features they correspond to (use getFPUFeatures). 28f5f373fcSRenato Golin // FIXME: TableGen this. 29d5526303SJaved Absar // The entries must appear in the order listed in ARM::FPUKind for correct indexing 30f5f373fcSRenato Golin struct { 31f5f373fcSRenato Golin const char * Name; 32f5f373fcSRenato Golin ARM::FPUKind ID; 33d5526303SJaved Absar ARM::FPUVersion FPUVersion; 34d03d2292SJohn Brawn ARM::NeonSupportLevel NeonSupport; 35d03d2292SJohn Brawn ARM::FPURestriction Restriction; 36f5f373fcSRenato Golin } FPUNames[] = { 37*799e880eSChandler Carruth #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \ 38*799e880eSChandler Carruth { NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION }, 39*799e880eSChandler Carruth #include "llvm/Support/ARMTargetParser.def" 40f5f373fcSRenato Golin }; 41d03d2292SJohn Brawn 42f7c0d5f2SRenato Golin // List of canonical arch names (use getArchSynonym). 43f7c0d5f2SRenato Golin // This table also provides the build attribute fields for CPU arch 44f7c0d5f2SRenato Golin // and Arch ID, according to the Addenda to the ARM ABI, chapters 45f7c0d5f2SRenato Golin // 2.4 and 2.3.5.2 respectively. 4642dad647SRenato Golin // FIXME: SubArch values were simplified to fit into the expectations 4742dad647SRenato Golin // of the triples and are not conforming with their official names. 4842dad647SRenato Golin // Check to see if the expectation should be changed. 49f5f373fcSRenato Golin // FIXME: TableGen this. 50f5f373fcSRenato Golin struct { 51f5f373fcSRenato Golin const char *Name; 52f5f373fcSRenato Golin ARM::ArchKind ID; 53f7c0d5f2SRenato Golin const char *CPUAttr; // CPU class in build attributes. 5442dad647SRenato Golin const char *SubArch; // Sub-Arch name. 55f7c0d5f2SRenato Golin ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes. 56f5f373fcSRenato Golin } ARCHNames[] = { 57*799e880eSChandler Carruth #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR) \ 58*799e880eSChandler Carruth { NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR }, 59*799e880eSChandler Carruth #include "llvm/Support/ARMTargetParser.def" 60f5f373fcSRenato Golin }; 61e1326cadSRenato Golin // List of Arch Extension names. 62f5f373fcSRenato Golin // FIXME: TableGen this. 63f5f373fcSRenato Golin struct { 64f5f373fcSRenato Golin const char *Name; 654ea70755SAlexandros Lamprineas unsigned ID; 66f5f373fcSRenato Golin } ARCHExtNames[] = { 67*799e880eSChandler Carruth #define ARM_ARCH_EXT_NAME(NAME, ID) { NAME, ID }, 68*799e880eSChandler Carruth #include "llvm/Support/ARMTargetParser.def" 69f5f373fcSRenato Golin }; 704ea70755SAlexandros Lamprineas // List of HWDiv names (use getHWDivSynonym) and which architectural 714ea70755SAlexandros Lamprineas // features they correspond to (use getHWDivFeatures). 724ea70755SAlexandros Lamprineas // FIXME: TableGen this. 734ea70755SAlexandros Lamprineas struct { 744ea70755SAlexandros Lamprineas const char *Name; 754ea70755SAlexandros Lamprineas unsigned ID; 764ea70755SAlexandros Lamprineas } HWDivNames[] = { 77*799e880eSChandler Carruth #define ARM_HW_DIV_NAME(NAME, ID) { NAME, ID }, 78*799e880eSChandler Carruth #include "llvm/Support/ARMTargetParser.def" 794ea70755SAlexandros Lamprineas }; 80e8048f0dSRenato Golin // List of CPU names and their arches. 81e8048f0dSRenato Golin // The same CPU can have multiple arches and can be default on multiple arches. 82e8048f0dSRenato Golin // When finding the Arch for a CPU, first-found prevails. Sort them accordingly. 837374fcdbSRenato Golin // When this becomes table-generated, we'd probably need two tables. 84e8048f0dSRenato Golin // FIXME: TableGen this. 85e8048f0dSRenato Golin struct { 86e8048f0dSRenato Golin const char *Name; 87e8048f0dSRenato Golin ARM::ArchKind ArchID; 88fcd93d53SAlexandros Lamprineas ARM::FPUKind DefaultFPU; 89fcd93d53SAlexandros Lamprineas bool Default; // is $Name the default CPU for $ArchID ? 90e8048f0dSRenato Golin } CPUNames[] = { 91*799e880eSChandler Carruth #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT) \ 92*799e880eSChandler Carruth { NAME, ID, DEFAULT_FPU, IS_DEFAULT }, 93*799e880eSChandler Carruth #include "llvm/Support/ARMTargetParser.def" 94e8048f0dSRenato Golin }; 95f5f373fcSRenato Golin 96f5f373fcSRenato Golin } // namespace 97f5f373fcSRenato Golin 98f5f373fcSRenato Golin // ======================================================= // 99f5f373fcSRenato Golin // Information by ID 100f5f373fcSRenato Golin // ======================================================= // 101f5f373fcSRenato Golin 102bb47b9a3SChandler Carruth const char *llvm::ARM::getFPUName(unsigned FPUKind) { 103e8048f0dSRenato Golin if (FPUKind >= ARM::FK_LAST) 104f5f373fcSRenato Golin return nullptr; 105e8048f0dSRenato Golin return FPUNames[FPUKind].Name; 106f5f373fcSRenato Golin } 107f5f373fcSRenato Golin 108bb47b9a3SChandler Carruth unsigned llvm::ARM::getFPUVersion(unsigned FPUKind) { 109d03d2292SJohn Brawn if (FPUKind >= ARM::FK_LAST) 110d03d2292SJohn Brawn return 0; 111d03d2292SJohn Brawn return FPUNames[FPUKind].FPUVersion; 112d03d2292SJohn Brawn } 113d03d2292SJohn Brawn 114bb47b9a3SChandler Carruth unsigned llvm::ARM::getFPUNeonSupportLevel(unsigned FPUKind) { 115d03d2292SJohn Brawn if (FPUKind >= ARM::FK_LAST) 116d03d2292SJohn Brawn return 0; 117d03d2292SJohn Brawn return FPUNames[FPUKind].NeonSupport; 118d03d2292SJohn Brawn } 119d03d2292SJohn Brawn 120bb47b9a3SChandler Carruth unsigned llvm::ARM::getFPURestriction(unsigned FPUKind) { 121d03d2292SJohn Brawn if (FPUKind >= ARM::FK_LAST) 122d03d2292SJohn Brawn return 0; 123d03d2292SJohn Brawn return FPUNames[FPUKind].Restriction; 124d03d2292SJohn Brawn } 125d03d2292SJohn Brawn 126bb47b9a3SChandler Carruth unsigned llvm::ARM::getDefaultFPU(StringRef CPU) { 127fcd93d53SAlexandros Lamprineas for (const auto C : CPUNames) { 128fcd93d53SAlexandros Lamprineas if (CPU == C.Name) 129fcd93d53SAlexandros Lamprineas return C.DefaultFPU; 130fcd93d53SAlexandros Lamprineas } 131fcd93d53SAlexandros Lamprineas return ARM::FK_INVALID; 132fcd93d53SAlexandros Lamprineas } 133fcd93d53SAlexandros Lamprineas 134bb47b9a3SChandler Carruth bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind, 1354ea70755SAlexandros Lamprineas std::vector<const char *> &Features) { 1364ea70755SAlexandros Lamprineas 1374ea70755SAlexandros Lamprineas if (HWDivKind == ARM::AEK_INVALID) 1384ea70755SAlexandros Lamprineas return false; 1394ea70755SAlexandros Lamprineas 1404ea70755SAlexandros Lamprineas if (HWDivKind & ARM::AEK_HWDIVARM) 1414ea70755SAlexandros Lamprineas Features.push_back("+hwdiv-arm"); 1424ea70755SAlexandros Lamprineas else 1434ea70755SAlexandros Lamprineas Features.push_back("-hwdiv-arm"); 1444ea70755SAlexandros Lamprineas 1454ea70755SAlexandros Lamprineas if (HWDivKind & ARM::AEK_HWDIV) 1464ea70755SAlexandros Lamprineas Features.push_back("+hwdiv"); 1474ea70755SAlexandros Lamprineas else 1484ea70755SAlexandros Lamprineas Features.push_back("-hwdiv"); 1494ea70755SAlexandros Lamprineas 1504ea70755SAlexandros Lamprineas return true; 1514ea70755SAlexandros Lamprineas } 1524ea70755SAlexandros Lamprineas 153bb47b9a3SChandler Carruth bool llvm::ARM::getFPUFeatures(unsigned FPUKind, 154d03d2292SJohn Brawn std::vector<const char *> &Features) { 155d03d2292SJohn Brawn 156d03d2292SJohn Brawn if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID) 157d03d2292SJohn Brawn return false; 158d03d2292SJohn Brawn 159d03d2292SJohn Brawn // fp-only-sp and d16 subtarget features are independent of each other, so we 160d03d2292SJohn Brawn // must enable/disable both. 161d03d2292SJohn Brawn switch (FPUNames[FPUKind].Restriction) { 162d03d2292SJohn Brawn case ARM::FR_SP_D16: 163d03d2292SJohn Brawn Features.push_back("+fp-only-sp"); 164d03d2292SJohn Brawn Features.push_back("+d16"); 165d03d2292SJohn Brawn break; 166d03d2292SJohn Brawn case ARM::FR_D16: 167d03d2292SJohn Brawn Features.push_back("-fp-only-sp"); 168d03d2292SJohn Brawn Features.push_back("+d16"); 169d03d2292SJohn Brawn break; 170d03d2292SJohn Brawn case ARM::FR_None: 171d03d2292SJohn Brawn Features.push_back("-fp-only-sp"); 172d03d2292SJohn Brawn Features.push_back("-d16"); 173d03d2292SJohn Brawn break; 174d03d2292SJohn Brawn } 175d03d2292SJohn Brawn 176d03d2292SJohn Brawn // FPU version subtarget features are inclusive of lower-numbered ones, so 177d03d2292SJohn Brawn // enable the one corresponding to this version and disable all that are 178d9e39d53SJohn Brawn // higher. We also have to make sure to disable fp16 when vfp4 is disabled, 179d9e39d53SJohn Brawn // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16. 180d03d2292SJohn Brawn switch (FPUNames[FPUKind].FPUVersion) { 181d5526303SJaved Absar case ARM::FV_VFPV5: 182d03d2292SJohn Brawn Features.push_back("+fp-armv8"); 183d03d2292SJohn Brawn break; 184d5526303SJaved Absar case ARM::FV_VFPV4: 185d03d2292SJohn Brawn Features.push_back("+vfp4"); 186d03d2292SJohn Brawn Features.push_back("-fp-armv8"); 187d03d2292SJohn Brawn break; 188d5526303SJaved Absar case ARM::FV_VFPV3_FP16: 189d5526303SJaved Absar Features.push_back("+vfp3"); 190d5526303SJaved Absar Features.push_back("+fp16"); 191d5526303SJaved Absar Features.push_back("-vfp4"); 192d5526303SJaved Absar Features.push_back("-fp-armv8"); 193d5526303SJaved Absar break; 194d5526303SJaved Absar case ARM::FV_VFPV3: 195d03d2292SJohn Brawn Features.push_back("+vfp3"); 196d9e39d53SJohn Brawn Features.push_back("-fp16"); 197d03d2292SJohn Brawn Features.push_back("-vfp4"); 198d03d2292SJohn Brawn Features.push_back("-fp-armv8"); 199d03d2292SJohn Brawn break; 200d5526303SJaved Absar case ARM::FV_VFPV2: 201d03d2292SJohn Brawn Features.push_back("+vfp2"); 202d03d2292SJohn Brawn Features.push_back("-vfp3"); 203d9e39d53SJohn Brawn Features.push_back("-fp16"); 204d03d2292SJohn Brawn Features.push_back("-vfp4"); 205d03d2292SJohn Brawn Features.push_back("-fp-armv8"); 206d03d2292SJohn Brawn break; 207d5526303SJaved Absar case ARM::FV_NONE: 208d03d2292SJohn Brawn Features.push_back("-vfp2"); 209d03d2292SJohn Brawn Features.push_back("-vfp3"); 210d9e39d53SJohn Brawn Features.push_back("-fp16"); 211d03d2292SJohn Brawn Features.push_back("-vfp4"); 212d03d2292SJohn Brawn Features.push_back("-fp-armv8"); 213d03d2292SJohn Brawn break; 214d03d2292SJohn Brawn } 215d03d2292SJohn Brawn 216d03d2292SJohn Brawn // crypto includes neon, so we handle this similarly to FPU version. 217d03d2292SJohn Brawn switch (FPUNames[FPUKind].NeonSupport) { 218d03d2292SJohn Brawn case ARM::NS_Crypto: 219d03d2292SJohn Brawn Features.push_back("+crypto"); 220d03d2292SJohn Brawn break; 221d03d2292SJohn Brawn case ARM::NS_Neon: 222d03d2292SJohn Brawn Features.push_back("+neon"); 223d03d2292SJohn Brawn Features.push_back("-crypto"); 224d03d2292SJohn Brawn break; 225d03d2292SJohn Brawn case ARM::NS_None: 226d03d2292SJohn Brawn Features.push_back("-neon"); 227d03d2292SJohn Brawn Features.push_back("-crypto"); 228d03d2292SJohn Brawn break; 229d03d2292SJohn Brawn } 230d03d2292SJohn Brawn 231d03d2292SJohn Brawn return true; 232d03d2292SJohn Brawn } 233d03d2292SJohn Brawn 234bb47b9a3SChandler Carruth const char *llvm::ARM::getArchName(unsigned ArchKind) { 235e8048f0dSRenato Golin if (ArchKind >= ARM::AK_LAST) 236f5f373fcSRenato Golin return nullptr; 237e8048f0dSRenato Golin return ARCHNames[ArchKind].Name; 238f5f373fcSRenato Golin } 239f5f373fcSRenato Golin 240bb47b9a3SChandler Carruth const char *llvm::ARM::getCPUAttr(unsigned ArchKind) { 241e8048f0dSRenato Golin if (ArchKind >= ARM::AK_LAST) 242f5f373fcSRenato Golin return nullptr; 243f7c0d5f2SRenato Golin return ARCHNames[ArchKind].CPUAttr; 244f5f373fcSRenato Golin } 245f5f373fcSRenato Golin 246bb47b9a3SChandler Carruth const char *llvm::ARM::getSubArch(unsigned ArchKind) { 24742dad647SRenato Golin if (ArchKind >= ARM::AK_LAST) 24842dad647SRenato Golin return nullptr; 24942dad647SRenato Golin return ARCHNames[ArchKind].SubArch; 25042dad647SRenato Golin } 25142dad647SRenato Golin 252bb47b9a3SChandler Carruth unsigned llvm::ARM::getArchAttr(unsigned ArchKind) { 253e8048f0dSRenato Golin if (ArchKind >= ARM::AK_LAST) 254e8048f0dSRenato Golin return ARMBuildAttrs::CPUArch::Pre_v4; 255f7c0d5f2SRenato Golin return ARCHNames[ArchKind].ArchAttr; 256f5f373fcSRenato Golin } 257f5f373fcSRenato Golin 258bb47b9a3SChandler Carruth const char *llvm::ARM::getArchExtName(unsigned ArchExtKind) { 2594ea70755SAlexandros Lamprineas for (const auto AE : ARCHExtNames) { 2604ea70755SAlexandros Lamprineas if (ArchExtKind == AE.ID) 2614ea70755SAlexandros Lamprineas return AE.Name; 2624ea70755SAlexandros Lamprineas } 263f5f373fcSRenato Golin return nullptr; 2644ea70755SAlexandros Lamprineas } 2654ea70755SAlexandros Lamprineas 266bb47b9a3SChandler Carruth const char *llvm::ARM::getHWDivName(unsigned HWDivKind) { 2674ea70755SAlexandros Lamprineas for (const auto D : HWDivNames) { 2684ea70755SAlexandros Lamprineas if (HWDivKind == D.ID) 2694ea70755SAlexandros Lamprineas return D.Name; 2704ea70755SAlexandros Lamprineas } 2714ea70755SAlexandros Lamprineas return nullptr; 272e8048f0dSRenato Golin } 273e8048f0dSRenato Golin 274bb47b9a3SChandler Carruth const char *llvm::ARM::getDefaultCPU(StringRef Arch) { 275e8048f0dSRenato Golin unsigned AK = parseArch(Arch); 276e8048f0dSRenato Golin if (AK == ARM::AK_INVALID) 277e8048f0dSRenato Golin return nullptr; 278e8048f0dSRenato Golin 279e8048f0dSRenato Golin // Look for multiple AKs to find the default for pair AK+Name. 280e8048f0dSRenato Golin for (const auto CPU : CPUNames) { 281e8048f0dSRenato Golin if (CPU.ArchID == AK && CPU.Default) 282e8048f0dSRenato Golin return CPU.Name; 283e8048f0dSRenato Golin } 284e8048f0dSRenato Golin return nullptr; 285f5f373fcSRenato Golin } 286f5f373fcSRenato Golin 287f5f373fcSRenato Golin // ======================================================= // 288f5f373fcSRenato Golin // Parsers 289f5f373fcSRenato Golin // ======================================================= // 290f5f373fcSRenato Golin 291bb47b9a3SChandler Carruth static StringRef getHWDivSynonym(StringRef HWDiv) { 2924ea70755SAlexandros Lamprineas return StringSwitch<StringRef>(HWDiv) 2934ea70755SAlexandros Lamprineas .Case("thumb,arm", "arm,thumb") 2944ea70755SAlexandros Lamprineas .Default(HWDiv); 2954ea70755SAlexandros Lamprineas } 2964ea70755SAlexandros Lamprineas 297bb47b9a3SChandler Carruth static StringRef getFPUSynonym(StringRef FPU) { 298f5f373fcSRenato Golin return StringSwitch<StringRef>(FPU) 299f5f373fcSRenato Golin .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported 300f5f373fcSRenato Golin .Case("vfp2", "vfpv2") 301f5f373fcSRenato Golin .Case("vfp3", "vfpv3") 302f5f373fcSRenato Golin .Case("vfp4", "vfpv4") 303f5f373fcSRenato Golin .Case("vfp3-d16", "vfpv3-d16") 304f5f373fcSRenato Golin .Case("vfp4-d16", "vfpv4-d16") 305985c04e8SJohn Brawn .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16") 306f5f373fcSRenato Golin .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16") 307985c04e8SJohn Brawn .Case("fp5-sp-d16", "fpv5-sp-d16") 308f5f373fcSRenato Golin .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16") 309f5f373fcSRenato Golin // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3. 310f5f373fcSRenato Golin .Case("neon-vfpv3", "neon") 311f5f373fcSRenato Golin .Default(FPU); 312f5f373fcSRenato Golin } 313f5f373fcSRenato Golin 314bb47b9a3SChandler Carruth static StringRef getArchSynonym(StringRef Arch) { 315f5f373fcSRenato Golin return StringSwitch<StringRef>(Arch) 31685aebc8cSArtyom Skrobov .Case("v6sm", "v6s-m") 31785aebc8cSArtyom Skrobov .Case("v6m", "v6-m") 31885aebc8cSArtyom Skrobov .Case("v7a", "v7-a") 31985aebc8cSArtyom Skrobov .Case("v7r", "v7-r") 32085aebc8cSArtyom Skrobov .Case("v7m", "v7-m") 32185aebc8cSArtyom Skrobov .Case("v7em", "v7e-m") 322acd1cd66SArtyom Skrobov .Cases("v8", "v8a", "aarch64", "arm64", "v8-a") 32385aebc8cSArtyom Skrobov .Case("v8.1a", "v8.1-a") 324f5f373fcSRenato Golin .Default(Arch); 325f5f373fcSRenato Golin } 326f5f373fcSRenato Golin 327e8048f0dSRenato Golin // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but 328e8048f0dSRenato Golin // (iwmmxt|xscale)(eb)? is also permitted. If the former, return 329ebdd12cbSRenato Golin // "v.+", if the latter, return unmodified string, minus 'eb'. 330ebdd12cbSRenato Golin // If invalid, return empty string. 331bb47b9a3SChandler Carruth StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) { 332e8048f0dSRenato Golin size_t offset = StringRef::npos; 333e8048f0dSRenato Golin StringRef A = Arch; 334b6b9e056SRenato Golin StringRef Error = ""; 335e8048f0dSRenato Golin 336e8048f0dSRenato Golin // Begins with "arm" / "thumb", move past it. 337ebdd12cbSRenato Golin if (A.startswith("arm64")) 338ebdd12cbSRenato Golin offset = 5; 339ebdd12cbSRenato Golin else if (A.startswith("arm")) 340e8048f0dSRenato Golin offset = 3; 341e8048f0dSRenato Golin else if (A.startswith("thumb")) 342e8048f0dSRenato Golin offset = 5; 343b6b9e056SRenato Golin else if (A.startswith("aarch64")) { 344b6b9e056SRenato Golin offset = 7; 345b6b9e056SRenato Golin // AArch64 uses "_be", not "eb" suffix. 346b6b9e056SRenato Golin if (A.find("eb") != StringRef::npos) 347b6b9e056SRenato Golin return Error; 348b6b9e056SRenato Golin if (A.substr(offset, 3) == "_be") 349b6b9e056SRenato Golin offset += 3; 350b6b9e056SRenato Golin } 351b6b9e056SRenato Golin 352e8048f0dSRenato Golin // Ex. "armebv7", move past the "eb". 353e8048f0dSRenato Golin if (offset != StringRef::npos && A.substr(offset, 2) == "eb") 354e8048f0dSRenato Golin offset += 2; 355e8048f0dSRenato Golin // Or, if it ends with eb ("armv7eb"), chop it off. 356e8048f0dSRenato Golin else if (A.endswith("eb")) 357e8048f0dSRenato Golin A = A.substr(0, A.size() - 2); 358ebdd12cbSRenato Golin // Trim the head 359ebdd12cbSRenato Golin if (offset != StringRef::npos) 360e8048f0dSRenato Golin A = A.substr(offset); 361e8048f0dSRenato Golin 362ebdd12cbSRenato Golin // Empty string means offset reached the end, which means it's valid. 363e8048f0dSRenato Golin if (A.empty()) 364e8048f0dSRenato Golin return Arch; 365e8048f0dSRenato Golin 366ebdd12cbSRenato Golin // Only match non-marketing names 367ebdd12cbSRenato Golin if (offset != StringRef::npos) { 368ebdd12cbSRenato Golin // Must start with 'vN'. 369ebdd12cbSRenato Golin if (A[0] != 'v' || !std::isdigit(A[1])) 370b6b9e056SRenato Golin return Error; 371ebdd12cbSRenato Golin // Can't have an extra 'eb'. 372ebdd12cbSRenato Golin if (A.find("eb") != StringRef::npos) 373ebdd12cbSRenato Golin return Error; 374ebdd12cbSRenato Golin } 375e8048f0dSRenato Golin 376ebdd12cbSRenato Golin // Arch will either be a 'v' name (v7a) or a marketing name (xscale). 377e8048f0dSRenato Golin return A; 378e8048f0dSRenato Golin } 379e8048f0dSRenato Golin 380bb47b9a3SChandler Carruth unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) { 3814ea70755SAlexandros Lamprineas StringRef Syn = getHWDivSynonym(HWDiv); 3824ea70755SAlexandros Lamprineas for (const auto D : HWDivNames) { 3834ea70755SAlexandros Lamprineas if (Syn == D.Name) 3844ea70755SAlexandros Lamprineas return D.ID; 3854ea70755SAlexandros Lamprineas } 3864ea70755SAlexandros Lamprineas return ARM::AEK_INVALID; 3874ea70755SAlexandros Lamprineas } 3884ea70755SAlexandros Lamprineas 389bb47b9a3SChandler Carruth unsigned llvm::ARM::parseFPU(StringRef FPU) { 390f5f373fcSRenato Golin StringRef Syn = getFPUSynonym(FPU); 391f5f373fcSRenato Golin for (const auto F : FPUNames) { 392f5f373fcSRenato Golin if (Syn == F.Name) 393f5f373fcSRenato Golin return F.ID; 394f5f373fcSRenato Golin } 39535de35d0SRenato Golin return ARM::FK_INVALID; 396f5f373fcSRenato Golin } 397f5f373fcSRenato Golin 398e8048f0dSRenato Golin // Allows partial match, ex. "v7a" matches "armv7a". 399bb47b9a3SChandler Carruth unsigned llvm::ARM::parseArch(StringRef Arch) { 40085aebc8cSArtyom Skrobov Arch = getCanonicalArchName(Arch); 401f5f373fcSRenato Golin StringRef Syn = getArchSynonym(Arch); 402f5f373fcSRenato Golin for (const auto A : ARCHNames) { 403e8048f0dSRenato Golin if (StringRef(A.Name).endswith(Syn)) 404f5f373fcSRenato Golin return A.ID; 405f5f373fcSRenato Golin } 40635de35d0SRenato Golin return ARM::AK_INVALID; 407f5f373fcSRenato Golin } 408f5f373fcSRenato Golin 409bb47b9a3SChandler Carruth unsigned llvm::ARM::parseArchExt(StringRef ArchExt) { 410f5f373fcSRenato Golin for (const auto A : ARCHExtNames) { 411f5f373fcSRenato Golin if (ArchExt == A.Name) 412f5f373fcSRenato Golin return A.ID; 413f5f373fcSRenato Golin } 41435de35d0SRenato Golin return ARM::AEK_INVALID; 415f5f373fcSRenato Golin } 416f5f373fcSRenato Golin 417bb47b9a3SChandler Carruth unsigned llvm::ARM::parseCPUArch(StringRef CPU) { 418e8048f0dSRenato Golin for (const auto C : CPUNames) { 419e8048f0dSRenato Golin if (CPU == C.Name) 420e8048f0dSRenato Golin return C.ArchID; 421e8048f0dSRenato Golin } 422e8048f0dSRenato Golin return ARM::AK_INVALID; 423e8048f0dSRenato Golin } 424e8048f0dSRenato Golin 425b6b9e056SRenato Golin // ARM, Thumb, AArch64 426bb47b9a3SChandler Carruth unsigned llvm::ARM::parseArchISA(StringRef Arch) { 427b6b9e056SRenato Golin return StringSwitch<unsigned>(Arch) 428b6b9e056SRenato Golin .StartsWith("aarch64", ARM::IK_AARCH64) 429b6b9e056SRenato Golin .StartsWith("arm64", ARM::IK_AARCH64) 430b6b9e056SRenato Golin .StartsWith("thumb", ARM::IK_THUMB) 431b6b9e056SRenato Golin .StartsWith("arm", ARM::IK_ARM) 432b6b9e056SRenato Golin .Default(ARM::EK_INVALID); 433b6b9e056SRenato Golin } 434b6b9e056SRenato Golin 435b6b9e056SRenato Golin // Little/Big endian 436bb47b9a3SChandler Carruth unsigned llvm::ARM::parseArchEndian(StringRef Arch) { 4374fc3a986SChandler Carruth if (Arch.startswith("armeb") || Arch.startswith("thumbeb") || 438b6b9e056SRenato Golin Arch.startswith("aarch64_be")) 439b6b9e056SRenato Golin return ARM::EK_BIG; 440b6b9e056SRenato Golin 441b6b9e056SRenato Golin if (Arch.startswith("arm") || Arch.startswith("thumb")) { 442b6b9e056SRenato Golin if (Arch.endswith("eb")) 443b6b9e056SRenato Golin return ARM::EK_BIG; 444b6b9e056SRenato Golin else 445b6b9e056SRenato Golin return ARM::EK_LITTLE; 446b6b9e056SRenato Golin } 447b6b9e056SRenato Golin 448b6b9e056SRenato Golin if (Arch.startswith("aarch64")) 449b6b9e056SRenato Golin return ARM::EK_LITTLE; 450b6b9e056SRenato Golin 451b6b9e056SRenato Golin return ARM::EK_INVALID; 452b6b9e056SRenato Golin } 453b6b9e056SRenato Golin 454fadc2108SRenato Golin // Profile A/R/M 455bb47b9a3SChandler Carruth unsigned llvm::ARM::parseArchProfile(StringRef Arch) { 456fadc2108SRenato Golin Arch = getCanonicalArchName(Arch); 457fadc2108SRenato Golin switch (parseArch(Arch)) { 458fadc2108SRenato Golin case ARM::AK_ARMV6M: 459fadc2108SRenato Golin case ARM::AK_ARMV7M: 460fadc2108SRenato Golin case ARM::AK_ARMV6SM: 461fadc2108SRenato Golin case ARM::AK_ARMV7EM: 462fadc2108SRenato Golin return ARM::PK_M; 463fadc2108SRenato Golin case ARM::AK_ARMV7R: 464fadc2108SRenato Golin return ARM::PK_R; 465fadc2108SRenato Golin case ARM::AK_ARMV7: 466fadc2108SRenato Golin case ARM::AK_ARMV7A: 4670e20b8dcSAlexandros Lamprineas case ARM::AK_ARMV7L: 468fadc2108SRenato Golin case ARM::AK_ARMV8A: 469fadc2108SRenato Golin case ARM::AK_ARMV8_1A: 470fadc2108SRenato Golin return ARM::PK_A; 471fadc2108SRenato Golin } 472fadc2108SRenato Golin return ARM::PK_INVALID; 473fadc2108SRenato Golin } 474fadc2108SRenato Golin 475ebdd12cbSRenato Golin // Version number (ex. v7 = 7). 476bb47b9a3SChandler Carruth unsigned llvm::ARM::parseArchVersion(StringRef Arch) { 477fadc2108SRenato Golin Arch = getCanonicalArchName(Arch); 478fadc2108SRenato Golin switch (parseArch(Arch)) { 479fadc2108SRenato Golin case ARM::AK_ARMV2: 480fadc2108SRenato Golin case ARM::AK_ARMV2A: 481fadc2108SRenato Golin return 2; 482fadc2108SRenato Golin case ARM::AK_ARMV3: 483fadc2108SRenato Golin case ARM::AK_ARMV3M: 484fadc2108SRenato Golin return 3; 485fadc2108SRenato Golin case ARM::AK_ARMV4: 486fadc2108SRenato Golin case ARM::AK_ARMV4T: 487fadc2108SRenato Golin return 4; 488fadc2108SRenato Golin case ARM::AK_ARMV5: 489fadc2108SRenato Golin case ARM::AK_ARMV5T: 490fadc2108SRenato Golin case ARM::AK_ARMV5TE: 491fadc2108SRenato Golin case ARM::AK_IWMMXT: 492fadc2108SRenato Golin case ARM::AK_IWMMXT2: 493fadc2108SRenato Golin case ARM::AK_XSCALE: 494fadc2108SRenato Golin case ARM::AK_ARMV5E: 495fadc2108SRenato Golin case ARM::AK_ARMV5TEJ: 496fadc2108SRenato Golin return 5; 497fadc2108SRenato Golin case ARM::AK_ARMV6: 498fadc2108SRenato Golin case ARM::AK_ARMV6J: 499fadc2108SRenato Golin case ARM::AK_ARMV6K: 500fadc2108SRenato Golin case ARM::AK_ARMV6T2: 501fadc2108SRenato Golin case ARM::AK_ARMV6Z: 502fadc2108SRenato Golin case ARM::AK_ARMV6ZK: 503fadc2108SRenato Golin case ARM::AK_ARMV6M: 504fadc2108SRenato Golin case ARM::AK_ARMV6SM: 505fadc2108SRenato Golin case ARM::AK_ARMV6HL: 506fadc2108SRenato Golin return 6; 507fadc2108SRenato Golin case ARM::AK_ARMV7: 508fadc2108SRenato Golin case ARM::AK_ARMV7A: 509fadc2108SRenato Golin case ARM::AK_ARMV7R: 510fadc2108SRenato Golin case ARM::AK_ARMV7M: 511fadc2108SRenato Golin case ARM::AK_ARMV7L: 512fadc2108SRenato Golin case ARM::AK_ARMV7HL: 513fadc2108SRenato Golin case ARM::AK_ARMV7S: 514fadc2108SRenato Golin case ARM::AK_ARMV7EM: 515366dd9fdSVedant Kumar case ARM::AK_ARMV7K: 516fadc2108SRenato Golin return 7; 517fadc2108SRenato Golin case ARM::AK_ARMV8A: 518fadc2108SRenato Golin case ARM::AK_ARMV8_1A: 519fadc2108SRenato Golin return 8; 520fadc2108SRenato Golin } 521fadc2108SRenato Golin return 0; 522fadc2108SRenato Golin } 523