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/ArrayRef.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, ARM::ArchKind::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, ARM::ArchKind::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 ARM::getFPUName(unsigned FPUKind) {
157   if (FPUKind >= ARM::FK_LAST)
158     return StringRef();
159   return FPUNames[FPUKind].getName();
160 }
161 
162 FPUVersion ARM::getFPUVersion(unsigned FPUKind) {
163   if (FPUKind >= ARM::FK_LAST)
164     return FPUVersion::NONE;
165   return FPUNames[FPUKind].FPUVersion;
166 }
167 
168 ARM::NeonSupportLevel ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
169   if (FPUKind >= ARM::FK_LAST)
170     return ARM::NeonSupportLevel::None;
171   return FPUNames[FPUKind].NeonSupport;
172 }
173 
174 ARM::FPURestriction ARM::getFPURestriction(unsigned FPUKind) {
175   if (FPUKind >= ARM::FK_LAST)
176     return ARM::FPURestriction::None;
177   return FPUNames[FPUKind].Restriction;
178 }
179 
180 unsigned llvm::ARM::getDefaultFPU(StringRef CPU, ArchKind AK) {
181   if (CPU == "generic")
182     return ARCHNames[static_cast<unsigned>(AK)].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, ArchKind AK) {
192   if (CPU == "generic")
193     return ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
194 
195   return StringSwitch<unsigned>(CPU)
196 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
197     .Case(NAME, ARCHNames[static_cast<unsigned>(ARM::ArchKind::ID)]\
198             .ArchBaseExtensions | DEFAULT_EXT)
199 #include "llvm/Support/ARMTargetParser.def"
200     .Default(ARM::AEK_INVALID);
201 }
202 
203 bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
204                                  std::vector<StringRef> &Features) {
205 
206   if (HWDivKind == ARM::AEK_INVALID)
207     return false;
208 
209   if (HWDivKind & ARM::AEK_HWDIVARM)
210     Features.push_back("+hwdiv-arm");
211   else
212     Features.push_back("-hwdiv-arm");
213 
214   if (HWDivKind & ARM::AEK_HWDIVTHUMB)
215     Features.push_back("+hwdiv");
216   else
217     Features.push_back("-hwdiv");
218 
219   return true;
220 }
221 
222 bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
223                                      std::vector<StringRef> &Features) {
224 
225   if (Extensions == ARM::AEK_INVALID)
226     return false;
227 
228   if (Extensions & ARM::AEK_CRC)
229     Features.push_back("+crc");
230   else
231     Features.push_back("-crc");
232 
233   if (Extensions & ARM::AEK_DSP)
234     Features.push_back("+dsp");
235   else
236     Features.push_back("-dsp");
237 
238   if (Extensions & ARM::AEK_FP16FML)
239     Features.push_back("+fp16fml");
240   else
241     Features.push_back("-fp16fml");
242 
243   if (Extensions & ARM::AEK_RAS)
244     Features.push_back("+ras");
245   else
246     Features.push_back("-ras");
247 
248   if (Extensions & ARM::AEK_DOTPROD)
249     Features.push_back("+dotprod");
250   else
251     Features.push_back("-dotprod");
252 
253   return getHWDivFeatures(Extensions, Features);
254 }
255 
256 bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
257                                std::vector<StringRef> &Features) {
258 
259   if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
260     return false;
261 
262   // fp-only-sp and d16 subtarget features are independent of each other, so we
263   // must enable/disable both.
264   switch (FPUNames[FPUKind].Restriction) {
265   case ARM::FPURestriction::SP_D16:
266     Features.push_back("+fp-only-sp");
267     Features.push_back("+d16");
268     break;
269   case ARM::FPURestriction::D16:
270     Features.push_back("-fp-only-sp");
271     Features.push_back("+d16");
272     break;
273   case ARM::FPURestriction::None:
274     Features.push_back("-fp-only-sp");
275     Features.push_back("-d16");
276     break;
277   }
278 
279   // FPU version subtarget features are inclusive of lower-numbered ones, so
280   // enable the one corresponding to this version and disable all that are
281   // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
282   // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
283   switch (FPUNames[FPUKind].FPUVersion) {
284   case ARM::FPUVersion::VFPV5:
285     Features.push_back("+fp-armv8");
286     break;
287   case ARM::FPUVersion::VFPV4:
288     Features.push_back("+vfp4");
289     Features.push_back("-fp-armv8");
290     break;
291   case ARM::FPUVersion::VFPV3_FP16:
292     Features.push_back("+vfp3");
293     Features.push_back("+fp16");
294     Features.push_back("-vfp4");
295     Features.push_back("-fp-armv8");
296     break;
297   case ARM::FPUVersion::VFPV3:
298     Features.push_back("+vfp3");
299     Features.push_back("-fp16");
300     Features.push_back("-vfp4");
301     Features.push_back("-fp-armv8");
302     break;
303   case ARM::FPUVersion::VFPV2:
304     Features.push_back("+vfp2");
305     Features.push_back("-vfp3");
306     Features.push_back("-fp16");
307     Features.push_back("-vfp4");
308     Features.push_back("-fp-armv8");
309     break;
310   case ARM::FPUVersion::NONE:
311     Features.push_back("-vfp2");
312     Features.push_back("-vfp3");
313     Features.push_back("-fp16");
314     Features.push_back("-vfp4");
315     Features.push_back("-fp-armv8");
316     break;
317   }
318 
319   // crypto includes neon, so we handle this similarly to FPU version.
320   switch (FPUNames[FPUKind].NeonSupport) {
321   case ARM::NeonSupportLevel::Crypto:
322     Features.push_back("+neon");
323     Features.push_back("+crypto");
324     break;
325   case ARM::NeonSupportLevel::Neon:
326     Features.push_back("+neon");
327     Features.push_back("-crypto");
328     break;
329   case ARM::NeonSupportLevel::None:
330     Features.push_back("-neon");
331     Features.push_back("-crypto");
332     break;
333   }
334 
335   return true;
336 }
337 
338 StringRef llvm::ARM::getArchName(ArchKind AK) {
339   return ARCHNames[static_cast<unsigned>(AK)].getName();
340 }
341 
342 StringRef llvm::ARM::getCPUAttr(ArchKind AK) {
343   return ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
344 }
345 
346 StringRef llvm::ARM::getSubArch(ArchKind AK) {
347   return ARCHNames[static_cast<unsigned>(AK)].getSubArch();
348 }
349 
350 unsigned llvm::ARM::getArchAttr(ArchKind AK) {
351   return ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
352 }
353 
354 StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
355   for (const auto AE : ARCHExtNames) {
356     if (ArchExtKind == AE.ID)
357       return AE.getName();
358   }
359   return StringRef();
360 }
361 
362 StringRef llvm::ARM::getArchExtFeature(StringRef ArchExt) {
363   if (ArchExt.startswith("no")) {
364     StringRef ArchExtBase(ArchExt.substr(2));
365     for (const auto AE : ARCHExtNames) {
366       if (AE.NegFeature && ArchExtBase == AE.getName())
367         return StringRef(AE.NegFeature);
368     }
369   }
370   for (const auto AE : ARCHExtNames) {
371     if (AE.Feature && ArchExt == AE.getName())
372       return StringRef(AE.Feature);
373   }
374 
375   return StringRef();
376 }
377 
378 StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
379   for (const auto D : HWDivNames) {
380     if (HWDivKind == D.ID)
381       return D.getName();
382   }
383   return StringRef();
384 }
385 
386 StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
387   ArchKind AK = parseArch(Arch);
388   if (AK == ARM::ArchKind::INVALID)
389     return StringRef();
390 
391   // Look for multiple AKs to find the default for pair AK+Name.
392   for (const auto CPU : CPUNames) {
393     if (CPU.ArchID == AK && CPU.Default)
394       return CPU.getName();
395   }
396 
397   // If we can't find a default then target the architecture instead
398   return "generic";
399 }
400 
401 StringRef llvm::AArch64::getFPUName(unsigned FPUKind) {
402   return ARM::getFPUName(FPUKind);
403 }
404 
405 ARM::FPUVersion AArch64::getFPUVersion(unsigned FPUKind) {
406   return ARM::getFPUVersion(FPUKind);
407 }
408 
409 ARM::NeonSupportLevel AArch64::getFPUNeonSupportLevel(unsigned FPUKind) {
410   return ARM::getFPUNeonSupportLevel( FPUKind);
411 }
412 
413 ARM::FPURestriction AArch64::getFPURestriction(unsigned FPUKind) {
414   return ARM::getFPURestriction(FPUKind);
415 }
416 
417 unsigned llvm::AArch64::getDefaultFPU(StringRef CPU, ArchKind AK) {
418   if (CPU == "generic")
419     return AArch64ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
420 
421   return StringSwitch<unsigned>(CPU)
422 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
423     .Case(NAME, DEFAULT_FPU)
424 #include "llvm/Support/AArch64TargetParser.def"
425     .Default(ARM::FK_INVALID);
426 }
427 
428 unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, ArchKind AK) {
429   if (CPU == "generic")
430     return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
431 
432   return StringSwitch<unsigned>(CPU)
433 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)       \
434   .Case(NAME,                                                                  \
435         AArch64ARCHNames[static_cast<unsigned>(AArch64::ArchKind::ID)] \
436             .ArchBaseExtensions | \
437             DEFAULT_EXT)
438 #include "llvm/Support/AArch64TargetParser.def"
439     .Default(AArch64::AEK_INVALID);
440 }
441 
442 AArch64::ArchKind llvm::AArch64::getCPUArchKind(StringRef CPU) {
443   if (CPU == "generic")
444     return AArch64::ArchKind::ARMV8A;
445 
446   return StringSwitch<AArch64::ArchKind>(CPU)
447 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
448   .Case(NAME, AArch64::ArchKind:: ID)
449 #include "llvm/Support/AArch64TargetParser.def"
450     .Default(AArch64::ArchKind::INVALID);
451 }
452 
453 bool llvm::AArch64::getExtensionFeatures(unsigned Extensions,
454                                      std::vector<StringRef> &Features) {
455 
456   if (Extensions == AArch64::AEK_INVALID)
457     return false;
458 
459   if (Extensions & AArch64::AEK_FP)
460     Features.push_back("+fp-armv8");
461   if (Extensions & AArch64::AEK_SIMD)
462     Features.push_back("+neon");
463   if (Extensions & AArch64::AEK_CRC)
464     Features.push_back("+crc");
465   if (Extensions & AArch64::AEK_CRYPTO)
466     Features.push_back("+crypto");
467   if (Extensions & AArch64::AEK_DOTPROD)
468     Features.push_back("+dotprod");
469   if (Extensions & AArch64::AEK_FP16FML)
470     Features.push_back("+fp16fml");
471   if (Extensions & AArch64::AEK_FP16)
472     Features.push_back("+fullfp16");
473   if (Extensions & AArch64::AEK_PROFILE)
474     Features.push_back("+spe");
475   if (Extensions & AArch64::AEK_RAS)
476     Features.push_back("+ras");
477   if (Extensions & AArch64::AEK_LSE)
478     Features.push_back("+lse");
479   if (Extensions & AArch64::AEK_RDM)
480     Features.push_back("+rdm");
481   if (Extensions & AArch64::AEK_SVE)
482     Features.push_back("+sve");
483   if (Extensions & AArch64::AEK_RCPC)
484     Features.push_back("+rcpc");
485 
486   return true;
487 }
488 
489 bool llvm::AArch64::getFPUFeatures(unsigned FPUKind,
490                                std::vector<StringRef> &Features) {
491   return ARM::getFPUFeatures(FPUKind, Features);
492 }
493 
494 bool llvm::AArch64::getArchFeatures(AArch64::ArchKind AK,
495                                     std::vector<StringRef> &Features) {
496   if (AK == AArch64::ArchKind::ARMV8_1A)
497     Features.push_back("+v8.1a");
498   if (AK == AArch64::ArchKind::ARMV8_2A)
499     Features.push_back("+v8.2a");
500   if (AK == AArch64::ArchKind::ARMV8_3A)
501     Features.push_back("+v8.3a");
502   if (AK == AArch64::ArchKind::ARMV8_4A)
503     Features.push_back("+v8.4a");
504 
505   return AK != AArch64::ArchKind::INVALID;
506 }
507 
508 StringRef llvm::AArch64::getArchName(ArchKind AK) {
509   return AArch64ARCHNames[static_cast<unsigned>(AK)].getName();
510 }
511 
512 StringRef llvm::AArch64::getCPUAttr(ArchKind AK) {
513   return AArch64ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
514 }
515 
516 StringRef llvm::AArch64::getSubArch(ArchKind AK) {
517   return AArch64ARCHNames[static_cast<unsigned>(AK)].getSubArch();
518 }
519 
520 unsigned llvm::AArch64::getArchAttr(ArchKind AK) {
521   return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
522 }
523 
524 StringRef llvm::AArch64::getArchExtName(unsigned ArchExtKind) {
525   for (const auto &AE : AArch64ARCHExtNames)
526     if (ArchExtKind == AE.ID)
527       return AE.getName();
528   return StringRef();
529 }
530 
531 StringRef llvm::AArch64::getArchExtFeature(StringRef ArchExt) {
532   if (ArchExt.startswith("no")) {
533     StringRef ArchExtBase(ArchExt.substr(2));
534     for (const auto &AE : AArch64ARCHExtNames) {
535       if (AE.NegFeature && ArchExtBase == AE.getName())
536         return StringRef(AE.NegFeature);
537     }
538   }
539 
540   for (const auto &AE : AArch64ARCHExtNames)
541     if (AE.Feature && ArchExt == AE.getName())
542       return StringRef(AE.Feature);
543   return StringRef();
544 }
545 
546 StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) {
547   AArch64::ArchKind AK = parseArch(Arch);
548   if (AK == ArchKind::INVALID)
549     return StringRef();
550 
551   // Look for multiple AKs to find the default for pair AK+Name.
552   for (const auto &CPU : AArch64CPUNames)
553     if (CPU.ArchID == AK && CPU.Default)
554       return CPU.getName();
555 
556   // If we can't find a default then target the architecture instead
557   return "generic";
558 }
559 
560 unsigned llvm::AArch64::checkArchVersion(StringRef Arch) {
561   if (Arch.size() >= 2 && Arch[0] == 'v' && std::isdigit(Arch[1]))
562     return (Arch[1] - 48);
563   return 0;
564 }
565 
566 // ======================================================= //
567 // Parsers
568 // ======================================================= //
569 
570 static StringRef getHWDivSynonym(StringRef HWDiv) {
571   return StringSwitch<StringRef>(HWDiv)
572       .Case("thumb,arm", "arm,thumb")
573       .Default(HWDiv);
574 }
575 
576 static StringRef getFPUSynonym(StringRef FPU) {
577   return StringSwitch<StringRef>(FPU)
578       .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
579       .Case("vfp2", "vfpv2")
580       .Case("vfp3", "vfpv3")
581       .Case("vfp4", "vfpv4")
582       .Case("vfp3-d16", "vfpv3-d16")
583       .Case("vfp4-d16", "vfpv4-d16")
584       .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
585       .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
586       .Case("fp5-sp-d16", "fpv5-sp-d16")
587       .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
588       // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
589       .Case("neon-vfpv3", "neon")
590       .Default(FPU);
591 }
592 
593 static StringRef getArchSynonym(StringRef Arch) {
594   return StringSwitch<StringRef>(Arch)
595       .Case("v5", "v5t")
596       .Case("v5e", "v5te")
597       .Case("v6j", "v6")
598       .Case("v6hl", "v6k")
599       .Cases("v6m", "v6sm", "v6s-m", "v6-m")
600       .Cases("v6z", "v6zk", "v6kz")
601       .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
602       .Case("v7r", "v7-r")
603       .Case("v7m", "v7-m")
604       .Case("v7em", "v7e-m")
605       .Cases("v8", "v8a", "v8l", "aarch64", "arm64", "v8-a")
606       .Case("v8.1a", "v8.1-a")
607       .Case("v8.2a", "v8.2-a")
608       .Case("v8.3a", "v8.3-a")
609       .Case("v8.4a", "v8.4-a")
610       .Case("v8r", "v8-r")
611       .Case("v8m.base", "v8-m.base")
612       .Case("v8m.main", "v8-m.main")
613       .Default(Arch);
614 }
615 
616 // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
617 // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
618 // "v.+", if the latter, return unmodified string, minus 'eb'.
619 // If invalid, return empty string.
620 StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
621   size_t offset = StringRef::npos;
622   StringRef A = Arch;
623   StringRef Error = "";
624 
625   // Begins with "arm" / "thumb", move past it.
626   if (A.startswith("arm64"))
627     offset = 5;
628   else if (A.startswith("arm"))
629     offset = 3;
630   else if (A.startswith("thumb"))
631     offset = 5;
632   else if (A.startswith("aarch64")) {
633     offset = 7;
634     // AArch64 uses "_be", not "eb" suffix.
635     if (A.find("eb") != StringRef::npos)
636       return Error;
637     if (A.substr(offset, 3) == "_be")
638       offset += 3;
639   }
640 
641   // Ex. "armebv7", move past the "eb".
642   if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
643     offset += 2;
644   // Or, if it ends with eb ("armv7eb"), chop it off.
645   else if (A.endswith("eb"))
646     A = A.substr(0, A.size() - 2);
647   // Trim the head
648   if (offset != StringRef::npos)
649     A = A.substr(offset);
650 
651   // Empty string means offset reached the end, which means it's valid.
652   if (A.empty())
653     return Arch;
654 
655   // Only match non-marketing names
656   if (offset != StringRef::npos) {
657     // Must start with 'vN'.
658     if (A.size() >= 2 && (A[0] != 'v' || !std::isdigit(A[1])))
659       return Error;
660     // Can't have an extra 'eb'.
661     if (A.find("eb") != StringRef::npos)
662       return Error;
663   }
664 
665   // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
666   return A;
667 }
668 
669 unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
670   StringRef Syn = getHWDivSynonym(HWDiv);
671   for (const auto D : HWDivNames) {
672     if (Syn == D.getName())
673       return D.ID;
674   }
675   return ARM::AEK_INVALID;
676 }
677 
678 unsigned llvm::ARM::parseFPU(StringRef FPU) {
679   StringRef Syn = getFPUSynonym(FPU);
680   for (const auto F : FPUNames) {
681     if (Syn == F.getName())
682       return F.ID;
683   }
684   return ARM::FK_INVALID;
685 }
686 
687 // Allows partial match, ex. "v7a" matches "armv7a".
688 ARM::ArchKind ARM::parseArch(StringRef Arch) {
689   Arch = getCanonicalArchName(Arch);
690   StringRef Syn = getArchSynonym(Arch);
691   for (const auto A : ARCHNames) {
692     if (A.getName().endswith(Syn))
693       return A.ID;
694   }
695   return ARM::ArchKind::INVALID;
696 }
697 
698 unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
699   for (const auto A : ARCHExtNames) {
700     if (ArchExt == A.getName())
701       return A.ID;
702   }
703   return ARM::AEK_INVALID;
704 }
705 
706 ARM::ArchKind llvm::ARM::parseCPUArch(StringRef CPU) {
707   for (const auto C : CPUNames) {
708     if (CPU == C.getName())
709       return C.ArchID;
710   }
711   return ARM::ArchKind::INVALID;
712 }
713 
714 void llvm::ARM::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
715   for (const CpuNames<ARM::ArchKind> &Arch : CPUNames) {
716     if (Arch.ArchID != ARM::ArchKind::INVALID)
717       Values.push_back(Arch.getName());
718   }
719 }
720 
721 void llvm::AArch64::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
722   for (const CpuNames<AArch64::ArchKind> &Arch : AArch64CPUNames) {
723     if (Arch.ArchID != AArch64::ArchKind::INVALID)
724       Values.push_back(Arch.getName());
725   }
726 }
727 
728 // ARM, Thumb, AArch64
729 ARM::ISAKind ARM::parseArchISA(StringRef Arch) {
730   return StringSwitch<ARM::ISAKind>(Arch)
731       .StartsWith("aarch64", ARM::ISAKind::AARCH64)
732       .StartsWith("arm64", ARM::ISAKind::AARCH64)
733       .StartsWith("thumb", ARM::ISAKind::THUMB)
734       .StartsWith("arm", ARM::ISAKind::ARM)
735       .Default(ARM::ISAKind::INVALID);
736 }
737 
738 // Little/Big endian
739 ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
740   if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
741       Arch.startswith("aarch64_be"))
742     return ARM::EndianKind::BIG;
743 
744   if (Arch.startswith("arm") || Arch.startswith("thumb")) {
745     if (Arch.endswith("eb"))
746       return ARM::EndianKind::BIG;
747     else
748       return ARM::EndianKind::LITTLE;
749   }
750 
751   if (Arch.startswith("aarch64"))
752     return ARM::EndianKind::LITTLE;
753 
754   return ARM::EndianKind::INVALID;
755 }
756 
757 // Profile A/R/M
758 ARM::ProfileKind ARM::parseArchProfile(StringRef Arch) {
759   Arch = getCanonicalArchName(Arch);
760   switch (parseArch(Arch)) {
761   case ARM::ArchKind::ARMV6M:
762   case ARM::ArchKind::ARMV7M:
763   case ARM::ArchKind::ARMV7EM:
764   case ARM::ArchKind::ARMV8MMainline:
765   case ARM::ArchKind::ARMV8MBaseline:
766     return ARM::ProfileKind::M;
767   case ARM::ArchKind::ARMV7R:
768   case ARM::ArchKind::ARMV8R:
769     return ARM::ProfileKind::R;
770   case ARM::ArchKind::ARMV7A:
771   case ARM::ArchKind::ARMV7VE:
772   case ARM::ArchKind::ARMV7K:
773   case ARM::ArchKind::ARMV8A:
774   case ARM::ArchKind::ARMV8_1A:
775   case ARM::ArchKind::ARMV8_2A:
776   case ARM::ArchKind::ARMV8_3A:
777   case ARM::ArchKind::ARMV8_4A:
778     return ARM::ProfileKind::A;
779   case ARM::ArchKind::ARMV2:
780   case ARM::ArchKind::ARMV2A:
781   case ARM::ArchKind::ARMV3:
782   case ARM::ArchKind::ARMV3M:
783   case ARM::ArchKind::ARMV4:
784   case ARM::ArchKind::ARMV4T:
785   case ARM::ArchKind::ARMV5T:
786   case ARM::ArchKind::ARMV5TE:
787   case ARM::ArchKind::ARMV5TEJ:
788   case ARM::ArchKind::ARMV6:
789   case ARM::ArchKind::ARMV6K:
790   case ARM::ArchKind::ARMV6T2:
791   case ARM::ArchKind::ARMV6KZ:
792   case ARM::ArchKind::ARMV7S:
793   case ARM::ArchKind::IWMMXT:
794   case ARM::ArchKind::IWMMXT2:
795   case ARM::ArchKind::XSCALE:
796   case ARM::ArchKind::INVALID:
797     return ARM::ProfileKind::INVALID;
798   }
799   llvm_unreachable("Unhandled architecture");
800 }
801 
802 // Version number (ex. v7 = 7).
803 unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
804   Arch = getCanonicalArchName(Arch);
805   switch (parseArch(Arch)) {
806   case ARM::ArchKind::ARMV2:
807   case ARM::ArchKind::ARMV2A:
808     return 2;
809   case ARM::ArchKind::ARMV3:
810   case ARM::ArchKind::ARMV3M:
811     return 3;
812   case ARM::ArchKind::ARMV4:
813   case ARM::ArchKind::ARMV4T:
814     return 4;
815   case ARM::ArchKind::ARMV5T:
816   case ARM::ArchKind::ARMV5TE:
817   case ARM::ArchKind::IWMMXT:
818   case ARM::ArchKind::IWMMXT2:
819   case ARM::ArchKind::XSCALE:
820   case ARM::ArchKind::ARMV5TEJ:
821     return 5;
822   case ARM::ArchKind::ARMV6:
823   case ARM::ArchKind::ARMV6K:
824   case ARM::ArchKind::ARMV6T2:
825   case ARM::ArchKind::ARMV6KZ:
826   case ARM::ArchKind::ARMV6M:
827     return 6;
828   case ARM::ArchKind::ARMV7A:
829   case ARM::ArchKind::ARMV7VE:
830   case ARM::ArchKind::ARMV7R:
831   case ARM::ArchKind::ARMV7M:
832   case ARM::ArchKind::ARMV7S:
833   case ARM::ArchKind::ARMV7EM:
834   case ARM::ArchKind::ARMV7K:
835     return 7;
836   case ARM::ArchKind::ARMV8A:
837   case ARM::ArchKind::ARMV8_1A:
838   case ARM::ArchKind::ARMV8_2A:
839   case ARM::ArchKind::ARMV8_3A:
840   case ARM::ArchKind::ARMV8_4A:
841   case ARM::ArchKind::ARMV8R:
842   case ARM::ArchKind::ARMV8MBaseline:
843   case ARM::ArchKind::ARMV8MMainline:
844     return 8;
845   case ARM::ArchKind::INVALID:
846     return 0;
847   }
848   llvm_unreachable("Unhandled architecture");
849 }
850 
851 StringRef llvm::ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) {
852   StringRef ArchName =
853       CPU.empty() ? TT.getArchName() : ARM::getArchName(ARM::parseCPUArch(CPU));
854 
855   if (TT.isOSBinFormatMachO()) {
856     if (TT.getEnvironment() == Triple::EABI ||
857         TT.getOS() == Triple::UnknownOS ||
858         llvm::ARM::parseArchProfile(ArchName) == ARM::ProfileKind::M)
859       return "aapcs";
860     if (TT.isWatchABI())
861       return "aapcs16";
862     return "apcs-gnu";
863   } else if (TT.isOSWindows())
864     // FIXME: this is invalid for WindowsCE.
865     return "aapcs";
866 
867   // Select the default based on the platform.
868   switch (TT.getEnvironment()) {
869   case Triple::Android:
870   case Triple::GNUEABI:
871   case Triple::GNUEABIHF:
872   case Triple::MuslEABI:
873   case Triple::MuslEABIHF:
874     return "aapcs-linux";
875   case Triple::EABIHF:
876   case Triple::EABI:
877     return "aapcs";
878   default:
879     if (TT.isOSNetBSD())
880       return "apcs-gnu";
881     if (TT.isOSOpenBSD())
882       return "aapcs-linux";
883     return "aapcs";
884   }
885 }
886 
887 StringRef llvm::AArch64::getCanonicalArchName(StringRef Arch) {
888   return ARM::getCanonicalArchName(Arch);
889 }
890 
891 unsigned llvm::AArch64::parseFPU(StringRef FPU) {
892   return ARM::parseFPU(FPU);
893 }
894 
895 // Allows partial match, ex. "v8a" matches "armv8a".
896 AArch64::ArchKind AArch64::parseArch(StringRef Arch) {
897   Arch = getCanonicalArchName(Arch);
898   if (checkArchVersion(Arch) < 8)
899     return ArchKind::INVALID;
900 
901   StringRef Syn = getArchSynonym(Arch);
902   for (const auto A : AArch64ARCHNames) {
903     if (A.getName().endswith(Syn))
904       return A.ID;
905   }
906   return ArchKind::INVALID;
907 }
908 
909 AArch64::ArchExtKind llvm::AArch64::parseArchExt(StringRef ArchExt) {
910   for (const auto A : AArch64ARCHExtNames) {
911     if (ArchExt == A.getName())
912       return static_cast<ArchExtKind>(A.ID);
913   }
914   return AArch64::AEK_INVALID;
915 }
916 
917 AArch64::ArchKind llvm::AArch64::parseCPUArch(StringRef CPU) {
918   for (const auto C : AArch64CPUNames) {
919     if (CPU == C.getName())
920       return C.ArchID;
921   }
922   return ArchKind::INVALID;
923 }
924 
925 // ARM, Thumb, AArch64
926 ARM::ISAKind AArch64::parseArchISA(StringRef Arch) {
927   return ARM::parseArchISA(Arch);
928 }
929 
930 // Little/Big endian
931 ARM::EndianKind AArch64::parseArchEndian(StringRef Arch) {
932   return ARM::parseArchEndian(Arch);
933 }
934 
935 // Profile A/R/M
936 ARM::ProfileKind AArch64::parseArchProfile(StringRef Arch) {
937   return ARM::parseArchProfile(Arch);
938 }
939 
940 // Version number (ex. v8 = 8).
941 unsigned llvm::AArch64::parseArchVersion(StringRef Arch) {
942   return ARM::parseArchVersion(Arch);
943 }
944 
945 bool llvm::AArch64::isX18ReservedByDefault(const Triple &TT) {
946   return TT.isOSDarwin() || TT.isOSFuchsia() || TT.isOSWindows();
947 }
948 
949 struct GPUInfo {
950   StringLiteral Name;
951   StringLiteral CanonicalName;
952   AMDGPU::GPUKind Kind;
953   unsigned Features;
954 };
955 
956 using namespace AMDGPU;
957 static constexpr GPUInfo R600GPUs[26] = {
958   // Name         Canonical    Kind       Features
959   //              Name
960   //
961   {{"r600"},    {"r600"},    GK_R600,    FEATURE_NONE },
962   {{"rv630"},   {"r600"},    GK_R600,    FEATURE_NONE },
963   {{"rv635"},   {"r600"},    GK_R600,    FEATURE_NONE },
964   {{"r630"},    {"r630"},    GK_R630,    FEATURE_NONE },
965   {{"rs780"},   {"rs880"},   GK_RS880,   FEATURE_NONE },
966   {{"rs880"},   {"rs880"},   GK_RS880,   FEATURE_NONE },
967   {{"rv610"},   {"rs880"},   GK_RS880,   FEATURE_NONE },
968   {{"rv620"},   {"rs880"},   GK_RS880,   FEATURE_NONE },
969   {{"rv670"},   {"rv670"},   GK_RV670,   FEATURE_NONE },
970   {{"rv710"},   {"rv710"},   GK_RV710,   FEATURE_NONE },
971   {{"rv730"},   {"rv730"},   GK_RV730,   FEATURE_NONE },
972   {{"rv740"},   {"rv770"},   GK_RV770,   FEATURE_NONE },
973   {{"rv770"},   {"rv770"},   GK_RV770,   FEATURE_NONE },
974   {{"cedar"},   {"cedar"},   GK_CEDAR,   FEATURE_NONE },
975   {{"palm"},    {"cedar"},   GK_CEDAR,   FEATURE_NONE },
976   {{"cypress"}, {"cypress"}, GK_CYPRESS, FEATURE_FMA  },
977   {{"hemlock"}, {"cypress"}, GK_CYPRESS, FEATURE_FMA  },
978   {{"juniper"}, {"juniper"}, GK_JUNIPER, FEATURE_NONE },
979   {{"redwood"}, {"redwood"}, GK_REDWOOD, FEATURE_NONE },
980   {{"sumo"},    {"sumo"},    GK_SUMO,    FEATURE_NONE },
981   {{"sumo2"},   {"sumo"},    GK_SUMO,    FEATURE_NONE },
982   {{"barts"},   {"barts"},   GK_BARTS,   FEATURE_NONE },
983   {{"caicos"},  {"caicos"},  GK_CAICOS,  FEATURE_NONE },
984   {{"aruba"},   {"cayman"},  GK_CAYMAN,  FEATURE_FMA  },
985   {{"cayman"},  {"cayman"},  GK_CAYMAN,  FEATURE_FMA  },
986   {{"turks"},   {"turks"},   GK_TURKS,   FEATURE_NONE }
987 };
988 
989 // This table should be sorted by the value of GPUKind
990 // Don't bother listing the implicitly true features
991 static constexpr GPUInfo AMDGCNGPUs[32] = {
992   // Name           Canonical    Kind      Features
993   //                Name
994   {{"gfx600"},    {"gfx600"},  GK_GFX600,  FEATURE_FAST_FMA_F32},
995   {{"tahiti"},    {"gfx600"},  GK_GFX600,  FEATURE_FAST_FMA_F32},
996   {{"gfx601"},    {"gfx601"},  GK_GFX601,  FEATURE_NONE},
997   {{"hainan"},    {"gfx601"},  GK_GFX601,  FEATURE_NONE},
998   {{"oland"},     {"gfx601"},  GK_GFX601,  FEATURE_NONE},
999   {{"pitcairn"},  {"gfx601"},  GK_GFX601,  FEATURE_NONE},
1000   {{"verde"},     {"gfx601"},  GK_GFX601,  FEATURE_NONE},
1001   {{"gfx700"},    {"gfx700"},  GK_GFX700,  FEATURE_NONE},
1002   {{"kaveri"},    {"gfx700"},  GK_GFX700,  FEATURE_NONE},
1003   {{"gfx701"},    {"gfx701"},  GK_GFX701,  FEATURE_FAST_FMA_F32},
1004   {{"hawaii"},    {"gfx701"},  GK_GFX701,  FEATURE_FAST_FMA_F32},
1005   {{"gfx702"},    {"gfx702"},  GK_GFX702,  FEATURE_FAST_FMA_F32},
1006   {{"gfx703"},    {"gfx703"},  GK_GFX703,  FEATURE_NONE},
1007   {{"kabini"},    {"gfx703"},  GK_GFX703,  FEATURE_NONE},
1008   {{"mullins"},   {"gfx703"},  GK_GFX703,  FEATURE_NONE},
1009   {{"gfx704"},    {"gfx704"},  GK_GFX704,  FEATURE_NONE},
1010   {{"bonaire"},   {"gfx704"},  GK_GFX704,  FEATURE_NONE},
1011   {{"gfx801"},    {"gfx801"},  GK_GFX801,  FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
1012   {{"carrizo"},   {"gfx801"},  GK_GFX801,  FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
1013   {{"gfx802"},    {"gfx802"},  GK_GFX802,  FEATURE_FAST_DENORMAL_F32},
1014   {{"iceland"},   {"gfx802"},  GK_GFX802,  FEATURE_FAST_DENORMAL_F32},
1015   {{"tonga"},     {"gfx802"},  GK_GFX802,  FEATURE_FAST_DENORMAL_F32},
1016   {{"gfx803"},    {"gfx803"},  GK_GFX803,  FEATURE_FAST_DENORMAL_F32},
1017   {{"fiji"},      {"gfx803"},  GK_GFX803,  FEATURE_FAST_DENORMAL_F32},
1018   {{"polaris10"}, {"gfx803"},  GK_GFX803,  FEATURE_FAST_DENORMAL_F32},
1019   {{"polaris11"}, {"gfx803"},  GK_GFX803,  FEATURE_FAST_DENORMAL_F32},
1020   {{"gfx810"},    {"gfx810"},  GK_GFX810,  FEATURE_FAST_DENORMAL_F32},
1021   {{"stoney"},    {"gfx810"},  GK_GFX810,  FEATURE_FAST_DENORMAL_F32},
1022   {{"gfx900"},    {"gfx900"},  GK_GFX900,  FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
1023   {{"gfx902"},    {"gfx902"},  GK_GFX902,  FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
1024   {{"gfx904"},    {"gfx904"},  GK_GFX904,  FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
1025   {{"gfx906"},    {"gfx906"},  GK_GFX906,  FEATURE_FAST_FMA_F32|FEATURE_FAST_DENORMAL_F32},
1026 };
1027 
1028 static const GPUInfo *getArchEntry(AMDGPU::GPUKind AK,
1029                                    ArrayRef<GPUInfo> Table) {
1030   GPUInfo Search = { {""}, {""}, AK, AMDGPU::FEATURE_NONE };
1031 
1032   auto I = std::lower_bound(Table.begin(), Table.end(), Search,
1033     [](const GPUInfo &A, const GPUInfo &B) {
1034       return A.Kind < B.Kind;
1035     });
1036 
1037   if (I == Table.end())
1038     return nullptr;
1039   return I;
1040 }
1041 
1042 StringRef llvm::AMDGPU::getArchNameAMDGCN(GPUKind AK) {
1043   if (const auto *Entry = getArchEntry(AK, AMDGCNGPUs))
1044     return Entry->CanonicalName;
1045   return "";
1046 }
1047 
1048 StringRef llvm::AMDGPU::getArchNameR600(GPUKind AK) {
1049   if (const auto *Entry = getArchEntry(AK, R600GPUs))
1050     return Entry->CanonicalName;
1051   return "";
1052 }
1053 
1054 AMDGPU::GPUKind llvm::AMDGPU::parseArchAMDGCN(StringRef CPU) {
1055   for (const auto C : AMDGCNGPUs) {
1056     if (CPU == C.Name)
1057       return C.Kind;
1058   }
1059 
1060   return AMDGPU::GPUKind::GK_NONE;
1061 }
1062 
1063 AMDGPU::GPUKind llvm::AMDGPU::parseArchR600(StringRef CPU) {
1064   for (const auto C : R600GPUs) {
1065     if (CPU == C.Name)
1066       return C.Kind;
1067   }
1068 
1069   return AMDGPU::GPUKind::GK_NONE;
1070 }
1071 
1072 unsigned AMDGPU::getArchAttrAMDGCN(GPUKind AK) {
1073   if (const auto *Entry = getArchEntry(AK, AMDGCNGPUs))
1074     return Entry->Features;
1075   return FEATURE_NONE;
1076 }
1077 
1078 unsigned AMDGPU::getArchAttrR600(GPUKind AK) {
1079   if (const auto *Entry = getArchEntry(AK, R600GPUs))
1080     return Entry->Features;
1081   return FEATURE_NONE;
1082 }
1083 
1084 void AMDGPU::fillValidArchListAMDGCN(SmallVectorImpl<StringRef> &Values) {
1085   // XXX: Should this only report unique canonical names?
1086   for (const auto C : AMDGCNGPUs)
1087     Values.push_back(C.Name);
1088 }
1089 
1090 void AMDGPU::fillValidArchListR600(SmallVectorImpl<StringRef> &Values) {
1091   for (const auto C : R600GPUs)
1092     Values.push_back(C.Name);
1093 }
1094