]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Support/TargetParser.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r308421, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Support / TargetParser.cpp
1 //===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements a target parser to recognise hardware features such as
11 // FPU/CPU/ARCH names as well as specific support such as HDIV, etc.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/Support/ARMBuildAttributes.h"
16 #include "llvm/Support/TargetParser.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/ADT/Twine.h"
20 #include <cctype>
21
22 using namespace llvm;
23 using namespace ARM;
24 using namespace AArch64;
25
26 namespace {
27
28 // List of canonical FPU names (use getFPUSynonym) and which architectural
29 // features they correspond to (use getFPUFeatures).
30 // FIXME: TableGen this.
31 // The entries must appear in the order listed in ARM::FPUKind for correct indexing
32 static const struct {
33   const char *NameCStr;
34   size_t NameLength;
35   ARM::FPUKind ID;
36   ARM::FPUVersion FPUVersion;
37   ARM::NeonSupportLevel NeonSupport;
38   ARM::FPURestriction Restriction;
39
40   StringRef getName() const { return StringRef(NameCStr, NameLength); }
41 } FPUNames[] = {
42 #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
43   { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION },
44 #include "llvm/Support/ARMTargetParser.def"
45 };
46
47 // List of canonical arch names (use getArchSynonym).
48 // This table also provides the build attribute fields for CPU arch
49 // and Arch ID, according to the Addenda to the ARM ABI, chapters
50 // 2.4 and 2.3.5.2 respectively.
51 // FIXME: SubArch values were simplified to fit into the expectations
52 // of the triples and are not conforming with their official names.
53 // Check to see if the expectation should be changed.
54 // FIXME: TableGen this.
55 template <typename T> struct ArchNames {
56   const char *NameCStr;
57   size_t NameLength;
58   const char *CPUAttrCStr;
59   size_t CPUAttrLength;
60   const char *SubArchCStr;
61   size_t SubArchLength;
62   unsigned DefaultFPU;
63   unsigned ArchBaseExtensions;
64   T ID;
65   ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
66
67   StringRef getName() const { return StringRef(NameCStr, NameLength); }
68
69   // CPU class in build attributes.
70   StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
71
72   // Sub-Arch name.
73   StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
74 };
75 ArchNames<ARM::ArchKind> ARCHNames[] = {
76 #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT)       \
77   {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH,       \
78    sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ID, ARCH_ATTR},
79 #include "llvm/Support/ARMTargetParser.def"
80 };
81
82 ArchNames<AArch64::ArchKind> AArch64ARCHNames[] = {
83  #define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT)       \
84    {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH,       \
85     sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, AArch64::ArchKind::ID, ARCH_ATTR},
86  #include "llvm/Support/AArch64TargetParser.def"
87  };
88
89
90 // List of Arch Extension names.
91 // FIXME: TableGen this.
92 static const struct {
93   const char *NameCStr;
94   size_t NameLength;
95   unsigned ID;
96   const char *Feature;
97   const char *NegFeature;
98
99   StringRef getName() const { return StringRef(NameCStr, NameLength); }
100 } ARCHExtNames[] = {
101 #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
102   { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
103 #include "llvm/Support/ARMTargetParser.def"
104 },AArch64ARCHExtNames[] = {
105 #define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
106   { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
107 #include "llvm/Support/AArch64TargetParser.def"
108 };
109
110 // List of HWDiv names (use getHWDivSynonym) and which architectural
111 // features they correspond to (use getHWDivFeatures).
112 // FIXME: TableGen this.
113 static const struct {
114   const char *NameCStr;
115   size_t NameLength;
116   unsigned ID;
117
118   StringRef getName() const { return StringRef(NameCStr, NameLength); }
119 } HWDivNames[] = {
120 #define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
121 #include "llvm/Support/ARMTargetParser.def"
122 };
123
124 // List of CPU names and their arches.
125 // The same CPU can have multiple arches and can be default on multiple arches.
126 // When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
127 // When this becomes table-generated, we'd probably need two tables.
128 // FIXME: TableGen this.
129 template <typename T> struct CpuNames {
130   const char *NameCStr;
131   size_t NameLength;
132   T ArchID;
133   bool Default; // is $Name the default CPU for $ArchID ?
134   unsigned DefaultExtensions;
135
136   StringRef getName() const { return StringRef(NameCStr, NameLength); }
137 };
138 CpuNames<ARM::ArchKind> CPUNames[] = {
139 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
140   { NAME, sizeof(NAME) - 1, ID, IS_DEFAULT, DEFAULT_EXT },
141 #include "llvm/Support/ARMTargetParser.def"
142 };
143
144 CpuNames<AArch64::ArchKind> AArch64CPUNames[] = {
145  #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
146    { NAME, sizeof(NAME) - 1, AArch64::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
147  #include "llvm/Support/AArch64TargetParser.def"
148  };
149
150 } // namespace
151
152 // ======================================================= //
153 // Information by ID
154 // ======================================================= //
155
156 StringRef llvm::ARM::getFPUName(unsigned FPUKind) {
157   if (FPUKind >= ARM::FK_LAST)
158     return StringRef();
159   return FPUNames[FPUKind].getName();
160 }
161
162 unsigned llvm::ARM::getFPUVersion(unsigned FPUKind) {
163   if (FPUKind >= ARM::FK_LAST)
164     return 0;
165   return FPUNames[FPUKind].FPUVersion;
166 }
167
168 unsigned llvm::ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
169   if (FPUKind >= ARM::FK_LAST)
170     return 0;
171   return FPUNames[FPUKind].NeonSupport;
172 }
173
174 unsigned llvm::ARM::getFPURestriction(unsigned FPUKind) {
175   if (FPUKind >= ARM::FK_LAST)
176     return 0;
177   return FPUNames[FPUKind].Restriction;
178 }
179
180 unsigned llvm::ARM::getDefaultFPU(StringRef CPU, unsigned ArchKind) {
181   if (CPU == "generic")
182     return ARCHNames[ArchKind].DefaultFPU;
183
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);
189 }
190
191 unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, unsigned ArchKind) {
192   if (CPU == "generic")
193     return ARCHNames[ArchKind].ArchBaseExtensions;
194
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);
200 }
201
202 bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
203                                  std::vector<StringRef> &Features) {
204
205   if (HWDivKind == ARM::AEK_INVALID)
206     return false;
207
208   if (HWDivKind & ARM::AEK_HWDIVARM)
209     Features.push_back("+hwdiv-arm");
210   else
211     Features.push_back("-hwdiv-arm");
212
213   if (HWDivKind & ARM::AEK_HWDIVTHUMB)
214     Features.push_back("+hwdiv");
215   else
216     Features.push_back("-hwdiv");
217
218   return true;
219 }
220
221 bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
222                                      std::vector<StringRef> &Features) {
223
224   if (Extensions == ARM::AEK_INVALID)
225     return false;
226
227   if (Extensions & ARM::AEK_CRC)
228     Features.push_back("+crc");
229   else
230     Features.push_back("-crc");
231
232   if (Extensions & ARM::AEK_DSP)
233     Features.push_back("+dsp");
234   else
235     Features.push_back("-dsp");
236
237   return getHWDivFeatures(Extensions, Features);
238 }
239
240 bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
241                                std::vector<StringRef> &Features) {
242
243   if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
244     return false;
245
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) {
249   case ARM::FR_SP_D16:
250     Features.push_back("+fp-only-sp");
251     Features.push_back("+d16");
252     break;
253   case ARM::FR_D16:
254     Features.push_back("-fp-only-sp");
255     Features.push_back("+d16");
256     break;
257   case ARM::FR_None:
258     Features.push_back("-fp-only-sp");
259     Features.push_back("-d16");
260     break;
261   }
262
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) {
268   case ARM::FV_VFPV5:
269     Features.push_back("+fp-armv8");
270     break;
271   case ARM::FV_VFPV4:
272     Features.push_back("+vfp4");
273     Features.push_back("-fp-armv8");
274     break;
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");
280     break;
281   case ARM::FV_VFPV3:
282     Features.push_back("+vfp3");
283     Features.push_back("-fp16");
284     Features.push_back("-vfp4");
285     Features.push_back("-fp-armv8");
286     break;
287   case ARM::FV_VFPV2:
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");
293     break;
294   case ARM::FV_NONE:
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");
300     break;
301   }
302
303   // crypto includes neon, so we handle this similarly to FPU version.
304   switch (FPUNames[FPUKind].NeonSupport) {
305   case ARM::NS_Crypto:
306     Features.push_back("+neon");
307     Features.push_back("+crypto");
308     break;
309   case ARM::NS_Neon:
310     Features.push_back("+neon");
311     Features.push_back("-crypto");
312     break;
313   case ARM::NS_None:
314     Features.push_back("-neon");
315     Features.push_back("-crypto");
316     break;
317   }
318
319   return true;
320 }
321
322 StringRef llvm::ARM::getArchName(unsigned ArchKind) {
323   if (ArchKind >= ARM::AK_LAST)
324     return StringRef();
325   return ARCHNames[ArchKind].getName();
326 }
327
328 StringRef llvm::ARM::getCPUAttr(unsigned ArchKind) {
329   if (ArchKind == ARM::AK_INVALID || ArchKind >= ARM::AK_LAST)
330     return StringRef();
331   return ARCHNames[ArchKind].getCPUAttr();
332 }
333
334 StringRef llvm::ARM::getSubArch(unsigned ArchKind) {
335   if (ArchKind == ARM::AK_INVALID || ArchKind >= ARM::AK_LAST)
336     return StringRef();
337   return ARCHNames[ArchKind].getSubArch();
338 }
339
340 unsigned llvm::ARM::getArchAttr(unsigned ArchKind) {
341   if (ArchKind >= ARM::AK_LAST)
342     return ARMBuildAttrs::CPUArch::Pre_v4;
343   return ARCHNames[ArchKind].ArchAttr;
344 }
345
346 StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
347   for (const auto AE : ARCHExtNames) {
348     if (ArchExtKind == AE.ID)
349       return AE.getName();
350   }
351   return StringRef();
352 }
353
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);
360     }
361   }
362   for (const auto AE : ARCHExtNames) {
363     if (AE.Feature && ArchExt == AE.getName())
364       return StringRef(AE.Feature);
365   }
366
367   return StringRef();
368 }
369
370 StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
371   for (const auto D : HWDivNames) {
372     if (HWDivKind == D.ID)
373       return D.getName();
374   }
375   return StringRef();
376 }
377
378 StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
379   unsigned AK = parseArch(Arch);
380   if (AK == ARM::AK_INVALID)
381     return StringRef();
382
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();
387   }
388
389   // If we can't find a default then target the architecture instead
390   return "generic";
391 }
392
393 StringRef llvm::AArch64::getFPUName(unsigned FPUKind) {
394   return ARM::getFPUName(FPUKind);
395 }
396
397 unsigned llvm::AArch64::getFPUVersion(unsigned FPUKind) {
398   return ARM::getFPUVersion(FPUKind);
399 }
400
401 unsigned llvm::AArch64::getFPUNeonSupportLevel(unsigned FPUKind) {
402   return ARM::getFPUNeonSupportLevel( FPUKind);
403 }
404
405 unsigned llvm::AArch64::getFPURestriction(unsigned FPUKind) {
406   return ARM::getFPURestriction(FPUKind);
407 }
408
409 unsigned llvm::AArch64::getDefaultFPU(StringRef CPU, unsigned ArchKind) {
410   if (CPU == "generic")
411     return AArch64ARCHNames[ArchKind].DefaultFPU;
412
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);
418 }
419
420 unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, unsigned ArchKind) {
421   if (CPU == "generic")
422     return AArch64ARCHNames[ArchKind].ArchBaseExtensions;
423
424   return StringSwitch<unsigned>(CPU)
425 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)       \
426   .Case(NAME,                                                                  \
427         AArch64ARCHNames[(unsigned)AArch64::ArchKind::ID].ArchBaseExtensions | \
428             DEFAULT_EXT)
429 #include "llvm/Support/AArch64TargetParser.def"
430     .Default(AArch64::AEK_INVALID);
431 }
432
433 bool llvm::AArch64::getExtensionFeatures(unsigned Extensions,
434                                      std::vector<StringRef> &Features) {
435
436   if (Extensions == AArch64::AEK_INVALID)
437     return false;
438
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");
455   if (Extensions & AArch64::AEK_SVE)
456     Features.push_back("+sve");
457
458   return true;
459 }
460
461 bool llvm::AArch64::getFPUFeatures(unsigned FPUKind,
462                                std::vector<StringRef> &Features) {
463   return ARM::getFPUFeatures(FPUKind, Features);
464 }
465
466 bool llvm::AArch64::getArchFeatures(unsigned ArchKind,
467                                      std::vector<StringRef> &Features) {
468   if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_ARMV8_1A))
469     Features.push_back("+v8.1a");
470   if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_ARMV8_2A))
471     Features.push_back("+v8.2a");
472
473   return ArchKind > static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) &&
474          ArchKind < static_cast<unsigned>(AArch64::ArchKind::AK_LAST);
475 }
476
477 StringRef llvm::AArch64::getArchName(unsigned ArchKind) {
478   if (ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
479     return StringRef();
480   return AArch64ARCHNames[ArchKind].getName();
481 }
482
483 StringRef llvm::AArch64::getCPUAttr(unsigned ArchKind) {
484   if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
485       ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
486     return StringRef();
487   return AArch64ARCHNames[ArchKind].getCPUAttr();
488 }
489
490 StringRef llvm::AArch64::getSubArch(unsigned ArchKind) {
491   if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
492       ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
493     return StringRef();
494   return AArch64ARCHNames[ArchKind].getSubArch();
495 }
496
497 unsigned llvm::AArch64::getArchAttr(unsigned ArchKind) {
498   if (ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
499     return ARMBuildAttrs::CPUArch::v8_A;
500   return AArch64ARCHNames[ArchKind].ArchAttr;
501 }
502
503 StringRef llvm::AArch64::getArchExtName(unsigned ArchExtKind) {
504   for (const auto &AE : AArch64ARCHExtNames)
505     if (ArchExtKind == AE.ID)
506       return AE.getName();
507   return StringRef();
508 }
509
510 StringRef llvm::AArch64::getArchExtFeature(StringRef ArchExt) {
511   if (ArchExt.startswith("no")) {
512     StringRef ArchExtBase(ArchExt.substr(2));
513     for (const auto &AE : AArch64ARCHExtNames) {
514       if (AE.NegFeature && ArchExtBase == AE.getName())
515         return StringRef(AE.NegFeature);
516     }
517   }
518
519   for (const auto &AE : AArch64ARCHExtNames)
520     if (AE.Feature && ArchExt == AE.getName())
521       return StringRef(AE.Feature);
522   return StringRef();
523 }
524
525 StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) {
526   unsigned AK = parseArch(Arch);
527   if (AK == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID))
528     return StringRef();
529
530   // Look for multiple AKs to find the default for pair AK+Name.
531   for (const auto &CPU : AArch64CPUNames)
532     if (static_cast<unsigned>(CPU.ArchID) == AK && CPU.Default)
533       return CPU.getName();
534
535   // If we can't find a default then target the architecture instead
536   return "generic";
537 }
538
539 unsigned llvm::AArch64::checkArchVersion(StringRef Arch) {
540   if (Arch[0] == 'v' && std::isdigit(Arch[1]))
541     return (Arch[1] - 48);
542   return 0;
543 }
544
545 // ======================================================= //
546 // Parsers
547 // ======================================================= //
548
549 static StringRef getHWDivSynonym(StringRef HWDiv) {
550   return StringSwitch<StringRef>(HWDiv)
551       .Case("thumb,arm", "arm,thumb")
552       .Default(HWDiv);
553 }
554
555 static StringRef getFPUSynonym(StringRef FPU) {
556   return StringSwitch<StringRef>(FPU)
557       .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
558       .Case("vfp2", "vfpv2")
559       .Case("vfp3", "vfpv3")
560       .Case("vfp4", "vfpv4")
561       .Case("vfp3-d16", "vfpv3-d16")
562       .Case("vfp4-d16", "vfpv4-d16")
563       .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
564       .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
565       .Case("fp5-sp-d16", "fpv5-sp-d16")
566       .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
567       // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
568       .Case("neon-vfpv3", "neon")
569       .Default(FPU);
570 }
571
572 static StringRef getArchSynonym(StringRef Arch) {
573   return StringSwitch<StringRef>(Arch)
574       .Case("v5", "v5t")
575       .Case("v5e", "v5te")
576       .Case("v6j", "v6")
577       .Case("v6hl", "v6k")
578       .Cases("v6m", "v6sm", "v6s-m", "v6-m")
579       .Cases("v6z", "v6zk", "v6kz")
580       .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
581       .Case("v7r", "v7-r")
582       .Case("v7m", "v7-m")
583       .Case("v7em", "v7e-m")
584       .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
585       .Case("v8.1a", "v8.1-a")
586       .Case("v8.2a", "v8.2-a")
587       .Case("v8r", "v8-r")
588       .Case("v8m.base", "v8-m.base")
589       .Case("v8m.main", "v8-m.main")
590       .Default(Arch);
591 }
592
593 // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
594 // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
595 // "v.+", if the latter, return unmodified string, minus 'eb'.
596 // If invalid, return empty string.
597 StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
598   size_t offset = StringRef::npos;
599   StringRef A = Arch;
600   StringRef Error = "";
601
602   // Begins with "arm" / "thumb", move past it.
603   if (A.startswith("arm64"))
604     offset = 5;
605   else if (A.startswith("arm"))
606     offset = 3;
607   else if (A.startswith("thumb"))
608     offset = 5;
609   else if (A.startswith("aarch64")) {
610     offset = 7;
611     // AArch64 uses "_be", not "eb" suffix.
612     if (A.find("eb") != StringRef::npos)
613       return Error;
614     if (A.substr(offset, 3) == "_be")
615       offset += 3;
616   }
617
618   // Ex. "armebv7", move past the "eb".
619   if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
620     offset += 2;
621   // Or, if it ends with eb ("armv7eb"), chop it off.
622   else if (A.endswith("eb"))
623     A = A.substr(0, A.size() - 2);
624   // Trim the head
625   if (offset != StringRef::npos)
626     A = A.substr(offset);
627
628   // Empty string means offset reached the end, which means it's valid.
629   if (A.empty())
630     return Arch;
631
632   // Only match non-marketing names
633   if (offset != StringRef::npos) {
634     // Must start with 'vN'.
635     if (A[0] != 'v' || !std::isdigit(A[1]))
636       return Error;
637     // Can't have an extra 'eb'.
638     if (A.find("eb") != StringRef::npos)
639       return Error;
640   }
641
642   // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
643   return A;
644 }
645
646 unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
647   StringRef Syn = getHWDivSynonym(HWDiv);
648   for (const auto D : HWDivNames) {
649     if (Syn == D.getName())
650       return D.ID;
651   }
652   return ARM::AEK_INVALID;
653 }
654
655 unsigned llvm::ARM::parseFPU(StringRef FPU) {
656   StringRef Syn = getFPUSynonym(FPU);
657   for (const auto F : FPUNames) {
658     if (Syn == F.getName())
659       return F.ID;
660   }
661   return ARM::FK_INVALID;
662 }
663
664 // Allows partial match, ex. "v7a" matches "armv7a".
665 unsigned llvm::ARM::parseArch(StringRef Arch) {
666   Arch = getCanonicalArchName(Arch);
667   StringRef Syn = getArchSynonym(Arch);
668   for (const auto A : ARCHNames) {
669     if (A.getName().endswith(Syn))
670       return A.ID;
671   }
672   return ARM::AK_INVALID;
673 }
674
675 unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
676   for (const auto A : ARCHExtNames) {
677     if (ArchExt == A.getName())
678       return A.ID;
679   }
680   return ARM::AEK_INVALID;
681 }
682
683 unsigned llvm::ARM::parseCPUArch(StringRef CPU) {
684   for (const auto C : CPUNames) {
685     if (CPU == C.getName())
686       return C.ArchID;
687   }
688   return ARM::AK_INVALID;
689 }
690
691 // ARM, Thumb, AArch64
692 unsigned llvm::ARM::parseArchISA(StringRef Arch) {
693   return StringSwitch<unsigned>(Arch)
694       .StartsWith("aarch64", ARM::IK_AARCH64)
695       .StartsWith("arm64", ARM::IK_AARCH64)
696       .StartsWith("thumb", ARM::IK_THUMB)
697       .StartsWith("arm", ARM::IK_ARM)
698       .Default(ARM::IK_INVALID);
699 }
700
701 // Little/Big endian
702 unsigned llvm::ARM::parseArchEndian(StringRef Arch) {
703   if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
704       Arch.startswith("aarch64_be"))
705     return ARM::EK_BIG;
706
707   if (Arch.startswith("arm") || Arch.startswith("thumb")) {
708     if (Arch.endswith("eb"))
709       return ARM::EK_BIG;
710     else
711       return ARM::EK_LITTLE;
712   }
713
714   if (Arch.startswith("aarch64"))
715     return ARM::EK_LITTLE;
716
717   return ARM::EK_INVALID;
718 }
719
720 // Profile A/R/M
721 unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
722   Arch = getCanonicalArchName(Arch);
723   switch (parseArch(Arch)) {
724   case ARM::AK_ARMV6M:
725   case ARM::AK_ARMV7M:
726   case ARM::AK_ARMV7EM:
727   case ARM::AK_ARMV8MMainline:
728   case ARM::AK_ARMV8MBaseline:
729     return ARM::PK_M;
730   case ARM::AK_ARMV7R:
731   case ARM::AK_ARMV8R:
732     return ARM::PK_R;
733   case ARM::AK_ARMV7A:
734   case ARM::AK_ARMV7VE:
735   case ARM::AK_ARMV7K:
736   case ARM::AK_ARMV8A:
737   case ARM::AK_ARMV8_1A:
738   case ARM::AK_ARMV8_2A:
739     return ARM::PK_A;
740   }
741   return ARM::PK_INVALID;
742 }
743
744 // Version number (ex. v7 = 7).
745 unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
746   Arch = getCanonicalArchName(Arch);
747   switch (parseArch(Arch)) {
748   case ARM::AK_ARMV2:
749   case ARM::AK_ARMV2A:
750     return 2;
751   case ARM::AK_ARMV3:
752   case ARM::AK_ARMV3M:
753     return 3;
754   case ARM::AK_ARMV4:
755   case ARM::AK_ARMV4T:
756     return 4;
757   case ARM::AK_ARMV5T:
758   case ARM::AK_ARMV5TE:
759   case ARM::AK_IWMMXT:
760   case ARM::AK_IWMMXT2:
761   case ARM::AK_XSCALE:
762   case ARM::AK_ARMV5TEJ:
763     return 5;
764   case ARM::AK_ARMV6:
765   case ARM::AK_ARMV6K:
766   case ARM::AK_ARMV6T2:
767   case ARM::AK_ARMV6KZ:
768   case ARM::AK_ARMV6M:
769     return 6;
770   case ARM::AK_ARMV7A:
771   case ARM::AK_ARMV7VE:
772   case ARM::AK_ARMV7R:
773   case ARM::AK_ARMV7M:
774   case ARM::AK_ARMV7S:
775   case ARM::AK_ARMV7EM:
776   case ARM::AK_ARMV7K:
777     return 7;
778   case ARM::AK_ARMV8A:
779   case ARM::AK_ARMV8_1A:
780   case ARM::AK_ARMV8_2A:
781   case ARM::AK_ARMV8R:
782   case ARM::AK_ARMV8MBaseline:
783   case ARM::AK_ARMV8MMainline:
784     return 8;
785   }
786   return 0;
787 }
788
789 StringRef llvm::ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) {
790   StringRef ArchName =
791       CPU.empty() ? TT.getArchName() : ARM::getArchName(ARM::parseCPUArch(CPU));
792
793   if (TT.isOSBinFormatMachO()) {
794     if (TT.getEnvironment() == Triple::EABI ||
795         TT.getOS() == Triple::UnknownOS ||
796         llvm::ARM::parseArchProfile(ArchName) == ARM::PK_M)
797       return "aapcs";
798     if (TT.isWatchABI())
799       return "aapcs16";
800     return "apcs-gnu";
801   } else if (TT.isOSWindows())
802     // FIXME: this is invalid for WindowsCE.
803     return "aapcs";
804
805   // Select the default based on the platform.
806   switch (TT.getEnvironment()) {
807   case Triple::Android:
808   case Triple::GNUEABI:
809   case Triple::GNUEABIHF:
810   case Triple::MuslEABI:
811   case Triple::MuslEABIHF:
812     return "aapcs-linux";
813   case Triple::EABIHF:
814   case Triple::EABI:
815     return "aapcs";
816   default:
817     if (TT.isOSNetBSD())
818       return "apcs-gnu";
819     if (TT.isOSOpenBSD())
820       return "aapcs-linux";
821     return "aapcs";
822   }
823 }
824
825 StringRef llvm::AArch64::getCanonicalArchName(StringRef Arch) {
826   return ARM::getCanonicalArchName(Arch);
827 }
828
829 unsigned llvm::AArch64::parseFPU(StringRef FPU) {
830   return ARM::parseFPU(FPU);
831 }
832
833 // Allows partial match, ex. "v8a" matches "armv8a".
834 unsigned llvm::AArch64::parseArch(StringRef Arch) {
835   Arch = getCanonicalArchName(Arch);
836   if (checkArchVersion(Arch) < 8)
837     return static_cast<unsigned>(AArch64::ArchKind::AK_INVALID);
838
839   StringRef Syn = getArchSynonym(Arch);
840   for (const auto A : AArch64ARCHNames) {
841     if (A.getName().endswith(Syn))
842       return static_cast<unsigned>(A.ID);
843   }
844   return static_cast<unsigned>(AArch64::ArchKind::AK_INVALID);
845 }
846
847 unsigned llvm::AArch64::parseArchExt(StringRef ArchExt) {
848   for (const auto A : AArch64ARCHExtNames) {
849     if (ArchExt == A.getName())
850       return A.ID;
851   }
852   return AArch64::AEK_INVALID;
853 }
854
855 unsigned llvm::AArch64::parseCPUArch(StringRef CPU) {
856   for (const auto C : AArch64CPUNames) {
857     if (CPU == C.getName())
858       return static_cast<unsigned>(C.ArchID);
859   }
860   return static_cast<unsigned>(AArch64::ArchKind::AK_INVALID);
861 }
862
863 // ARM, Thumb, AArch64
864 unsigned llvm::AArch64::parseArchISA(StringRef Arch) {
865   return ARM::parseArchISA(Arch);
866 }
867
868 // Little/Big endian
869 unsigned llvm::AArch64::parseArchEndian(StringRef Arch) {
870   return ARM::parseArchEndian(Arch);
871 }
872
873 // Profile A/R/M
874 unsigned llvm::AArch64::parseArchProfile(StringRef Arch) {
875   return ARM::parseArchProfile(Arch);
876 }
877
878 // Version number (ex. v8 = 8).
879 unsigned llvm::AArch64::parseArchVersion(StringRef Arch) {
880   return ARM::parseArchVersion(Arch);
881 }