1 //===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements a target parser to recognise hardware features such as
11 // FPU/CPU/ARCH names as well as specific support such as HDIV, etc.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Support/ARMBuildAttributes.h"
16 #include "llvm/Support/TargetParser.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/ADT/Twine.h"
24 using namespace AArch64;
28 // List of canonical FPU names (use getFPUSynonym) and which architectural
29 // features they correspond to (use getFPUFeatures).
30 // FIXME: TableGen this.
31 // The entries must appear in the order listed in ARM::FPUKind for correct indexing
36 ARM::FPUVersion FPUVersion;
37 ARM::NeonSupportLevel NeonSupport;
38 ARM::FPURestriction Restriction;
40 StringRef getName() const { return StringRef(NameCStr, NameLength); }
42 #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
43 { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION },
44 #include "llvm/Support/ARMTargetParser.def"
47 // List of canonical arch names (use getArchSynonym).
48 // This table also provides the build attribute fields for CPU arch
49 // and Arch ID, according to the Addenda to the ARM ABI, chapters
50 // 2.4 and 2.3.5.2 respectively.
51 // FIXME: SubArch values were simplified to fit into the expectations
52 // of the triples and are not conforming with their official names.
53 // Check to see if the expectation should be changed.
54 // FIXME: TableGen this.
55 template <typename T> struct ArchNames {
58 const char *CPUAttrCStr;
60 const char *SubArchCStr;
63 unsigned ArchBaseExtensions;
65 ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
67 StringRef getName() const { return StringRef(NameCStr, NameLength); }
69 // CPU class in build attributes.
70 StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
73 StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
75 ArchNames<ARM::ArchKind> ARCHNames[] = {
76 #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
77 {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
78 sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ID, ARCH_ATTR},
79 #include "llvm/Support/ARMTargetParser.def"
82 ArchNames<AArch64::ArchKind> AArch64ARCHNames[] = {
83 #define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
84 {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
85 sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, AArch64::ArchKind::ID, ARCH_ATTR},
86 #include "llvm/Support/AArch64TargetParser.def"
90 // List of Arch Extension names.
91 // FIXME: TableGen this.
97 const char *NegFeature;
99 StringRef getName() const { return StringRef(NameCStr, NameLength); }
101 #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
102 { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
103 #include "llvm/Support/ARMTargetParser.def"
104 },AArch64ARCHExtNames[] = {
105 #define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
106 { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
107 #include "llvm/Support/AArch64TargetParser.def"
110 // List of HWDiv names (use getHWDivSynonym) and which architectural
111 // features they correspond to (use getHWDivFeatures).
112 // FIXME: TableGen this.
113 static const struct {
114 const char *NameCStr;
118 StringRef getName() const { return StringRef(NameCStr, NameLength); }
120 #define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
121 #include "llvm/Support/ARMTargetParser.def"
124 // List of CPU names and their arches.
125 // The same CPU can have multiple arches and can be default on multiple arches.
126 // When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
127 // When this becomes table-generated, we'd probably need two tables.
128 // FIXME: TableGen this.
129 template <typename T> struct CpuNames {
130 const char *NameCStr;
133 bool Default; // is $Name the default CPU for $ArchID ?
134 unsigned DefaultExtensions;
136 StringRef getName() const { return StringRef(NameCStr, NameLength); }
138 CpuNames<ARM::ArchKind> CPUNames[] = {
139 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
140 { NAME, sizeof(NAME) - 1, ID, IS_DEFAULT, DEFAULT_EXT },
141 #include "llvm/Support/ARMTargetParser.def"
144 CpuNames<AArch64::ArchKind> AArch64CPUNames[] = {
145 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
146 { NAME, sizeof(NAME) - 1, AArch64::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
147 #include "llvm/Support/AArch64TargetParser.def"
152 // ======================================================= //
154 // ======================================================= //
156 StringRef llvm::ARM::getFPUName(unsigned FPUKind) {
157 if (FPUKind >= ARM::FK_LAST)
159 return FPUNames[FPUKind].getName();
162 unsigned llvm::ARM::getFPUVersion(unsigned FPUKind) {
163 if (FPUKind >= ARM::FK_LAST)
165 return FPUNames[FPUKind].FPUVersion;
168 unsigned llvm::ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
169 if (FPUKind >= ARM::FK_LAST)
171 return FPUNames[FPUKind].NeonSupport;
174 unsigned llvm::ARM::getFPURestriction(unsigned FPUKind) {
175 if (FPUKind >= ARM::FK_LAST)
177 return FPUNames[FPUKind].Restriction;
180 unsigned llvm::ARM::getDefaultFPU(StringRef CPU, unsigned ArchKind) {
181 if (CPU == "generic")
182 return ARCHNames[ArchKind].DefaultFPU;
184 return StringSwitch<unsigned>(CPU)
185 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
186 .Case(NAME, DEFAULT_FPU)
187 #include "llvm/Support/ARMTargetParser.def"
188 .Default(ARM::FK_INVALID);
191 unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, unsigned ArchKind) {
192 if (CPU == "generic")
193 return ARCHNames[ArchKind].ArchBaseExtensions;
195 return StringSwitch<unsigned>(CPU)
196 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
197 .Case(NAME, ARCHNames[ID].ArchBaseExtensions | DEFAULT_EXT)
198 #include "llvm/Support/ARMTargetParser.def"
199 .Default(ARM::AEK_INVALID);
202 bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
203 std::vector<StringRef> &Features) {
205 if (HWDivKind == ARM::AEK_INVALID)
208 if (HWDivKind & ARM::AEK_HWDIVARM)
209 Features.push_back("+hwdiv-arm");
211 Features.push_back("-hwdiv-arm");
213 if (HWDivKind & ARM::AEK_HWDIVTHUMB)
214 Features.push_back("+hwdiv");
216 Features.push_back("-hwdiv");
221 bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
222 std::vector<StringRef> &Features) {
224 if (Extensions == ARM::AEK_INVALID)
227 if (Extensions & ARM::AEK_CRC)
228 Features.push_back("+crc");
230 Features.push_back("-crc");
232 if (Extensions & ARM::AEK_DSP)
233 Features.push_back("+dsp");
235 Features.push_back("-dsp");
237 return getHWDivFeatures(Extensions, Features);
240 bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
241 std::vector<StringRef> &Features) {
243 if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
246 // fp-only-sp and d16 subtarget features are independent of each other, so we
247 // must enable/disable both.
248 switch (FPUNames[FPUKind].Restriction) {
250 Features.push_back("+fp-only-sp");
251 Features.push_back("+d16");
254 Features.push_back("-fp-only-sp");
255 Features.push_back("+d16");
258 Features.push_back("-fp-only-sp");
259 Features.push_back("-d16");
263 // FPU version subtarget features are inclusive of lower-numbered ones, so
264 // enable the one corresponding to this version and disable all that are
265 // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
266 // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
267 switch (FPUNames[FPUKind].FPUVersion) {
269 Features.push_back("+fp-armv8");
272 Features.push_back("+vfp4");
273 Features.push_back("-fp-armv8");
275 case ARM::FV_VFPV3_FP16:
276 Features.push_back("+vfp3");
277 Features.push_back("+fp16");
278 Features.push_back("-vfp4");
279 Features.push_back("-fp-armv8");
282 Features.push_back("+vfp3");
283 Features.push_back("-fp16");
284 Features.push_back("-vfp4");
285 Features.push_back("-fp-armv8");
288 Features.push_back("+vfp2");
289 Features.push_back("-vfp3");
290 Features.push_back("-fp16");
291 Features.push_back("-vfp4");
292 Features.push_back("-fp-armv8");
295 Features.push_back("-vfp2");
296 Features.push_back("-vfp3");
297 Features.push_back("-fp16");
298 Features.push_back("-vfp4");
299 Features.push_back("-fp-armv8");
303 // crypto includes neon, so we handle this similarly to FPU version.
304 switch (FPUNames[FPUKind].NeonSupport) {
306 Features.push_back("+neon");
307 Features.push_back("+crypto");
310 Features.push_back("+neon");
311 Features.push_back("-crypto");
314 Features.push_back("-neon");
315 Features.push_back("-crypto");
322 StringRef llvm::ARM::getArchName(unsigned ArchKind) {
323 if (ArchKind >= ARM::AK_LAST)
325 return ARCHNames[ArchKind].getName();
328 StringRef llvm::ARM::getCPUAttr(unsigned ArchKind) {
329 if (ArchKind == ARM::AK_INVALID || ArchKind >= ARM::AK_LAST)
331 return ARCHNames[ArchKind].getCPUAttr();
334 StringRef llvm::ARM::getSubArch(unsigned ArchKind) {
335 if (ArchKind == ARM::AK_INVALID || ArchKind >= ARM::AK_LAST)
337 return ARCHNames[ArchKind].getSubArch();
340 unsigned llvm::ARM::getArchAttr(unsigned ArchKind) {
341 if (ArchKind >= ARM::AK_LAST)
342 return ARMBuildAttrs::CPUArch::Pre_v4;
343 return ARCHNames[ArchKind].ArchAttr;
346 StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
347 for (const auto AE : ARCHExtNames) {
348 if (ArchExtKind == AE.ID)
354 StringRef llvm::ARM::getArchExtFeature(StringRef ArchExt) {
355 if (ArchExt.startswith("no")) {
356 StringRef ArchExtBase(ArchExt.substr(2));
357 for (const auto AE : ARCHExtNames) {
358 if (AE.NegFeature && ArchExtBase == AE.getName())
359 return StringRef(AE.NegFeature);
362 for (const auto AE : ARCHExtNames) {
363 if (AE.Feature && ArchExt == AE.getName())
364 return StringRef(AE.Feature);
370 StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
371 for (const auto D : HWDivNames) {
372 if (HWDivKind == D.ID)
378 StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
379 unsigned AK = parseArch(Arch);
380 if (AK == ARM::AK_INVALID)
383 // Look for multiple AKs to find the default for pair AK+Name.
384 for (const auto CPU : CPUNames) {
385 if (CPU.ArchID == AK && CPU.Default)
386 return CPU.getName();
389 // If we can't find a default then target the architecture instead
393 StringRef llvm::AArch64::getFPUName(unsigned FPUKind) {
394 return ARM::getFPUName(FPUKind);
397 unsigned llvm::AArch64::getFPUVersion(unsigned FPUKind) {
398 return ARM::getFPUVersion(FPUKind);
401 unsigned llvm::AArch64::getFPUNeonSupportLevel(unsigned FPUKind) {
402 return ARM::getFPUNeonSupportLevel( FPUKind);
405 unsigned llvm::AArch64::getFPURestriction(unsigned FPUKind) {
406 return ARM::getFPURestriction(FPUKind);
409 unsigned llvm::AArch64::getDefaultFPU(StringRef CPU, unsigned ArchKind) {
410 if (CPU == "generic")
411 return AArch64ARCHNames[ArchKind].DefaultFPU;
413 return StringSwitch<unsigned>(CPU)
414 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
415 .Case(NAME, DEFAULT_FPU)
416 #include "llvm/Support/AArch64TargetParser.def"
417 .Default(ARM::FK_INVALID);
420 unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, unsigned ArchKind) {
421 if (CPU == "generic")
422 return AArch64ARCHNames[ArchKind].ArchBaseExtensions;
424 return StringSwitch<unsigned>(CPU)
425 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
427 AArch64ARCHNames[(unsigned)AArch64::ArchKind::ID].ArchBaseExtensions | \
429 #include "llvm/Support/AArch64TargetParser.def"
430 .Default(AArch64::AEK_INVALID);
433 bool llvm::AArch64::getExtensionFeatures(unsigned Extensions,
434 std::vector<StringRef> &Features) {
436 if (Extensions == AArch64::AEK_INVALID)
439 if (Extensions & AArch64::AEK_FP)
440 Features.push_back("+fp-armv8");
441 if (Extensions & AArch64::AEK_SIMD)
442 Features.push_back("+neon");
443 if (Extensions & AArch64::AEK_CRC)
444 Features.push_back("+crc");
445 if (Extensions & AArch64::AEK_CRYPTO)
446 Features.push_back("+crypto");
447 if (Extensions & AArch64::AEK_FP16)
448 Features.push_back("+fullfp16");
449 if (Extensions & AArch64::AEK_PROFILE)
450 Features.push_back("+spe");
451 if (Extensions & AArch64::AEK_RAS)
452 Features.push_back("+ras");
453 if (Extensions & AArch64::AEK_LSE)
454 Features.push_back("+lse");
459 bool llvm::AArch64::getFPUFeatures(unsigned FPUKind,
460 std::vector<StringRef> &Features) {
461 return ARM::getFPUFeatures(FPUKind, Features);
464 bool llvm::AArch64::getArchFeatures(unsigned ArchKind,
465 std::vector<StringRef> &Features) {
466 if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_ARMV8_1A))
467 Features.push_back("+v8.1a");
468 if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_ARMV8_2A))
469 Features.push_back("+v8.2a");
471 return ArchKind > static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) &&
472 ArchKind < static_cast<unsigned>(AArch64::ArchKind::AK_LAST);
475 StringRef llvm::AArch64::getArchName(unsigned ArchKind) {
476 if (ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
478 return AArch64ARCHNames[ArchKind].getName();
481 StringRef llvm::AArch64::getCPUAttr(unsigned ArchKind) {
482 if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
483 ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
485 return AArch64ARCHNames[ArchKind].getCPUAttr();
488 StringRef llvm::AArch64::getSubArch(unsigned ArchKind) {
489 if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
490 ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
492 return AArch64ARCHNames[ArchKind].getSubArch();
495 unsigned llvm::AArch64::getArchAttr(unsigned ArchKind) {
496 if (ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
497 return ARMBuildAttrs::CPUArch::v8_A;
498 return AArch64ARCHNames[ArchKind].ArchAttr;
501 StringRef llvm::AArch64::getArchExtName(unsigned ArchExtKind) {
502 for (const auto &AE : AArch64ARCHExtNames)
503 if (ArchExtKind == AE.ID)
508 StringRef llvm::AArch64::getArchExtFeature(StringRef ArchExt) {
509 if (ArchExt.startswith("no")) {
510 StringRef ArchExtBase(ArchExt.substr(2));
511 for (const auto &AE : AArch64ARCHExtNames) {
512 if (AE.NegFeature && ArchExtBase == AE.getName())
513 return StringRef(AE.NegFeature);
517 for (const auto &AE : AArch64ARCHExtNames)
518 if (AE.Feature && ArchExt == AE.getName())
519 return StringRef(AE.Feature);
523 StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) {
524 unsigned AK = parseArch(Arch);
525 if (AK == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID))
528 // Look for multiple AKs to find the default for pair AK+Name.
529 for (const auto &CPU : AArch64CPUNames)
530 if (static_cast<unsigned>(CPU.ArchID) == AK && CPU.Default)
531 return CPU.getName();
533 // If we can't find a default then target the architecture instead
537 unsigned llvm::AArch64::checkArchVersion(StringRef Arch) {
538 if (Arch[0] == 'v' && std::isdigit(Arch[1]))
539 return (Arch[1] - 48);
543 // ======================================================= //
545 // ======================================================= //
547 static StringRef getHWDivSynonym(StringRef HWDiv) {
548 return StringSwitch<StringRef>(HWDiv)
549 .Case("thumb,arm", "arm,thumb")
553 static StringRef getFPUSynonym(StringRef FPU) {
554 return StringSwitch<StringRef>(FPU)
555 .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
556 .Case("vfp2", "vfpv2")
557 .Case("vfp3", "vfpv3")
558 .Case("vfp4", "vfpv4")
559 .Case("vfp3-d16", "vfpv3-d16")
560 .Case("vfp4-d16", "vfpv4-d16")
561 .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
562 .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
563 .Case("fp5-sp-d16", "fpv5-sp-d16")
564 .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
565 // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
566 .Case("neon-vfpv3", "neon")
570 static StringRef getArchSynonym(StringRef Arch) {
571 return StringSwitch<StringRef>(Arch)
576 .Cases("v6m", "v6sm", "v6s-m", "v6-m")
577 .Cases("v6z", "v6zk", "v6kz")
578 .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
581 .Case("v7em", "v7e-m")
582 .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
583 .Case("v8.1a", "v8.1-a")
584 .Case("v8.2a", "v8.2-a")
586 .Case("v8m.base", "v8-m.base")
587 .Case("v8m.main", "v8-m.main")
591 // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
592 // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
593 // "v.+", if the latter, return unmodified string, minus 'eb'.
594 // If invalid, return empty string.
595 StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
596 size_t offset = StringRef::npos;
598 StringRef Error = "";
600 // Begins with "arm" / "thumb", move past it.
601 if (A.startswith("arm64"))
603 else if (A.startswith("arm"))
605 else if (A.startswith("thumb"))
607 else if (A.startswith("aarch64")) {
609 // AArch64 uses "_be", not "eb" suffix.
610 if (A.find("eb") != StringRef::npos)
612 if (A.substr(offset, 3) == "_be")
616 // Ex. "armebv7", move past the "eb".
617 if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
619 // Or, if it ends with eb ("armv7eb"), chop it off.
620 else if (A.endswith("eb"))
621 A = A.substr(0, A.size() - 2);
623 if (offset != StringRef::npos)
624 A = A.substr(offset);
626 // Empty string means offset reached the end, which means it's valid.
630 // Only match non-marketing names
631 if (offset != StringRef::npos) {
632 // Must start with 'vN'.
633 if (A[0] != 'v' || !std::isdigit(A[1]))
635 // Can't have an extra 'eb'.
636 if (A.find("eb") != StringRef::npos)
640 // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
644 unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
645 StringRef Syn = getHWDivSynonym(HWDiv);
646 for (const auto D : HWDivNames) {
647 if (Syn == D.getName())
650 return ARM::AEK_INVALID;
653 unsigned llvm::ARM::parseFPU(StringRef FPU) {
654 StringRef Syn = getFPUSynonym(FPU);
655 for (const auto F : FPUNames) {
656 if (Syn == F.getName())
659 return ARM::FK_INVALID;
662 // Allows partial match, ex. "v7a" matches "armv7a".
663 unsigned llvm::ARM::parseArch(StringRef Arch) {
664 Arch = getCanonicalArchName(Arch);
665 StringRef Syn = getArchSynonym(Arch);
666 for (const auto A : ARCHNames) {
667 if (A.getName().endswith(Syn))
670 return ARM::AK_INVALID;
673 unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
674 for (const auto A : ARCHExtNames) {
675 if (ArchExt == A.getName())
678 return ARM::AEK_INVALID;
681 unsigned llvm::ARM::parseCPUArch(StringRef CPU) {
682 for (const auto C : CPUNames) {
683 if (CPU == C.getName())
686 return ARM::AK_INVALID;
689 // ARM, Thumb, AArch64
690 unsigned llvm::ARM::parseArchISA(StringRef Arch) {
691 return StringSwitch<unsigned>(Arch)
692 .StartsWith("aarch64", ARM::IK_AARCH64)
693 .StartsWith("arm64", ARM::IK_AARCH64)
694 .StartsWith("thumb", ARM::IK_THUMB)
695 .StartsWith("arm", ARM::IK_ARM)
696 .Default(ARM::IK_INVALID);
700 unsigned llvm::ARM::parseArchEndian(StringRef Arch) {
701 if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
702 Arch.startswith("aarch64_be"))
705 if (Arch.startswith("arm") || Arch.startswith("thumb")) {
706 if (Arch.endswith("eb"))
709 return ARM::EK_LITTLE;
712 if (Arch.startswith("aarch64"))
713 return ARM::EK_LITTLE;
715 return ARM::EK_INVALID;
719 unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
720 Arch = getCanonicalArchName(Arch);
721 switch (parseArch(Arch)) {
724 case ARM::AK_ARMV7EM:
725 case ARM::AK_ARMV8MMainline:
726 case ARM::AK_ARMV8MBaseline:
732 case ARM::AK_ARMV7VE:
735 case ARM::AK_ARMV8_1A:
736 case ARM::AK_ARMV8_2A:
739 return ARM::PK_INVALID;
742 // Version number (ex. v7 = 7).
743 unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
744 Arch = getCanonicalArchName(Arch);
745 switch (parseArch(Arch)) {
756 case ARM::AK_ARMV5TE:
758 case ARM::AK_IWMMXT2:
760 case ARM::AK_ARMV5TEJ:
764 case ARM::AK_ARMV6T2:
765 case ARM::AK_ARMV6KZ:
769 case ARM::AK_ARMV7VE:
773 case ARM::AK_ARMV7EM:
777 case ARM::AK_ARMV8_1A:
778 case ARM::AK_ARMV8_2A:
780 case ARM::AK_ARMV8MBaseline:
781 case ARM::AK_ARMV8MMainline:
787 StringRef llvm::AArch64::getCanonicalArchName(StringRef Arch) {
788 return ARM::getCanonicalArchName(Arch);
791 unsigned llvm::AArch64::parseFPU(StringRef FPU) {
792 return ARM::parseFPU(FPU);
795 // Allows partial match, ex. "v8a" matches "armv8a".
796 unsigned llvm::AArch64::parseArch(StringRef Arch) {
797 Arch = getCanonicalArchName(Arch);
798 if (checkArchVersion(Arch) < 8)
799 return static_cast<unsigned>(AArch64::ArchKind::AK_INVALID);
801 StringRef Syn = getArchSynonym(Arch);
802 for (const auto A : AArch64ARCHNames) {
803 if (A.getName().endswith(Syn))
804 return static_cast<unsigned>(A.ID);
806 return static_cast<unsigned>(AArch64::ArchKind::AK_INVALID);
809 unsigned llvm::AArch64::parseArchExt(StringRef ArchExt) {
810 for (const auto A : AArch64ARCHExtNames) {
811 if (ArchExt == A.getName())
814 return AArch64::AEK_INVALID;
817 unsigned llvm::AArch64::parseCPUArch(StringRef CPU) {
818 for (const auto C : AArch64CPUNames) {
819 if (CPU == C.getName())
820 return static_cast<unsigned>(C.ArchID);
822 return static_cast<unsigned>(AArch64::ArchKind::AK_INVALID);
825 // ARM, Thumb, AArch64
826 unsigned llvm::AArch64::parseArchISA(StringRef Arch) {
827 return ARM::parseArchISA(Arch);
831 unsigned llvm::AArch64::parseArchEndian(StringRef Arch) {
832 return ARM::parseArchEndian(Arch);
836 unsigned llvm::AArch64::parseArchProfile(StringRef Arch) {
837 return ARM::parseArchProfile(Arch);
840 // Version number (ex. v8 = 8).
841 unsigned llvm::AArch64::parseArchVersion(StringRef Arch) {
842 return ARM::parseArchVersion(Arch);