1ff0cc061SDimitry Andric //===-- TargetParser - Parser for target features ---------------*- C++ -*-===// 2ff0cc061SDimitry Andric // 3ff0cc061SDimitry Andric // The LLVM Compiler Infrastructure 4ff0cc061SDimitry Andric // 5ff0cc061SDimitry Andric // This file is distributed under the University of Illinois Open Source 6ff0cc061SDimitry Andric // License. See LICENSE.TXT for details. 7ff0cc061SDimitry Andric // 8ff0cc061SDimitry Andric //===----------------------------------------------------------------------===// 9ff0cc061SDimitry Andric // 10ff0cc061SDimitry Andric // This file implements a target parser to recognise hardware features such as 11ff0cc061SDimitry Andric // FPU/CPU/ARCH names as well as specific support such as HDIV, etc. 12ff0cc061SDimitry Andric // 13ff0cc061SDimitry Andric //===----------------------------------------------------------------------===// 14ff0cc061SDimitry Andric 15ff0cc061SDimitry Andric #include "llvm/Support/ARMBuildAttributes.h" 16ff0cc061SDimitry Andric #include "llvm/Support/TargetParser.h" 17ff0cc061SDimitry Andric #include "llvm/ADT/StringExtras.h" 18ff0cc061SDimitry Andric #include "llvm/ADT/StringSwitch.h" 197d523365SDimitry Andric #include "llvm/ADT/Twine.h" 20ff0cc061SDimitry Andric #include <cctype> 21ff0cc061SDimitry Andric 22ff0cc061SDimitry Andric using namespace llvm; 237d523365SDimitry Andric using namespace ARM; 243ca95b02SDimitry Andric using namespace AArch64; 25ff0cc061SDimitry Andric 26ff0cc061SDimitry Andric namespace { 27ff0cc061SDimitry Andric 2897bc6c73SDimitry Andric // List of canonical FPU names (use getFPUSynonym) and which architectural 2997bc6c73SDimitry Andric // features they correspond to (use getFPUFeatures). 30ff0cc061SDimitry Andric // FIXME: TableGen this. 313dac3a9bSDimitry Andric // The entries must appear in the order listed in ARM::FPUKind for correct indexing 327d523365SDimitry Andric static const struct { 337d523365SDimitry Andric const char *NameCStr; 347d523365SDimitry Andric size_t NameLength; 35ff0cc061SDimitry Andric ARM::FPUKind ID; 363dac3a9bSDimitry Andric ARM::FPUVersion FPUVersion; 3797bc6c73SDimitry Andric ARM::NeonSupportLevel NeonSupport; 3897bc6c73SDimitry Andric ARM::FPURestriction Restriction; 397d523365SDimitry Andric 407d523365SDimitry Andric StringRef getName() const { return StringRef(NameCStr, NameLength); } 41ff0cc061SDimitry Andric } FPUNames[] = { 427d523365SDimitry Andric #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \ 437d523365SDimitry Andric { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION }, 447d523365SDimitry Andric #include "llvm/Support/ARMTargetParser.def" 45ff0cc061SDimitry Andric }; 4697bc6c73SDimitry Andric 4797bc6c73SDimitry Andric // List of canonical arch names (use getArchSynonym). 4897bc6c73SDimitry Andric // This table also provides the build attribute fields for CPU arch 4997bc6c73SDimitry Andric // and Arch ID, according to the Addenda to the ARM ABI, chapters 5097bc6c73SDimitry Andric // 2.4 and 2.3.5.2 respectively. 5197bc6c73SDimitry Andric // FIXME: SubArch values were simplified to fit into the expectations 5297bc6c73SDimitry Andric // of the triples and are not conforming with their official names. 5397bc6c73SDimitry Andric // Check to see if the expectation should be changed. 54ff0cc061SDimitry Andric // FIXME: TableGen this. 557d523365SDimitry Andric static const struct { 567d523365SDimitry Andric const char *NameCStr; 577d523365SDimitry Andric size_t NameLength; 587d523365SDimitry Andric const char *CPUAttrCStr; 597d523365SDimitry Andric size_t CPUAttrLength; 607d523365SDimitry Andric const char *SubArchCStr; 617d523365SDimitry Andric size_t SubArchLength; 627d523365SDimitry Andric unsigned DefaultFPU; 637d523365SDimitry Andric unsigned ArchBaseExtensions; 64ff0cc061SDimitry Andric ARM::ArchKind ID; 6597bc6c73SDimitry Andric ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes. 667d523365SDimitry Andric 677d523365SDimitry Andric StringRef getName() const { return StringRef(NameCStr, NameLength); } 687d523365SDimitry Andric 697d523365SDimitry Andric // CPU class in build attributes. 707d523365SDimitry Andric StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); } 717d523365SDimitry Andric 727d523365SDimitry Andric // Sub-Arch name. 737d523365SDimitry Andric StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); } 74ff0cc061SDimitry Andric } ARCHNames[] = { 757d523365SDimitry Andric #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \ 767d523365SDimitry Andric {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \ 777d523365SDimitry Andric sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ID, ARCH_ATTR}, 787d523365SDimitry Andric #include "llvm/Support/ARMTargetParser.def" 793ca95b02SDimitry Andric },AArch64ARCHNames[] = { 803ca95b02SDimitry Andric #define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \ 813ca95b02SDimitry Andric {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \ 823ca95b02SDimitry Andric sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ID, ARCH_ATTR}, 833ca95b02SDimitry Andric #include "llvm/Support/AArch64TargetParser.def" 84ff0cc061SDimitry Andric }; 857d523365SDimitry Andric 8697bc6c73SDimitry Andric // List of Arch Extension names. 87ff0cc061SDimitry Andric // FIXME: TableGen this. 887d523365SDimitry Andric static const struct { 897d523365SDimitry Andric const char *NameCStr; 907d523365SDimitry Andric size_t NameLength; 917d523365SDimitry Andric unsigned ID; 927d523365SDimitry Andric const char *Feature; 937d523365SDimitry Andric const char *NegFeature; 947d523365SDimitry Andric 957d523365SDimitry Andric StringRef getName() const { return StringRef(NameCStr, NameLength); } 96ff0cc061SDimitry Andric } ARCHExtNames[] = { 977d523365SDimitry Andric #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \ 987d523365SDimitry Andric { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE }, 997d523365SDimitry Andric #include "llvm/Support/ARMTargetParser.def" 1003ca95b02SDimitry Andric },AArch64ARCHExtNames[] = { 1013ca95b02SDimitry Andric #define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \ 1023ca95b02SDimitry Andric { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE }, 1033ca95b02SDimitry Andric #include "llvm/Support/AArch64TargetParser.def" 104ff0cc061SDimitry Andric }; 1057d523365SDimitry Andric 1067d523365SDimitry Andric // List of HWDiv names (use getHWDivSynonym) and which architectural 1077d523365SDimitry Andric // features they correspond to (use getHWDivFeatures). 1087d523365SDimitry Andric // FIXME: TableGen this. 1097d523365SDimitry Andric static const struct { 1107d523365SDimitry Andric const char *NameCStr; 1117d523365SDimitry Andric size_t NameLength; 1127d523365SDimitry Andric unsigned ID; 1137d523365SDimitry Andric 1147d523365SDimitry Andric StringRef getName() const { return StringRef(NameCStr, NameLength); } 1157d523365SDimitry Andric } HWDivNames[] = { 1167d523365SDimitry Andric #define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID }, 1177d523365SDimitry Andric #include "llvm/Support/ARMTargetParser.def" 1187d523365SDimitry Andric }; 1197d523365SDimitry Andric 120ff0cc061SDimitry Andric // List of CPU names and their arches. 121ff0cc061SDimitry Andric // The same CPU can have multiple arches and can be default on multiple arches. 122ff0cc061SDimitry Andric // When finding the Arch for a CPU, first-found prevails. Sort them accordingly. 12397bc6c73SDimitry Andric // When this becomes table-generated, we'd probably need two tables. 124ff0cc061SDimitry Andric // FIXME: TableGen this. 1257d523365SDimitry Andric static const struct { 1267d523365SDimitry Andric const char *NameCStr; 1277d523365SDimitry Andric size_t NameLength; 128ff0cc061SDimitry Andric ARM::ArchKind ArchID; 1297d523365SDimitry Andric bool Default; // is $Name the default CPU for $ArchID ? 1307d523365SDimitry Andric unsigned DefaultExtensions; 1317d523365SDimitry Andric 1327d523365SDimitry Andric StringRef getName() const { return StringRef(NameCStr, NameLength); } 133ff0cc061SDimitry Andric } CPUNames[] = { 1347d523365SDimitry Andric #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 1357d523365SDimitry Andric { NAME, sizeof(NAME) - 1, ID, IS_DEFAULT, DEFAULT_EXT }, 1367d523365SDimitry Andric #include "llvm/Support/ARMTargetParser.def" 1373ca95b02SDimitry Andric },AArch64CPUNames[] = { 1383ca95b02SDimitry Andric #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 1393ca95b02SDimitry Andric { NAME, sizeof(NAME) - 1, ID, IS_DEFAULT, DEFAULT_EXT }, 1403ca95b02SDimitry Andric #include "llvm/Support/AArch64TargetParser.def" 141ff0cc061SDimitry Andric }; 142ff0cc061SDimitry Andric 143ff0cc061SDimitry Andric } // namespace 144ff0cc061SDimitry Andric 145ff0cc061SDimitry Andric // ======================================================= // 146ff0cc061SDimitry Andric // Information by ID 147ff0cc061SDimitry Andric // ======================================================= // 148ff0cc061SDimitry Andric 1497d523365SDimitry Andric StringRef llvm::ARM::getFPUName(unsigned FPUKind) { 150ff0cc061SDimitry Andric if (FPUKind >= ARM::FK_LAST) 1517d523365SDimitry Andric return StringRef(); 1527d523365SDimitry Andric return FPUNames[FPUKind].getName(); 153ff0cc061SDimitry Andric } 154ff0cc061SDimitry Andric 1557d523365SDimitry Andric unsigned llvm::ARM::getFPUVersion(unsigned FPUKind) { 15697bc6c73SDimitry Andric if (FPUKind >= ARM::FK_LAST) 15797bc6c73SDimitry Andric return 0; 15897bc6c73SDimitry Andric return FPUNames[FPUKind].FPUVersion; 15997bc6c73SDimitry Andric } 16097bc6c73SDimitry Andric 1617d523365SDimitry Andric unsigned llvm::ARM::getFPUNeonSupportLevel(unsigned FPUKind) { 16297bc6c73SDimitry Andric if (FPUKind >= ARM::FK_LAST) 16397bc6c73SDimitry Andric return 0; 16497bc6c73SDimitry Andric return FPUNames[FPUKind].NeonSupport; 16597bc6c73SDimitry Andric } 16697bc6c73SDimitry Andric 1677d523365SDimitry Andric unsigned llvm::ARM::getFPURestriction(unsigned FPUKind) { 16897bc6c73SDimitry Andric if (FPUKind >= ARM::FK_LAST) 16997bc6c73SDimitry Andric return 0; 17097bc6c73SDimitry Andric return FPUNames[FPUKind].Restriction; 17197bc6c73SDimitry Andric } 17297bc6c73SDimitry Andric 1737d523365SDimitry Andric unsigned llvm::ARM::getDefaultFPU(StringRef CPU, unsigned ArchKind) { 1747d523365SDimitry Andric if (CPU == "generic") 1757d523365SDimitry Andric return ARCHNames[ArchKind].DefaultFPU; 1767d523365SDimitry Andric 1777d523365SDimitry Andric return StringSwitch<unsigned>(CPU) 1787d523365SDimitry Andric #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 1797d523365SDimitry Andric .Case(NAME, DEFAULT_FPU) 1807d523365SDimitry Andric #include "llvm/Support/ARMTargetParser.def" 1817d523365SDimitry Andric .Default(ARM::FK_INVALID); 1827d523365SDimitry Andric } 1837d523365SDimitry Andric 1847d523365SDimitry Andric unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, unsigned ArchKind) { 1857d523365SDimitry Andric if (CPU == "generic") 1867d523365SDimitry Andric return ARCHNames[ArchKind].ArchBaseExtensions; 1877d523365SDimitry Andric 1887d523365SDimitry Andric return StringSwitch<unsigned>(CPU) 1897d523365SDimitry Andric #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 1907d523365SDimitry Andric .Case(NAME, ARCHNames[ID].ArchBaseExtensions | DEFAULT_EXT) 1917d523365SDimitry Andric #include "llvm/Support/ARMTargetParser.def" 1927d523365SDimitry Andric .Default(ARM::AEK_INVALID); 1937d523365SDimitry Andric } 1947d523365SDimitry Andric 1957d523365SDimitry Andric bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind, 1967d523365SDimitry Andric std::vector<const char *> &Features) { 1977d523365SDimitry Andric 1987d523365SDimitry Andric if (HWDivKind == ARM::AEK_INVALID) 1997d523365SDimitry Andric return false; 2007d523365SDimitry Andric 2017d523365SDimitry Andric if (HWDivKind & ARM::AEK_HWDIVARM) 2027d523365SDimitry Andric Features.push_back("+hwdiv-arm"); 2037d523365SDimitry Andric else 2047d523365SDimitry Andric Features.push_back("-hwdiv-arm"); 2057d523365SDimitry Andric 2067d523365SDimitry Andric if (HWDivKind & ARM::AEK_HWDIV) 2077d523365SDimitry Andric Features.push_back("+hwdiv"); 2087d523365SDimitry Andric else 2097d523365SDimitry Andric Features.push_back("-hwdiv"); 2107d523365SDimitry Andric 2117d523365SDimitry Andric return true; 2127d523365SDimitry Andric } 2137d523365SDimitry Andric 2147d523365SDimitry Andric bool llvm::ARM::getExtensionFeatures(unsigned Extensions, 2157d523365SDimitry Andric std::vector<const char *> &Features) { 2167d523365SDimitry Andric 2177d523365SDimitry Andric if (Extensions == ARM::AEK_INVALID) 2187d523365SDimitry Andric return false; 2197d523365SDimitry Andric 2207d523365SDimitry Andric if (Extensions & ARM::AEK_CRC) 2217d523365SDimitry Andric Features.push_back("+crc"); 2227d523365SDimitry Andric else 2237d523365SDimitry Andric Features.push_back("-crc"); 2247d523365SDimitry Andric 2257d523365SDimitry Andric if (Extensions & ARM::AEK_DSP) 2267d523365SDimitry Andric Features.push_back("+dsp"); 2277d523365SDimitry Andric else 2287d523365SDimitry Andric Features.push_back("-dsp"); 2297d523365SDimitry Andric 2307d523365SDimitry Andric return getHWDivFeatures(Extensions, Features); 2317d523365SDimitry Andric } 2327d523365SDimitry Andric 2337d523365SDimitry Andric bool llvm::ARM::getFPUFeatures(unsigned FPUKind, 23497bc6c73SDimitry Andric std::vector<const char *> &Features) { 23597bc6c73SDimitry Andric 23697bc6c73SDimitry Andric if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID) 23797bc6c73SDimitry Andric return false; 23897bc6c73SDimitry Andric 23997bc6c73SDimitry Andric // fp-only-sp and d16 subtarget features are independent of each other, so we 24097bc6c73SDimitry Andric // must enable/disable both. 24197bc6c73SDimitry Andric switch (FPUNames[FPUKind].Restriction) { 24297bc6c73SDimitry Andric case ARM::FR_SP_D16: 24397bc6c73SDimitry Andric Features.push_back("+fp-only-sp"); 24497bc6c73SDimitry Andric Features.push_back("+d16"); 24597bc6c73SDimitry Andric break; 24697bc6c73SDimitry Andric case ARM::FR_D16: 24797bc6c73SDimitry Andric Features.push_back("-fp-only-sp"); 24897bc6c73SDimitry Andric Features.push_back("+d16"); 24997bc6c73SDimitry Andric break; 25097bc6c73SDimitry Andric case ARM::FR_None: 25197bc6c73SDimitry Andric Features.push_back("-fp-only-sp"); 25297bc6c73SDimitry Andric Features.push_back("-d16"); 25397bc6c73SDimitry Andric break; 25497bc6c73SDimitry Andric } 25597bc6c73SDimitry Andric 25697bc6c73SDimitry Andric // FPU version subtarget features are inclusive of lower-numbered ones, so 25797bc6c73SDimitry Andric // enable the one corresponding to this version and disable all that are 2588f0fd8f6SDimitry Andric // higher. We also have to make sure to disable fp16 when vfp4 is disabled, 2598f0fd8f6SDimitry Andric // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16. 26097bc6c73SDimitry Andric switch (FPUNames[FPUKind].FPUVersion) { 2613dac3a9bSDimitry Andric case ARM::FV_VFPV5: 26297bc6c73SDimitry Andric Features.push_back("+fp-armv8"); 26397bc6c73SDimitry Andric break; 2643dac3a9bSDimitry Andric case ARM::FV_VFPV4: 26597bc6c73SDimitry Andric Features.push_back("+vfp4"); 26697bc6c73SDimitry Andric Features.push_back("-fp-armv8"); 26797bc6c73SDimitry Andric break; 2683dac3a9bSDimitry Andric case ARM::FV_VFPV3_FP16: 2693dac3a9bSDimitry Andric Features.push_back("+vfp3"); 2703dac3a9bSDimitry Andric Features.push_back("+fp16"); 2713dac3a9bSDimitry Andric Features.push_back("-vfp4"); 2723dac3a9bSDimitry Andric Features.push_back("-fp-armv8"); 2733dac3a9bSDimitry Andric break; 2743dac3a9bSDimitry Andric case ARM::FV_VFPV3: 27597bc6c73SDimitry Andric Features.push_back("+vfp3"); 2768f0fd8f6SDimitry Andric Features.push_back("-fp16"); 27797bc6c73SDimitry Andric Features.push_back("-vfp4"); 27897bc6c73SDimitry Andric Features.push_back("-fp-armv8"); 27997bc6c73SDimitry Andric break; 2803dac3a9bSDimitry Andric case ARM::FV_VFPV2: 28197bc6c73SDimitry Andric Features.push_back("+vfp2"); 28297bc6c73SDimitry Andric Features.push_back("-vfp3"); 2838f0fd8f6SDimitry Andric Features.push_back("-fp16"); 28497bc6c73SDimitry Andric Features.push_back("-vfp4"); 28597bc6c73SDimitry Andric Features.push_back("-fp-armv8"); 28697bc6c73SDimitry Andric break; 2873dac3a9bSDimitry Andric case ARM::FV_NONE: 28897bc6c73SDimitry Andric Features.push_back("-vfp2"); 28997bc6c73SDimitry Andric Features.push_back("-vfp3"); 2908f0fd8f6SDimitry Andric Features.push_back("-fp16"); 29197bc6c73SDimitry Andric Features.push_back("-vfp4"); 29297bc6c73SDimitry Andric Features.push_back("-fp-armv8"); 29397bc6c73SDimitry Andric break; 29497bc6c73SDimitry Andric } 29597bc6c73SDimitry Andric 29697bc6c73SDimitry Andric // crypto includes neon, so we handle this similarly to FPU version. 29797bc6c73SDimitry Andric switch (FPUNames[FPUKind].NeonSupport) { 29897bc6c73SDimitry Andric case ARM::NS_Crypto: 2997d523365SDimitry Andric Features.push_back("+neon"); 30097bc6c73SDimitry Andric Features.push_back("+crypto"); 30197bc6c73SDimitry Andric break; 30297bc6c73SDimitry Andric case ARM::NS_Neon: 30397bc6c73SDimitry Andric Features.push_back("+neon"); 30497bc6c73SDimitry Andric Features.push_back("-crypto"); 30597bc6c73SDimitry Andric break; 30697bc6c73SDimitry Andric case ARM::NS_None: 30797bc6c73SDimitry Andric Features.push_back("-neon"); 30897bc6c73SDimitry Andric Features.push_back("-crypto"); 30997bc6c73SDimitry Andric break; 31097bc6c73SDimitry Andric } 31197bc6c73SDimitry Andric 31297bc6c73SDimitry Andric return true; 31397bc6c73SDimitry Andric } 31497bc6c73SDimitry Andric 3157d523365SDimitry Andric StringRef llvm::ARM::getArchName(unsigned ArchKind) { 316ff0cc061SDimitry Andric if (ArchKind >= ARM::AK_LAST) 3177d523365SDimitry Andric return StringRef(); 3187d523365SDimitry Andric return ARCHNames[ArchKind].getName(); 319ff0cc061SDimitry Andric } 320ff0cc061SDimitry Andric 3217d523365SDimitry Andric StringRef llvm::ARM::getCPUAttr(unsigned ArchKind) { 3223ca95b02SDimitry Andric if (ArchKind == ARM::AK_INVALID || ArchKind >= ARM::AK_LAST) 3237d523365SDimitry Andric return StringRef(); 3247d523365SDimitry Andric return ARCHNames[ArchKind].getCPUAttr(); 325ff0cc061SDimitry Andric } 326ff0cc061SDimitry Andric 3277d523365SDimitry Andric StringRef llvm::ARM::getSubArch(unsigned ArchKind) { 3283ca95b02SDimitry Andric if (ArchKind == ARM::AK_INVALID || ArchKind >= ARM::AK_LAST) 3297d523365SDimitry Andric return StringRef(); 3307d523365SDimitry Andric return ARCHNames[ArchKind].getSubArch(); 33197bc6c73SDimitry Andric } 33297bc6c73SDimitry Andric 3337d523365SDimitry Andric unsigned llvm::ARM::getArchAttr(unsigned ArchKind) { 334ff0cc061SDimitry Andric if (ArchKind >= ARM::AK_LAST) 335ff0cc061SDimitry Andric return ARMBuildAttrs::CPUArch::Pre_v4; 33697bc6c73SDimitry Andric return ARCHNames[ArchKind].ArchAttr; 337ff0cc061SDimitry Andric } 338ff0cc061SDimitry Andric 3397d523365SDimitry Andric StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) { 3407d523365SDimitry Andric for (const auto AE : ARCHExtNames) { 3417d523365SDimitry Andric if (ArchExtKind == AE.ID) 3427d523365SDimitry Andric return AE.getName(); 3437d523365SDimitry Andric } 3447d523365SDimitry Andric return StringRef(); 345ff0cc061SDimitry Andric } 346ff0cc061SDimitry Andric 3477d523365SDimitry Andric const char *llvm::ARM::getArchExtFeature(StringRef ArchExt) { 3487d523365SDimitry Andric if (ArchExt.startswith("no")) { 3497d523365SDimitry Andric StringRef ArchExtBase(ArchExt.substr(2)); 3507d523365SDimitry Andric for (const auto AE : ARCHExtNames) { 3517d523365SDimitry Andric if (AE.NegFeature && ArchExtBase == AE.getName()) 3527d523365SDimitry Andric return AE.NegFeature; 3537d523365SDimitry Andric } 3547d523365SDimitry Andric } 3557d523365SDimitry Andric for (const auto AE : ARCHExtNames) { 3567d523365SDimitry Andric if (AE.Feature && ArchExt == AE.getName()) 3577d523365SDimitry Andric return AE.Feature; 3587d523365SDimitry Andric } 3597d523365SDimitry Andric 3607d523365SDimitry Andric return nullptr; 3617d523365SDimitry Andric } 3627d523365SDimitry Andric 3637d523365SDimitry Andric StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) { 3647d523365SDimitry Andric for (const auto D : HWDivNames) { 3657d523365SDimitry Andric if (HWDivKind == D.ID) 3667d523365SDimitry Andric return D.getName(); 3677d523365SDimitry Andric } 3687d523365SDimitry Andric return StringRef(); 3697d523365SDimitry Andric } 3707d523365SDimitry Andric 3717d523365SDimitry Andric StringRef llvm::ARM::getDefaultCPU(StringRef Arch) { 372ff0cc061SDimitry Andric unsigned AK = parseArch(Arch); 373ff0cc061SDimitry Andric if (AK == ARM::AK_INVALID) 3747d523365SDimitry Andric return StringRef(); 375ff0cc061SDimitry Andric 376ff0cc061SDimitry Andric // Look for multiple AKs to find the default for pair AK+Name. 377ff0cc061SDimitry Andric for (const auto CPU : CPUNames) { 378ff0cc061SDimitry Andric if (CPU.ArchID == AK && CPU.Default) 3797d523365SDimitry Andric return CPU.getName(); 380ff0cc061SDimitry Andric } 3817d523365SDimitry Andric 3827d523365SDimitry Andric // If we can't find a default then target the architecture instead 3837d523365SDimitry Andric return "generic"; 384ff0cc061SDimitry Andric } 385ff0cc061SDimitry Andric 3863ca95b02SDimitry Andric StringRef llvm::AArch64::getFPUName(unsigned FPUKind) { 3873ca95b02SDimitry Andric return ARM::getFPUName(FPUKind); 3883ca95b02SDimitry Andric } 3893ca95b02SDimitry Andric 3903ca95b02SDimitry Andric unsigned llvm::AArch64::getFPUVersion(unsigned FPUKind) { 3913ca95b02SDimitry Andric return ARM::getFPUVersion(FPUKind); 3923ca95b02SDimitry Andric } 3933ca95b02SDimitry Andric 3943ca95b02SDimitry Andric unsigned llvm::AArch64::getFPUNeonSupportLevel(unsigned FPUKind) { 3953ca95b02SDimitry Andric return ARM::getFPUNeonSupportLevel( FPUKind); 3963ca95b02SDimitry Andric } 3973ca95b02SDimitry Andric 3983ca95b02SDimitry Andric unsigned llvm::AArch64::getFPURestriction(unsigned FPUKind) { 3993ca95b02SDimitry Andric return ARM::getFPURestriction(FPUKind); 4003ca95b02SDimitry Andric } 4013ca95b02SDimitry Andric 4023ca95b02SDimitry Andric unsigned llvm::AArch64::getDefaultFPU(StringRef CPU, unsigned ArchKind) { 4033ca95b02SDimitry Andric if (CPU == "generic") 4043ca95b02SDimitry Andric return AArch64ARCHNames[ArchKind].DefaultFPU; 4053ca95b02SDimitry Andric 4063ca95b02SDimitry Andric return StringSwitch<unsigned>(CPU) 4073ca95b02SDimitry Andric #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 4083ca95b02SDimitry Andric .Case(NAME, DEFAULT_FPU) 4093ca95b02SDimitry Andric #include "llvm/Support/AArch64TargetParser.def" 4103ca95b02SDimitry Andric .Default(ARM::FK_INVALID); 4113ca95b02SDimitry Andric } 4123ca95b02SDimitry Andric 4133ca95b02SDimitry Andric unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, unsigned ArchKind) { 4143ca95b02SDimitry Andric if (CPU == "generic") 4153ca95b02SDimitry Andric return AArch64ARCHNames[ArchKind].ArchBaseExtensions; 4163ca95b02SDimitry Andric 4173ca95b02SDimitry Andric return StringSwitch<unsigned>(CPU) 4183ca95b02SDimitry Andric #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 4193ca95b02SDimitry Andric .Case(NAME, AArch64ARCHNames[ID].ArchBaseExtensions | DEFAULT_EXT) 4203ca95b02SDimitry Andric #include "llvm/Support/AArch64TargetParser.def" 4213ca95b02SDimitry Andric .Default(AArch64::AEK_INVALID); 4223ca95b02SDimitry Andric } 4233ca95b02SDimitry Andric 4243ca95b02SDimitry Andric bool llvm::AArch64::getExtensionFeatures(unsigned Extensions, 4253ca95b02SDimitry Andric std::vector<const char *> &Features) { 4263ca95b02SDimitry Andric 4273ca95b02SDimitry Andric if (Extensions == AArch64::AEK_INVALID) 4283ca95b02SDimitry Andric return false; 4293ca95b02SDimitry Andric 4303ca95b02SDimitry Andric if (Extensions & AArch64::AEK_FP) 4313ca95b02SDimitry Andric Features.push_back("+fp-armv8"); 4323ca95b02SDimitry Andric if (Extensions & AArch64::AEK_SIMD) 4333ca95b02SDimitry Andric Features.push_back("+neon"); 4343ca95b02SDimitry Andric if (Extensions & AArch64::AEK_CRC) 4353ca95b02SDimitry Andric Features.push_back("+crc"); 4363ca95b02SDimitry Andric if (Extensions & AArch64::AEK_CRYPTO) 4373ca95b02SDimitry Andric Features.push_back("+crypto"); 4383ca95b02SDimitry Andric if (Extensions & AArch64::AEK_FP16) 4393ca95b02SDimitry Andric Features.push_back("+fullfp16"); 4403ca95b02SDimitry Andric if (Extensions & AArch64::AEK_PROFILE) 4413ca95b02SDimitry Andric Features.push_back("+spe"); 4423ca95b02SDimitry Andric if (Extensions & AArch64::AEK_RAS) 4433ca95b02SDimitry Andric Features.push_back("+ras"); 4443ca95b02SDimitry Andric 4453ca95b02SDimitry Andric return true; 4463ca95b02SDimitry Andric } 4473ca95b02SDimitry Andric 4483ca95b02SDimitry Andric bool llvm::AArch64::getFPUFeatures(unsigned FPUKind, 4493ca95b02SDimitry Andric std::vector<const char *> &Features) { 4503ca95b02SDimitry Andric return ARM::getFPUFeatures(FPUKind, Features); 4513ca95b02SDimitry Andric } 4523ca95b02SDimitry Andric 4533ca95b02SDimitry Andric bool llvm::AArch64::getArchFeatures(unsigned ArchKind, 4543ca95b02SDimitry Andric std::vector<const char *> &Features) { 4553ca95b02SDimitry Andric if (ArchKind == ARM::AK_INVALID || ArchKind >= ARM::AK_LAST) 4563ca95b02SDimitry Andric return false; 4573ca95b02SDimitry Andric 4583ca95b02SDimitry Andric if (ArchKind == ARM::AK_ARMV8_1A) 4593ca95b02SDimitry Andric Features.push_back("+v8.1a"); 4603ca95b02SDimitry Andric if (ArchKind == ARM::AK_ARMV8_2A) 4613ca95b02SDimitry Andric Features.push_back("+v8.2a"); 4623ca95b02SDimitry Andric 4633ca95b02SDimitry Andric return true; 4643ca95b02SDimitry Andric } 4653ca95b02SDimitry Andric 4663ca95b02SDimitry Andric StringRef llvm::AArch64::getArchName(unsigned ArchKind) { 4673ca95b02SDimitry Andric for (const auto &AI : AArch64ARCHNames) 4683ca95b02SDimitry Andric if (AI.ID == ArchKind) 4693ca95b02SDimitry Andric return AI.getName(); 4703ca95b02SDimitry Andric return StringRef(); 4713ca95b02SDimitry Andric } 4723ca95b02SDimitry Andric 4733ca95b02SDimitry Andric StringRef llvm::AArch64::getCPUAttr(unsigned ArchKind) { 4743ca95b02SDimitry Andric for (const auto &AI : AArch64ARCHNames) 4753ca95b02SDimitry Andric if (AI.ID == ArchKind) 4763ca95b02SDimitry Andric return AI.getCPUAttr(); 4773ca95b02SDimitry Andric return StringRef(); 4783ca95b02SDimitry Andric } 4793ca95b02SDimitry Andric 4803ca95b02SDimitry Andric StringRef llvm::AArch64::getSubArch(unsigned ArchKind) { 4813ca95b02SDimitry Andric for (const auto &AI : AArch64ARCHNames) 4823ca95b02SDimitry Andric if (AI.ID == ArchKind) 4833ca95b02SDimitry Andric return AI.getSubArch(); 4843ca95b02SDimitry Andric return StringRef(); 4853ca95b02SDimitry Andric } 4863ca95b02SDimitry Andric 4873ca95b02SDimitry Andric unsigned llvm::AArch64::getArchAttr(unsigned ArchKind) { 4883ca95b02SDimitry Andric for (const auto &AI : AArch64ARCHNames) 4893ca95b02SDimitry Andric if (AI.ID == ArchKind) 4903ca95b02SDimitry Andric return AI.ArchAttr; 4913ca95b02SDimitry Andric return ARMBuildAttrs::CPUArch::v8_A; 4923ca95b02SDimitry Andric } 4933ca95b02SDimitry Andric 4943ca95b02SDimitry Andric StringRef llvm::AArch64::getArchExtName(unsigned AArchExtKind) { 4953ca95b02SDimitry Andric for (const auto &AE : AArch64ARCHExtNames) 4963ca95b02SDimitry Andric if (AArchExtKind == AE.ID) 4973ca95b02SDimitry Andric return AE.getName(); 4983ca95b02SDimitry Andric return StringRef(); 4993ca95b02SDimitry Andric } 5003ca95b02SDimitry Andric 5013ca95b02SDimitry Andric const char *llvm::AArch64::getArchExtFeature(StringRef ArchExt) { 5023ca95b02SDimitry Andric if (ArchExt.startswith("no")) { 5033ca95b02SDimitry Andric StringRef ArchExtBase(ArchExt.substr(2)); 5043ca95b02SDimitry Andric for (const auto &AE : AArch64ARCHExtNames) { 5053ca95b02SDimitry Andric if (AE.NegFeature && ArchExtBase == AE.getName()) 5063ca95b02SDimitry Andric return AE.NegFeature; 5073ca95b02SDimitry Andric } 5083ca95b02SDimitry Andric } 5093ca95b02SDimitry Andric 5103ca95b02SDimitry Andric for (const auto &AE : AArch64ARCHExtNames) 5113ca95b02SDimitry Andric if (AE.Feature && ArchExt == AE.getName()) 5123ca95b02SDimitry Andric return AE.Feature; 5133ca95b02SDimitry Andric return nullptr; 5143ca95b02SDimitry Andric } 5153ca95b02SDimitry Andric 5163ca95b02SDimitry Andric StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) { 5173ca95b02SDimitry Andric unsigned AK = parseArch(Arch); 5183ca95b02SDimitry Andric if (AK == ARM::AK_INVALID) 5193ca95b02SDimitry Andric return StringRef(); 5203ca95b02SDimitry Andric 5213ca95b02SDimitry Andric // Look for multiple AKs to find the default for pair AK+Name. 5223ca95b02SDimitry Andric for (const auto &CPU : AArch64CPUNames) 5233ca95b02SDimitry Andric if (CPU.ArchID == AK && CPU.Default) 5243ca95b02SDimitry Andric return CPU.getName(); 5253ca95b02SDimitry Andric 5263ca95b02SDimitry Andric // If we can't find a default then target the architecture instead 5273ca95b02SDimitry Andric return "generic"; 5283ca95b02SDimitry Andric } 5293ca95b02SDimitry Andric 5303ca95b02SDimitry Andric unsigned llvm::AArch64::checkArchVersion(StringRef Arch) { 5313ca95b02SDimitry Andric if (Arch[0] == 'v' && std::isdigit(Arch[1])) 5323ca95b02SDimitry Andric return (Arch[1] - 48); 5333ca95b02SDimitry Andric return 0; 5343ca95b02SDimitry Andric } 5353ca95b02SDimitry Andric 536ff0cc061SDimitry Andric // ======================================================= // 537ff0cc061SDimitry Andric // Parsers 538ff0cc061SDimitry Andric // ======================================================= // 539ff0cc061SDimitry Andric 5407d523365SDimitry Andric static StringRef getHWDivSynonym(StringRef HWDiv) { 5417d523365SDimitry Andric return StringSwitch<StringRef>(HWDiv) 5427d523365SDimitry Andric .Case("thumb,arm", "arm,thumb") 5437d523365SDimitry Andric .Default(HWDiv); 5447d523365SDimitry Andric } 5457d523365SDimitry Andric 5467d523365SDimitry Andric static StringRef getFPUSynonym(StringRef FPU) { 547ff0cc061SDimitry Andric return StringSwitch<StringRef>(FPU) 548ff0cc061SDimitry Andric .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported 549ff0cc061SDimitry Andric .Case("vfp2", "vfpv2") 550ff0cc061SDimitry Andric .Case("vfp3", "vfpv3") 551ff0cc061SDimitry Andric .Case("vfp4", "vfpv4") 552ff0cc061SDimitry Andric .Case("vfp3-d16", "vfpv3-d16") 553ff0cc061SDimitry Andric .Case("vfp4-d16", "vfpv4-d16") 55497bc6c73SDimitry Andric .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16") 555ff0cc061SDimitry Andric .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16") 55697bc6c73SDimitry Andric .Case("fp5-sp-d16", "fpv5-sp-d16") 557ff0cc061SDimitry Andric .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16") 558ff0cc061SDimitry Andric // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3. 559ff0cc061SDimitry Andric .Case("neon-vfpv3", "neon") 560ff0cc061SDimitry Andric .Default(FPU); 561ff0cc061SDimitry Andric } 562ff0cc061SDimitry Andric 5637d523365SDimitry Andric static StringRef getArchSynonym(StringRef Arch) { 564ff0cc061SDimitry Andric return StringSwitch<StringRef>(Arch) 5657d523365SDimitry Andric .Case("v5", "v5t") 5667d523365SDimitry Andric .Case("v5e", "v5te") 5677d523365SDimitry Andric .Case("v6j", "v6") 5687d523365SDimitry Andric .Case("v6hl", "v6k") 5697d523365SDimitry Andric .Cases("v6m", "v6sm", "v6s-m", "v6-m") 5707d523365SDimitry Andric .Cases("v6z", "v6zk", "v6kz") 5717d523365SDimitry Andric .Cases("v7", "v7a", "v7hl", "v7l", "v7-a") 57297bc6c73SDimitry Andric .Case("v7r", "v7-r") 57397bc6c73SDimitry Andric .Case("v7m", "v7-m") 57497bc6c73SDimitry Andric .Case("v7em", "v7e-m") 57597bc6c73SDimitry Andric .Cases("v8", "v8a", "aarch64", "arm64", "v8-a") 57697bc6c73SDimitry Andric .Case("v8.1a", "v8.1-a") 5777d523365SDimitry Andric .Case("v8.2a", "v8.2-a") 5783ca95b02SDimitry Andric .Case("v8m.base", "v8-m.base") 5793ca95b02SDimitry Andric .Case("v8m.main", "v8-m.main") 580ff0cc061SDimitry Andric .Default(Arch); 581ff0cc061SDimitry Andric } 582ff0cc061SDimitry Andric 583ff0cc061SDimitry Andric // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but 584ff0cc061SDimitry Andric // (iwmmxt|xscale)(eb)? is also permitted. If the former, return 585ff0cc061SDimitry Andric // "v.+", if the latter, return unmodified string, minus 'eb'. 586ff0cc061SDimitry Andric // If invalid, return empty string. 5877d523365SDimitry Andric StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) { 588ff0cc061SDimitry Andric size_t offset = StringRef::npos; 589ff0cc061SDimitry Andric StringRef A = Arch; 590ff0cc061SDimitry Andric StringRef Error = ""; 591ff0cc061SDimitry Andric 592ff0cc061SDimitry Andric // Begins with "arm" / "thumb", move past it. 593ff0cc061SDimitry Andric if (A.startswith("arm64")) 594ff0cc061SDimitry Andric offset = 5; 595ff0cc061SDimitry Andric else if (A.startswith("arm")) 596ff0cc061SDimitry Andric offset = 3; 597ff0cc061SDimitry Andric else if (A.startswith("thumb")) 598ff0cc061SDimitry Andric offset = 5; 599ff0cc061SDimitry Andric else if (A.startswith("aarch64")) { 600ff0cc061SDimitry Andric offset = 7; 601ff0cc061SDimitry Andric // AArch64 uses "_be", not "eb" suffix. 602ff0cc061SDimitry Andric if (A.find("eb") != StringRef::npos) 603ff0cc061SDimitry Andric return Error; 604ff0cc061SDimitry Andric if (A.substr(offset, 3) == "_be") 605ff0cc061SDimitry Andric offset += 3; 606ff0cc061SDimitry Andric } 607ff0cc061SDimitry Andric 608ff0cc061SDimitry Andric // Ex. "armebv7", move past the "eb". 609ff0cc061SDimitry Andric if (offset != StringRef::npos && A.substr(offset, 2) == "eb") 610ff0cc061SDimitry Andric offset += 2; 611ff0cc061SDimitry Andric // Or, if it ends with eb ("armv7eb"), chop it off. 612ff0cc061SDimitry Andric else if (A.endswith("eb")) 613ff0cc061SDimitry Andric A = A.substr(0, A.size() - 2); 614ff0cc061SDimitry Andric // Trim the head 615ff0cc061SDimitry Andric if (offset != StringRef::npos) 616ff0cc061SDimitry Andric A = A.substr(offset); 617ff0cc061SDimitry Andric 618ff0cc061SDimitry Andric // Empty string means offset reached the end, which means it's valid. 619ff0cc061SDimitry Andric if (A.empty()) 620ff0cc061SDimitry Andric return Arch; 621ff0cc061SDimitry Andric 622ff0cc061SDimitry Andric // Only match non-marketing names 623ff0cc061SDimitry Andric if (offset != StringRef::npos) { 624ff0cc061SDimitry Andric // Must start with 'vN'. 625ff0cc061SDimitry Andric if (A[0] != 'v' || !std::isdigit(A[1])) 626ff0cc061SDimitry Andric return Error; 627ff0cc061SDimitry Andric // Can't have an extra 'eb'. 628ff0cc061SDimitry Andric if (A.find("eb") != StringRef::npos) 629ff0cc061SDimitry Andric return Error; 630ff0cc061SDimitry Andric } 631ff0cc061SDimitry Andric 632ff0cc061SDimitry Andric // Arch will either be a 'v' name (v7a) or a marketing name (xscale). 633ff0cc061SDimitry Andric return A; 634ff0cc061SDimitry Andric } 635ff0cc061SDimitry Andric 6367d523365SDimitry Andric unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) { 6377d523365SDimitry Andric StringRef Syn = getHWDivSynonym(HWDiv); 6387d523365SDimitry Andric for (const auto D : HWDivNames) { 6397d523365SDimitry Andric if (Syn == D.getName()) 6407d523365SDimitry Andric return D.ID; 6417d523365SDimitry Andric } 6427d523365SDimitry Andric return ARM::AEK_INVALID; 6437d523365SDimitry Andric } 6447d523365SDimitry Andric 6457d523365SDimitry Andric unsigned llvm::ARM::parseFPU(StringRef FPU) { 646ff0cc061SDimitry Andric StringRef Syn = getFPUSynonym(FPU); 647ff0cc061SDimitry Andric for (const auto F : FPUNames) { 6487d523365SDimitry Andric if (Syn == F.getName()) 649ff0cc061SDimitry Andric return F.ID; 650ff0cc061SDimitry Andric } 651ff0cc061SDimitry Andric return ARM::FK_INVALID; 652ff0cc061SDimitry Andric } 653ff0cc061SDimitry Andric 654ff0cc061SDimitry Andric // Allows partial match, ex. "v7a" matches "armv7a". 6557d523365SDimitry Andric unsigned llvm::ARM::parseArch(StringRef Arch) { 65697bc6c73SDimitry Andric Arch = getCanonicalArchName(Arch); 657ff0cc061SDimitry Andric StringRef Syn = getArchSynonym(Arch); 658ff0cc061SDimitry Andric for (const auto A : ARCHNames) { 6597d523365SDimitry Andric if (A.getName().endswith(Syn)) 660ff0cc061SDimitry Andric return A.ID; 661ff0cc061SDimitry Andric } 662ff0cc061SDimitry Andric return ARM::AK_INVALID; 663ff0cc061SDimitry Andric } 664ff0cc061SDimitry Andric 6657d523365SDimitry Andric unsigned llvm::ARM::parseArchExt(StringRef ArchExt) { 666ff0cc061SDimitry Andric for (const auto A : ARCHExtNames) { 6677d523365SDimitry Andric if (ArchExt == A.getName()) 668ff0cc061SDimitry Andric return A.ID; 669ff0cc061SDimitry Andric } 670ff0cc061SDimitry Andric return ARM::AEK_INVALID; 671ff0cc061SDimitry Andric } 672ff0cc061SDimitry Andric 6737d523365SDimitry Andric unsigned llvm::ARM::parseCPUArch(StringRef CPU) { 674ff0cc061SDimitry Andric for (const auto C : CPUNames) { 6757d523365SDimitry Andric if (CPU == C.getName()) 676ff0cc061SDimitry Andric return C.ArchID; 677ff0cc061SDimitry Andric } 678ff0cc061SDimitry Andric return ARM::AK_INVALID; 679ff0cc061SDimitry Andric } 680ff0cc061SDimitry Andric 681ff0cc061SDimitry Andric // ARM, Thumb, AArch64 6827d523365SDimitry Andric unsigned llvm::ARM::parseArchISA(StringRef Arch) { 683ff0cc061SDimitry Andric return StringSwitch<unsigned>(Arch) 684ff0cc061SDimitry Andric .StartsWith("aarch64", ARM::IK_AARCH64) 685ff0cc061SDimitry Andric .StartsWith("arm64", ARM::IK_AARCH64) 686ff0cc061SDimitry Andric .StartsWith("thumb", ARM::IK_THUMB) 687ff0cc061SDimitry Andric .StartsWith("arm", ARM::IK_ARM) 688ff0cc061SDimitry Andric .Default(ARM::EK_INVALID); 689ff0cc061SDimitry Andric } 690ff0cc061SDimitry Andric 691ff0cc061SDimitry Andric // Little/Big endian 6927d523365SDimitry Andric unsigned llvm::ARM::parseArchEndian(StringRef Arch) { 6937d523365SDimitry Andric if (Arch.startswith("armeb") || Arch.startswith("thumbeb") || 694ff0cc061SDimitry Andric Arch.startswith("aarch64_be")) 695ff0cc061SDimitry Andric return ARM::EK_BIG; 696ff0cc061SDimitry Andric 697ff0cc061SDimitry Andric if (Arch.startswith("arm") || Arch.startswith("thumb")) { 698ff0cc061SDimitry Andric if (Arch.endswith("eb")) 699ff0cc061SDimitry Andric return ARM::EK_BIG; 700ff0cc061SDimitry Andric else 701ff0cc061SDimitry Andric return ARM::EK_LITTLE; 702ff0cc061SDimitry Andric } 703ff0cc061SDimitry Andric 704ff0cc061SDimitry Andric if (Arch.startswith("aarch64")) 705ff0cc061SDimitry Andric return ARM::EK_LITTLE; 706ff0cc061SDimitry Andric 707ff0cc061SDimitry Andric return ARM::EK_INVALID; 708ff0cc061SDimitry Andric } 709ff0cc061SDimitry Andric 710ff0cc061SDimitry Andric // Profile A/R/M 7117d523365SDimitry Andric unsigned llvm::ARM::parseArchProfile(StringRef Arch) { 712ff0cc061SDimitry Andric Arch = getCanonicalArchName(Arch); 713ff0cc061SDimitry Andric switch (parseArch(Arch)) { 714ff0cc061SDimitry Andric case ARM::AK_ARMV6M: 715ff0cc061SDimitry Andric case ARM::AK_ARMV7M: 716ff0cc061SDimitry Andric case ARM::AK_ARMV7EM: 7173ca95b02SDimitry Andric case ARM::AK_ARMV8MMainline: 7183ca95b02SDimitry Andric case ARM::AK_ARMV8MBaseline: 719ff0cc061SDimitry Andric return ARM::PK_M; 720ff0cc061SDimitry Andric case ARM::AK_ARMV7R: 721ff0cc061SDimitry Andric return ARM::PK_R; 722ff0cc061SDimitry Andric case ARM::AK_ARMV7A: 7237d523365SDimitry Andric case ARM::AK_ARMV7K: 724ff0cc061SDimitry Andric case ARM::AK_ARMV8A: 725ff0cc061SDimitry Andric case ARM::AK_ARMV8_1A: 7267d523365SDimitry Andric case ARM::AK_ARMV8_2A: 727ff0cc061SDimitry Andric return ARM::PK_A; 728ff0cc061SDimitry Andric } 729ff0cc061SDimitry Andric return ARM::PK_INVALID; 730ff0cc061SDimitry Andric } 731ff0cc061SDimitry Andric 732ff0cc061SDimitry Andric // Version number (ex. v7 = 7). 7337d523365SDimitry Andric unsigned llvm::ARM::parseArchVersion(StringRef Arch) { 734ff0cc061SDimitry Andric Arch = getCanonicalArchName(Arch); 735ff0cc061SDimitry Andric switch (parseArch(Arch)) { 736ff0cc061SDimitry Andric case ARM::AK_ARMV2: 737ff0cc061SDimitry Andric case ARM::AK_ARMV2A: 738ff0cc061SDimitry Andric return 2; 739ff0cc061SDimitry Andric case ARM::AK_ARMV3: 740ff0cc061SDimitry Andric case ARM::AK_ARMV3M: 741ff0cc061SDimitry Andric return 3; 742ff0cc061SDimitry Andric case ARM::AK_ARMV4: 743ff0cc061SDimitry Andric case ARM::AK_ARMV4T: 744ff0cc061SDimitry Andric return 4; 745ff0cc061SDimitry Andric case ARM::AK_ARMV5T: 746ff0cc061SDimitry Andric case ARM::AK_ARMV5TE: 747ff0cc061SDimitry Andric case ARM::AK_IWMMXT: 748ff0cc061SDimitry Andric case ARM::AK_IWMMXT2: 749ff0cc061SDimitry Andric case ARM::AK_XSCALE: 750ff0cc061SDimitry Andric case ARM::AK_ARMV5TEJ: 751ff0cc061SDimitry Andric return 5; 752ff0cc061SDimitry Andric case ARM::AK_ARMV6: 753ff0cc061SDimitry Andric case ARM::AK_ARMV6K: 754ff0cc061SDimitry Andric case ARM::AK_ARMV6T2: 7557d523365SDimitry Andric case ARM::AK_ARMV6KZ: 756ff0cc061SDimitry Andric case ARM::AK_ARMV6M: 757ff0cc061SDimitry Andric return 6; 758ff0cc061SDimitry Andric case ARM::AK_ARMV7A: 759ff0cc061SDimitry Andric case ARM::AK_ARMV7R: 760ff0cc061SDimitry Andric case ARM::AK_ARMV7M: 761ff0cc061SDimitry Andric case ARM::AK_ARMV7S: 762ff0cc061SDimitry Andric case ARM::AK_ARMV7EM: 7637d523365SDimitry Andric case ARM::AK_ARMV7K: 764ff0cc061SDimitry Andric return 7; 765ff0cc061SDimitry Andric case ARM::AK_ARMV8A: 766ff0cc061SDimitry Andric case ARM::AK_ARMV8_1A: 7677d523365SDimitry Andric case ARM::AK_ARMV8_2A: 7683ca95b02SDimitry Andric case ARM::AK_ARMV8MBaseline: 7693ca95b02SDimitry Andric case ARM::AK_ARMV8MMainline: 770ff0cc061SDimitry Andric return 8; 771ff0cc061SDimitry Andric } 772ff0cc061SDimitry Andric return 0; 773ff0cc061SDimitry Andric } 7743ca95b02SDimitry Andric 7753ca95b02SDimitry Andric StringRef llvm::AArch64::getCanonicalArchName(StringRef Arch) { 7763ca95b02SDimitry Andric return ARM::getCanonicalArchName(Arch); 7773ca95b02SDimitry Andric } 7783ca95b02SDimitry Andric 7793ca95b02SDimitry Andric unsigned llvm::AArch64::parseFPU(StringRef FPU) { 7803ca95b02SDimitry Andric return ARM::parseFPU(FPU); 7813ca95b02SDimitry Andric } 7823ca95b02SDimitry Andric 7833ca95b02SDimitry Andric // Allows partial match, ex. "v8a" matches "armv8a". 7843ca95b02SDimitry Andric unsigned llvm::AArch64::parseArch(StringRef Arch) { 7853ca95b02SDimitry Andric Arch = getCanonicalArchName(Arch); 7863ca95b02SDimitry Andric if (checkArchVersion(Arch) < 8) 7873ca95b02SDimitry Andric return ARM::AK_INVALID; 7883ca95b02SDimitry Andric 7893ca95b02SDimitry Andric StringRef Syn = getArchSynonym(Arch); 7903ca95b02SDimitry Andric for (const auto A : AArch64ARCHNames) { 7913ca95b02SDimitry Andric if (A.getName().endswith(Syn)) 7923ca95b02SDimitry Andric return A.ID; 7933ca95b02SDimitry Andric } 7943ca95b02SDimitry Andric return ARM::AK_INVALID; 7953ca95b02SDimitry Andric } 7963ca95b02SDimitry Andric 7973ca95b02SDimitry Andric unsigned llvm::AArch64::parseArchExt(StringRef ArchExt) { 7983ca95b02SDimitry Andric for (const auto A : AArch64ARCHExtNames) { 7993ca95b02SDimitry Andric if (ArchExt == A.getName()) 8003ca95b02SDimitry Andric return A.ID; 8013ca95b02SDimitry Andric } 8023ca95b02SDimitry Andric return AArch64::AEK_INVALID; 8033ca95b02SDimitry Andric } 8043ca95b02SDimitry Andric 8053ca95b02SDimitry Andric unsigned llvm::AArch64::parseCPUArch(StringRef CPU) { 8063ca95b02SDimitry Andric for (const auto C : AArch64CPUNames) { 8073ca95b02SDimitry Andric if (CPU == C.getName()) 8083ca95b02SDimitry Andric return C.ArchID; 8093ca95b02SDimitry Andric } 8103ca95b02SDimitry Andric return ARM::AK_INVALID; 8113ca95b02SDimitry Andric } 8123ca95b02SDimitry Andric 8133ca95b02SDimitry Andric // ARM, Thumb, AArch64 8143ca95b02SDimitry Andric unsigned llvm::AArch64::parseArchISA(StringRef Arch) { 8153ca95b02SDimitry Andric return ARM::parseArchISA(Arch); 8163ca95b02SDimitry Andric } 8173ca95b02SDimitry Andric 8183ca95b02SDimitry Andric // Little/Big endian 8193ca95b02SDimitry Andric unsigned llvm::AArch64::parseArchEndian(StringRef Arch) { 8203ca95b02SDimitry Andric return ARM::parseArchEndian(Arch); 8213ca95b02SDimitry Andric } 8223ca95b02SDimitry Andric 8233ca95b02SDimitry Andric // Profile A/R/M 8243ca95b02SDimitry Andric unsigned llvm::AArch64::parseArchProfile(StringRef Arch) { 8253ca95b02SDimitry Andric return ARM::parseArchProfile(Arch); 8263ca95b02SDimitry Andric } 8273ca95b02SDimitry Andric 8283ca95b02SDimitry Andric // Version number (ex. v8 = 8). 8293ca95b02SDimitry Andric unsigned llvm::AArch64::parseArchVersion(StringRef Arch) { 8303ca95b02SDimitry Andric return ARM::parseArchVersion(Arch); 8313ca95b02SDimitry Andric } 832