TargetParser.cpp revision 296417
1283625Sdim//===-- TargetParser - Parser for target features ---------------*- C++ -*-===// 2283625Sdim// 3283625Sdim// The LLVM Compiler Infrastructure 4283625Sdim// 5283625Sdim// This file is distributed under the University of Illinois Open Source 6283625Sdim// License. See LICENSE.TXT for details. 7283625Sdim// 8283625Sdim//===----------------------------------------------------------------------===// 9283625Sdim// 10283625Sdim// This file implements a target parser to recognise hardware features such as 11283625Sdim// FPU/CPU/ARCH names as well as specific support such as HDIV, etc. 12283625Sdim// 13283625Sdim//===----------------------------------------------------------------------===// 14283625Sdim 15283625Sdim#include "llvm/Support/ARMBuildAttributes.h" 16283625Sdim#include "llvm/Support/TargetParser.h" 17283625Sdim#include "llvm/ADT/StringExtras.h" 18283625Sdim#include "llvm/ADT/StringSwitch.h" 19296417Sdim#include "llvm/ADT/Twine.h" 20283625Sdim#include <cctype> 21283625Sdim 22283625Sdimusing namespace llvm; 23296417Sdimusing namespace ARM; 24283625Sdim 25283625Sdimnamespace { 26283625Sdim 27284236Sdim// List of canonical FPU names (use getFPUSynonym) and which architectural 28284236Sdim// features they correspond to (use getFPUFeatures). 29283625Sdim// FIXME: TableGen this. 30285181Sdim// The entries must appear in the order listed in ARM::FPUKind for correct indexing 31296417Sdimstatic const struct { 32296417Sdim const char *NameCStr; 33296417Sdim size_t NameLength; 34283625Sdim ARM::FPUKind ID; 35285181Sdim ARM::FPUVersion FPUVersion; 36284236Sdim ARM::NeonSupportLevel NeonSupport; 37284236Sdim ARM::FPURestriction Restriction; 38296417Sdim 39296417Sdim StringRef getName() const { return StringRef(NameCStr, NameLength); } 40283625Sdim} FPUNames[] = { 41296417Sdim#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \ 42296417Sdim { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION }, 43296417Sdim#include "llvm/Support/ARMTargetParser.def" 44283625Sdim}; 45284236Sdim 46284236Sdim// List of canonical arch names (use getArchSynonym). 47284236Sdim// This table also provides the build attribute fields for CPU arch 48284236Sdim// and Arch ID, according to the Addenda to the ARM ABI, chapters 49284236Sdim// 2.4 and 2.3.5.2 respectively. 50284236Sdim// FIXME: SubArch values were simplified to fit into the expectations 51284236Sdim// of the triples and are not conforming with their official names. 52284236Sdim// Check to see if the expectation should be changed. 53283625Sdim// FIXME: TableGen this. 54296417Sdimstatic const struct { 55296417Sdim const char *NameCStr; 56296417Sdim size_t NameLength; 57296417Sdim const char *CPUAttrCStr; 58296417Sdim size_t CPUAttrLength; 59296417Sdim const char *SubArchCStr; 60296417Sdim size_t SubArchLength; 61296417Sdim unsigned DefaultFPU; 62296417Sdim unsigned ArchBaseExtensions; 63283625Sdim ARM::ArchKind ID; 64284236Sdim ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes. 65296417Sdim 66296417Sdim StringRef getName() const { return StringRef(NameCStr, NameLength); } 67296417Sdim 68296417Sdim // CPU class in build attributes. 69296417Sdim StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); } 70296417Sdim 71296417Sdim // Sub-Arch name. 72296417Sdim StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); } 73283625Sdim} ARCHNames[] = { 74296417Sdim#define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \ 75296417Sdim {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \ 76296417Sdim sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ID, ARCH_ATTR}, 77296417Sdim#include "llvm/Support/ARMTargetParser.def" 78283625Sdim}; 79296417Sdim 80284236Sdim// List of Arch Extension names. 81283625Sdim// FIXME: TableGen this. 82296417Sdimstatic const struct { 83296417Sdim const char *NameCStr; 84296417Sdim size_t NameLength; 85296417Sdim unsigned ID; 86296417Sdim const char *Feature; 87296417Sdim const char *NegFeature; 88296417Sdim 89296417Sdim StringRef getName() const { return StringRef(NameCStr, NameLength); } 90283625Sdim} ARCHExtNames[] = { 91296417Sdim#define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \ 92296417Sdim { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE }, 93296417Sdim#include "llvm/Support/ARMTargetParser.def" 94283625Sdim}; 95296417Sdim 96296417Sdim// List of HWDiv names (use getHWDivSynonym) and which architectural 97296417Sdim// features they correspond to (use getHWDivFeatures). 98296417Sdim// FIXME: TableGen this. 99296417Sdimstatic const struct { 100296417Sdim const char *NameCStr; 101296417Sdim size_t NameLength; 102296417Sdim unsigned ID; 103296417Sdim 104296417Sdim StringRef getName() const { return StringRef(NameCStr, NameLength); } 105296417Sdim} HWDivNames[] = { 106296417Sdim#define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID }, 107296417Sdim#include "llvm/Support/ARMTargetParser.def" 108296417Sdim}; 109296417Sdim 110283625Sdim// List of CPU names and their arches. 111283625Sdim// The same CPU can have multiple arches and can be default on multiple arches. 112283625Sdim// When finding the Arch for a CPU, first-found prevails. Sort them accordingly. 113284236Sdim// When this becomes table-generated, we'd probably need two tables. 114283625Sdim// FIXME: TableGen this. 115296417Sdimstatic const struct { 116296417Sdim const char *NameCStr; 117296417Sdim size_t NameLength; 118283625Sdim ARM::ArchKind ArchID; 119296417Sdim bool Default; // is $Name the default CPU for $ArchID ? 120296417Sdim unsigned DefaultExtensions; 121296417Sdim 122296417Sdim StringRef getName() const { return StringRef(NameCStr, NameLength); } 123283625Sdim} CPUNames[] = { 124296417Sdim#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 125296417Sdim { NAME, sizeof(NAME) - 1, ID, IS_DEFAULT, DEFAULT_EXT }, 126296417Sdim#include "llvm/Support/ARMTargetParser.def" 127283625Sdim}; 128283625Sdim 129283625Sdim} // namespace 130283625Sdim 131283625Sdim// ======================================================= // 132283625Sdim// Information by ID 133283625Sdim// ======================================================= // 134283625Sdim 135296417SdimStringRef llvm::ARM::getFPUName(unsigned FPUKind) { 136283625Sdim if (FPUKind >= ARM::FK_LAST) 137296417Sdim return StringRef(); 138296417Sdim return FPUNames[FPUKind].getName(); 139283625Sdim} 140283625Sdim 141296417Sdimunsigned llvm::ARM::getFPUVersion(unsigned FPUKind) { 142284236Sdim if (FPUKind >= ARM::FK_LAST) 143284236Sdim return 0; 144284236Sdim return FPUNames[FPUKind].FPUVersion; 145284236Sdim} 146284236Sdim 147296417Sdimunsigned llvm::ARM::getFPUNeonSupportLevel(unsigned FPUKind) { 148284236Sdim if (FPUKind >= ARM::FK_LAST) 149284236Sdim return 0; 150284236Sdim return FPUNames[FPUKind].NeonSupport; 151284236Sdim} 152284236Sdim 153296417Sdimunsigned llvm::ARM::getFPURestriction(unsigned FPUKind) { 154284236Sdim if (FPUKind >= ARM::FK_LAST) 155284236Sdim return 0; 156284236Sdim return FPUNames[FPUKind].Restriction; 157284236Sdim} 158284236Sdim 159296417Sdimunsigned llvm::ARM::getDefaultFPU(StringRef CPU, unsigned ArchKind) { 160296417Sdim if (CPU == "generic") 161296417Sdim return ARCHNames[ArchKind].DefaultFPU; 162296417Sdim 163296417Sdim return StringSwitch<unsigned>(CPU) 164296417Sdim#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 165296417Sdim .Case(NAME, DEFAULT_FPU) 166296417Sdim#include "llvm/Support/ARMTargetParser.def" 167296417Sdim .Default(ARM::FK_INVALID); 168296417Sdim} 169296417Sdim 170296417Sdimunsigned llvm::ARM::getDefaultExtensions(StringRef CPU, unsigned ArchKind) { 171296417Sdim if (CPU == "generic") 172296417Sdim return ARCHNames[ArchKind].ArchBaseExtensions; 173296417Sdim 174296417Sdim return StringSwitch<unsigned>(CPU) 175296417Sdim#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 176296417Sdim .Case(NAME, ARCHNames[ID].ArchBaseExtensions | DEFAULT_EXT) 177296417Sdim#include "llvm/Support/ARMTargetParser.def" 178296417Sdim .Default(ARM::AEK_INVALID); 179296417Sdim} 180296417Sdim 181296417Sdimbool llvm::ARM::getHWDivFeatures(unsigned HWDivKind, 182296417Sdim std::vector<const char *> &Features) { 183296417Sdim 184296417Sdim if (HWDivKind == ARM::AEK_INVALID) 185296417Sdim return false; 186296417Sdim 187296417Sdim if (HWDivKind & ARM::AEK_HWDIVARM) 188296417Sdim Features.push_back("+hwdiv-arm"); 189296417Sdim else 190296417Sdim Features.push_back("-hwdiv-arm"); 191296417Sdim 192296417Sdim if (HWDivKind & ARM::AEK_HWDIV) 193296417Sdim Features.push_back("+hwdiv"); 194296417Sdim else 195296417Sdim Features.push_back("-hwdiv"); 196296417Sdim 197296417Sdim return true; 198296417Sdim} 199296417Sdim 200296417Sdimbool llvm::ARM::getExtensionFeatures(unsigned Extensions, 201284236Sdim std::vector<const char *> &Features) { 202284236Sdim 203296417Sdim if (Extensions == ARM::AEK_INVALID) 204296417Sdim return false; 205296417Sdim 206296417Sdim if (Extensions & ARM::AEK_CRC) 207296417Sdim Features.push_back("+crc"); 208296417Sdim else 209296417Sdim Features.push_back("-crc"); 210296417Sdim 211296417Sdim if (Extensions & ARM::AEK_DSP) 212296417Sdim Features.push_back("+dsp"); 213296417Sdim else 214296417Sdim Features.push_back("-dsp"); 215296417Sdim 216296417Sdim return getHWDivFeatures(Extensions, Features); 217296417Sdim} 218296417Sdim 219296417Sdimbool llvm::ARM::getFPUFeatures(unsigned FPUKind, 220296417Sdim std::vector<const char *> &Features) { 221296417Sdim 222284236Sdim if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID) 223284236Sdim return false; 224284236Sdim 225284236Sdim // fp-only-sp and d16 subtarget features are independent of each other, so we 226284236Sdim // must enable/disable both. 227284236Sdim switch (FPUNames[FPUKind].Restriction) { 228284236Sdim case ARM::FR_SP_D16: 229284236Sdim Features.push_back("+fp-only-sp"); 230284236Sdim Features.push_back("+d16"); 231284236Sdim break; 232284236Sdim case ARM::FR_D16: 233284236Sdim Features.push_back("-fp-only-sp"); 234284236Sdim Features.push_back("+d16"); 235284236Sdim break; 236284236Sdim case ARM::FR_None: 237284236Sdim Features.push_back("-fp-only-sp"); 238284236Sdim Features.push_back("-d16"); 239284236Sdim break; 240284236Sdim } 241284236Sdim 242284236Sdim // FPU version subtarget features are inclusive of lower-numbered ones, so 243284236Sdim // enable the one corresponding to this version and disable all that are 244284734Sdim // higher. We also have to make sure to disable fp16 when vfp4 is disabled, 245284734Sdim // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16. 246284236Sdim switch (FPUNames[FPUKind].FPUVersion) { 247285181Sdim case ARM::FV_VFPV5: 248284236Sdim Features.push_back("+fp-armv8"); 249284236Sdim break; 250285181Sdim case ARM::FV_VFPV4: 251284236Sdim Features.push_back("+vfp4"); 252284236Sdim Features.push_back("-fp-armv8"); 253284236Sdim break; 254285181Sdim case ARM::FV_VFPV3_FP16: 255284236Sdim Features.push_back("+vfp3"); 256285181Sdim Features.push_back("+fp16"); 257285181Sdim Features.push_back("-vfp4"); 258285181Sdim Features.push_back("-fp-armv8"); 259285181Sdim break; 260285181Sdim case ARM::FV_VFPV3: 261285181Sdim Features.push_back("+vfp3"); 262284734Sdim Features.push_back("-fp16"); 263284236Sdim Features.push_back("-vfp4"); 264284236Sdim Features.push_back("-fp-armv8"); 265284236Sdim break; 266285181Sdim case ARM::FV_VFPV2: 267284236Sdim Features.push_back("+vfp2"); 268284236Sdim Features.push_back("-vfp3"); 269284734Sdim Features.push_back("-fp16"); 270284236Sdim Features.push_back("-vfp4"); 271284236Sdim Features.push_back("-fp-armv8"); 272284236Sdim break; 273285181Sdim case ARM::FV_NONE: 274284236Sdim Features.push_back("-vfp2"); 275284236Sdim Features.push_back("-vfp3"); 276284734Sdim Features.push_back("-fp16"); 277284236Sdim Features.push_back("-vfp4"); 278284236Sdim Features.push_back("-fp-armv8"); 279284236Sdim break; 280284236Sdim } 281284236Sdim 282284236Sdim // crypto includes neon, so we handle this similarly to FPU version. 283284236Sdim switch (FPUNames[FPUKind].NeonSupport) { 284284236Sdim case ARM::NS_Crypto: 285296417Sdim Features.push_back("+neon"); 286284236Sdim Features.push_back("+crypto"); 287284236Sdim break; 288284236Sdim case ARM::NS_Neon: 289284236Sdim Features.push_back("+neon"); 290284236Sdim Features.push_back("-crypto"); 291284236Sdim break; 292284236Sdim case ARM::NS_None: 293284236Sdim Features.push_back("-neon"); 294284236Sdim Features.push_back("-crypto"); 295284236Sdim break; 296284236Sdim } 297284236Sdim 298284236Sdim return true; 299284236Sdim} 300284236Sdim 301296417SdimStringRef llvm::ARM::getArchName(unsigned ArchKind) { 302283625Sdim if (ArchKind >= ARM::AK_LAST) 303296417Sdim return StringRef(); 304296417Sdim return ARCHNames[ArchKind].getName(); 305283625Sdim} 306283625Sdim 307296417SdimStringRef llvm::ARM::getCPUAttr(unsigned ArchKind) { 308283625Sdim if (ArchKind >= ARM::AK_LAST) 309296417Sdim return StringRef(); 310296417Sdim return ARCHNames[ArchKind].getCPUAttr(); 311283625Sdim} 312283625Sdim 313296417SdimStringRef llvm::ARM::getSubArch(unsigned ArchKind) { 314283625Sdim if (ArchKind >= ARM::AK_LAST) 315296417Sdim return StringRef(); 316296417Sdim return ARCHNames[ArchKind].getSubArch(); 317284236Sdim} 318284236Sdim 319296417Sdimunsigned llvm::ARM::getArchAttr(unsigned ArchKind) { 320284236Sdim if (ArchKind >= ARM::AK_LAST) 321283625Sdim return ARMBuildAttrs::CPUArch::Pre_v4; 322284236Sdim return ARCHNames[ArchKind].ArchAttr; 323283625Sdim} 324283625Sdim 325296417SdimStringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) { 326296417Sdim for (const auto AE : ARCHExtNames) { 327296417Sdim if (ArchExtKind == AE.ID) 328296417Sdim return AE.getName(); 329296417Sdim } 330296417Sdim return StringRef(); 331283625Sdim} 332283625Sdim 333296417Sdimconst char *llvm::ARM::getArchExtFeature(StringRef ArchExt) { 334296417Sdim if (ArchExt.startswith("no")) { 335296417Sdim StringRef ArchExtBase(ArchExt.substr(2)); 336296417Sdim for (const auto AE : ARCHExtNames) { 337296417Sdim if (AE.NegFeature && ArchExtBase == AE.getName()) 338296417Sdim return AE.NegFeature; 339296417Sdim } 340296417Sdim } 341296417Sdim for (const auto AE : ARCHExtNames) { 342296417Sdim if (AE.Feature && ArchExt == AE.getName()) 343296417Sdim return AE.Feature; 344296417Sdim } 345296417Sdim 346296417Sdim return nullptr; 347296417Sdim} 348296417Sdim 349296417SdimStringRef llvm::ARM::getHWDivName(unsigned HWDivKind) { 350296417Sdim for (const auto D : HWDivNames) { 351296417Sdim if (HWDivKind == D.ID) 352296417Sdim return D.getName(); 353296417Sdim } 354296417Sdim return StringRef(); 355296417Sdim} 356296417Sdim 357296417SdimStringRef llvm::ARM::getDefaultCPU(StringRef Arch) { 358283625Sdim unsigned AK = parseArch(Arch); 359283625Sdim if (AK == ARM::AK_INVALID) 360296417Sdim return StringRef(); 361283625Sdim 362283625Sdim // Look for multiple AKs to find the default for pair AK+Name. 363283625Sdim for (const auto CPU : CPUNames) { 364283625Sdim if (CPU.ArchID == AK && CPU.Default) 365296417Sdim return CPU.getName(); 366283625Sdim } 367296417Sdim 368296417Sdim // If we can't find a default then target the architecture instead 369296417Sdim return "generic"; 370283625Sdim} 371283625Sdim 372283625Sdim// ======================================================= // 373283625Sdim// Parsers 374283625Sdim// ======================================================= // 375283625Sdim 376296417Sdimstatic StringRef getHWDivSynonym(StringRef HWDiv) { 377296417Sdim return StringSwitch<StringRef>(HWDiv) 378296417Sdim .Case("thumb,arm", "arm,thumb") 379296417Sdim .Default(HWDiv); 380296417Sdim} 381296417Sdim 382296417Sdimstatic StringRef getFPUSynonym(StringRef FPU) { 383283625Sdim return StringSwitch<StringRef>(FPU) 384296417Sdim .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported 385296417Sdim .Case("vfp2", "vfpv2") 386296417Sdim .Case("vfp3", "vfpv3") 387296417Sdim .Case("vfp4", "vfpv4") 388296417Sdim .Case("vfp3-d16", "vfpv3-d16") 389296417Sdim .Case("vfp4-d16", "vfpv4-d16") 390296417Sdim .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16") 391296417Sdim .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16") 392296417Sdim .Case("fp5-sp-d16", "fpv5-sp-d16") 393296417Sdim .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16") 394296417Sdim // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3. 395296417Sdim .Case("neon-vfpv3", "neon") 396296417Sdim .Default(FPU); 397283625Sdim} 398283625Sdim 399296417Sdimstatic StringRef getArchSynonym(StringRef Arch) { 400283625Sdim return StringSwitch<StringRef>(Arch) 401296417Sdim .Case("v5", "v5t") 402296417Sdim .Case("v5e", "v5te") 403296417Sdim .Case("v6j", "v6") 404296417Sdim .Case("v6hl", "v6k") 405296417Sdim .Cases("v6m", "v6sm", "v6s-m", "v6-m") 406296417Sdim .Cases("v6z", "v6zk", "v6kz") 407296417Sdim .Cases("v7", "v7a", "v7hl", "v7l", "v7-a") 408296417Sdim .Case("v7r", "v7-r") 409296417Sdim .Case("v7m", "v7-m") 410296417Sdim .Case("v7em", "v7e-m") 411296417Sdim .Cases("v8", "v8a", "aarch64", "arm64", "v8-a") 412296417Sdim .Case("v8.1a", "v8.1-a") 413296417Sdim .Case("v8.2a", "v8.2-a") 414296417Sdim .Default(Arch); 415283625Sdim} 416283625Sdim 417283625Sdim// MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but 418283625Sdim// (iwmmxt|xscale)(eb)? is also permitted. If the former, return 419283625Sdim// "v.+", if the latter, return unmodified string, minus 'eb'. 420283625Sdim// If invalid, return empty string. 421296417SdimStringRef llvm::ARM::getCanonicalArchName(StringRef Arch) { 422283625Sdim size_t offset = StringRef::npos; 423283625Sdim StringRef A = Arch; 424283625Sdim StringRef Error = ""; 425283625Sdim 426283625Sdim // Begins with "arm" / "thumb", move past it. 427283625Sdim if (A.startswith("arm64")) 428283625Sdim offset = 5; 429283625Sdim else if (A.startswith("arm")) 430283625Sdim offset = 3; 431283625Sdim else if (A.startswith("thumb")) 432283625Sdim offset = 5; 433283625Sdim else if (A.startswith("aarch64")) { 434283625Sdim offset = 7; 435283625Sdim // AArch64 uses "_be", not "eb" suffix. 436283625Sdim if (A.find("eb") != StringRef::npos) 437283625Sdim return Error; 438296417Sdim if (A.substr(offset, 3) == "_be") 439283625Sdim offset += 3; 440283625Sdim } 441283625Sdim 442283625Sdim // Ex. "armebv7", move past the "eb". 443283625Sdim if (offset != StringRef::npos && A.substr(offset, 2) == "eb") 444283625Sdim offset += 2; 445283625Sdim // Or, if it ends with eb ("armv7eb"), chop it off. 446283625Sdim else if (A.endswith("eb")) 447283625Sdim A = A.substr(0, A.size() - 2); 448283625Sdim // Trim the head 449283625Sdim if (offset != StringRef::npos) 450283625Sdim A = A.substr(offset); 451283625Sdim 452283625Sdim // Empty string means offset reached the end, which means it's valid. 453283625Sdim if (A.empty()) 454283625Sdim return Arch; 455283625Sdim 456283625Sdim // Only match non-marketing names 457283625Sdim if (offset != StringRef::npos) { 458296417Sdim // Must start with 'vN'. 459283625Sdim if (A[0] != 'v' || !std::isdigit(A[1])) 460283625Sdim return Error; 461283625Sdim // Can't have an extra 'eb'. 462283625Sdim if (A.find("eb") != StringRef::npos) 463283625Sdim return Error; 464283625Sdim } 465283625Sdim 466283625Sdim // Arch will either be a 'v' name (v7a) or a marketing name (xscale). 467283625Sdim return A; 468283625Sdim} 469283625Sdim 470296417Sdimunsigned llvm::ARM::parseHWDiv(StringRef HWDiv) { 471296417Sdim StringRef Syn = getHWDivSynonym(HWDiv); 472296417Sdim for (const auto D : HWDivNames) { 473296417Sdim if (Syn == D.getName()) 474296417Sdim return D.ID; 475296417Sdim } 476296417Sdim return ARM::AEK_INVALID; 477296417Sdim} 478296417Sdim 479296417Sdimunsigned llvm::ARM::parseFPU(StringRef FPU) { 480283625Sdim StringRef Syn = getFPUSynonym(FPU); 481283625Sdim for (const auto F : FPUNames) { 482296417Sdim if (Syn == F.getName()) 483283625Sdim return F.ID; 484283625Sdim } 485283625Sdim return ARM::FK_INVALID; 486283625Sdim} 487283625Sdim 488283625Sdim// Allows partial match, ex. "v7a" matches "armv7a". 489296417Sdimunsigned llvm::ARM::parseArch(StringRef Arch) { 490284236Sdim Arch = getCanonicalArchName(Arch); 491283625Sdim StringRef Syn = getArchSynonym(Arch); 492283625Sdim for (const auto A : ARCHNames) { 493296417Sdim if (A.getName().endswith(Syn)) 494283625Sdim return A.ID; 495283625Sdim } 496283625Sdim return ARM::AK_INVALID; 497283625Sdim} 498283625Sdim 499296417Sdimunsigned llvm::ARM::parseArchExt(StringRef ArchExt) { 500283625Sdim for (const auto A : ARCHExtNames) { 501296417Sdim if (ArchExt == A.getName()) 502283625Sdim return A.ID; 503283625Sdim } 504283625Sdim return ARM::AEK_INVALID; 505283625Sdim} 506283625Sdim 507296417Sdimunsigned llvm::ARM::parseCPUArch(StringRef CPU) { 508283625Sdim for (const auto C : CPUNames) { 509296417Sdim if (CPU == C.getName()) 510283625Sdim return C.ArchID; 511283625Sdim } 512283625Sdim return ARM::AK_INVALID; 513283625Sdim} 514283625Sdim 515283625Sdim// ARM, Thumb, AArch64 516296417Sdimunsigned llvm::ARM::parseArchISA(StringRef Arch) { 517283625Sdim return StringSwitch<unsigned>(Arch) 518283625Sdim .StartsWith("aarch64", ARM::IK_AARCH64) 519296417Sdim .StartsWith("arm64", ARM::IK_AARCH64) 520296417Sdim .StartsWith("thumb", ARM::IK_THUMB) 521296417Sdim .StartsWith("arm", ARM::IK_ARM) 522283625Sdim .Default(ARM::EK_INVALID); 523283625Sdim} 524283625Sdim 525283625Sdim// Little/Big endian 526296417Sdimunsigned llvm::ARM::parseArchEndian(StringRef Arch) { 527296417Sdim if (Arch.startswith("armeb") || Arch.startswith("thumbeb") || 528283625Sdim Arch.startswith("aarch64_be")) 529283625Sdim return ARM::EK_BIG; 530283625Sdim 531283625Sdim if (Arch.startswith("arm") || Arch.startswith("thumb")) { 532283625Sdim if (Arch.endswith("eb")) 533283625Sdim return ARM::EK_BIG; 534283625Sdim else 535283625Sdim return ARM::EK_LITTLE; 536283625Sdim } 537283625Sdim 538283625Sdim if (Arch.startswith("aarch64")) 539283625Sdim return ARM::EK_LITTLE; 540283625Sdim 541283625Sdim return ARM::EK_INVALID; 542283625Sdim} 543283625Sdim 544283625Sdim// Profile A/R/M 545296417Sdimunsigned llvm::ARM::parseArchProfile(StringRef Arch) { 546283625Sdim Arch = getCanonicalArchName(Arch); 547296417Sdim switch (parseArch(Arch)) { 548283625Sdim case ARM::AK_ARMV6M: 549283625Sdim case ARM::AK_ARMV7M: 550283625Sdim case ARM::AK_ARMV7EM: 551283625Sdim return ARM::PK_M; 552283625Sdim case ARM::AK_ARMV7R: 553283625Sdim return ARM::PK_R; 554283625Sdim case ARM::AK_ARMV7A: 555296417Sdim case ARM::AK_ARMV7K: 556283625Sdim case ARM::AK_ARMV8A: 557283625Sdim case ARM::AK_ARMV8_1A: 558296417Sdim case ARM::AK_ARMV8_2A: 559283625Sdim return ARM::PK_A; 560283625Sdim } 561283625Sdim return ARM::PK_INVALID; 562283625Sdim} 563283625Sdim 564283625Sdim// Version number (ex. v7 = 7). 565296417Sdimunsigned llvm::ARM::parseArchVersion(StringRef Arch) { 566283625Sdim Arch = getCanonicalArchName(Arch); 567296417Sdim switch (parseArch(Arch)) { 568283625Sdim case ARM::AK_ARMV2: 569283625Sdim case ARM::AK_ARMV2A: 570283625Sdim return 2; 571283625Sdim case ARM::AK_ARMV3: 572283625Sdim case ARM::AK_ARMV3M: 573283625Sdim return 3; 574283625Sdim case ARM::AK_ARMV4: 575283625Sdim case ARM::AK_ARMV4T: 576283625Sdim return 4; 577283625Sdim case ARM::AK_ARMV5T: 578283625Sdim case ARM::AK_ARMV5TE: 579283625Sdim case ARM::AK_IWMMXT: 580283625Sdim case ARM::AK_IWMMXT2: 581283625Sdim case ARM::AK_XSCALE: 582283625Sdim case ARM::AK_ARMV5TEJ: 583283625Sdim return 5; 584283625Sdim case ARM::AK_ARMV6: 585283625Sdim case ARM::AK_ARMV6K: 586283625Sdim case ARM::AK_ARMV6T2: 587296417Sdim case ARM::AK_ARMV6KZ: 588283625Sdim case ARM::AK_ARMV6M: 589283625Sdim return 6; 590283625Sdim case ARM::AK_ARMV7A: 591283625Sdim case ARM::AK_ARMV7R: 592283625Sdim case ARM::AK_ARMV7M: 593283625Sdim case ARM::AK_ARMV7S: 594283625Sdim case ARM::AK_ARMV7EM: 595296417Sdim case ARM::AK_ARMV7K: 596283625Sdim return 7; 597283625Sdim case ARM::AK_ARMV8A: 598283625Sdim case ARM::AK_ARMV8_1A: 599296417Sdim case ARM::AK_ARMV8_2A: 600283625Sdim return 8; 601283625Sdim } 602283625Sdim return 0; 603283625Sdim} 604