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