LLVM  7.0.0svn
TargetParser.cpp
Go to the documentation of this file.
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 
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/ADT/Twine.h"
19 #include <cctype>
20 
21 using namespace llvm;
22 using namespace ARM;
23 using namespace AArch64;
24 
25 namespace {
26 
27 // List of canonical FPU names (use getFPUSynonym) and which architectural
28 // features they correspond to (use getFPUFeatures).
29 // FIXME: TableGen this.
30 // The entries must appear in the order listed in ARM::FPUKind for correct indexing
31 static const struct {
32  const char *NameCStr;
33  size_t NameLength;
36  ARM::NeonSupportLevel NeonSupport;
37  ARM::FPURestriction Restriction;
38 
39  StringRef getName() const { return StringRef(NameCStr, NameLength); }
40 } FPUNames[] = {
41 #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
42  { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION },
43 #include "llvm/Support/ARMTargetParser.def"
44 };
45 
46 // List of canonical arch names (use getArchSynonym).
47 // This table also provides the build attribute fields for CPU arch
48 // and Arch ID, according to the Addenda to the ARM ABI, chapters
49 // 2.4 and 2.3.5.2 respectively.
50 // FIXME: SubArch values were simplified to fit into the expectations
51 // of the triples and are not conforming with their official names.
52 // Check to see if the expectation should be changed.
53 // FIXME: TableGen this.
54 template <typename T> struct ArchNames {
55  const char *NameCStr;
56  size_t NameLength;
57  const char *CPUAttrCStr;
58  size_t CPUAttrLength;
59  const char *SubArchCStr;
60  size_t SubArchLength;
61  unsigned DefaultFPU;
62  unsigned ArchBaseExtensions;
63  T ID;
64  ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
65 
66  StringRef getName() const { return StringRef(NameCStr, NameLength); }
67 
68  // CPU class in build attributes.
69  StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
70 
71  // Sub-Arch name.
72  StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
73 };
74 ArchNames<ARM::ArchKind> ARCHNames[] = {
75 #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
76  {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
77  sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ARM::ArchKind::ID, ARCH_ATTR},
78 #include "llvm/Support/ARMTargetParser.def"
79 };
80 
81 ArchNames<AArch64::ArchKind> AArch64ARCHNames[] = {
82  #define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
83  {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
84  sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, AArch64::ArchKind::ID, ARCH_ATTR},
85  #include "llvm/Support/AArch64TargetParser.def"
86  };
87 
88 
89 // List of Arch Extension names.
90 // FIXME: TableGen this.
91 static const struct {
92  const char *NameCStr;
93  size_t NameLength;
94  unsigned ID;
95  const char *Feature;
96  const char *NegFeature;
97 
98  StringRef getName() const { return StringRef(NameCStr, NameLength); }
99 } ARCHExtNames[] = {
100 #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
101  { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
102 #include "llvm/Support/ARMTargetParser.def"
103 },AArch64ARCHExtNames[] = {
104 #define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
105  { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
106 #include "llvm/Support/AArch64TargetParser.def"
107 };
108 
109 // List of HWDiv names (use getHWDivSynonym) and which architectural
110 // features they correspond to (use getHWDivFeatures).
111 // FIXME: TableGen this.
112 static const struct {
113  const char *NameCStr;
114  size_t NameLength;
115  unsigned ID;
116 
117  StringRef getName() const { return StringRef(NameCStr, NameLength); }
118 } HWDivNames[] = {
119 #define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
120 #include "llvm/Support/ARMTargetParser.def"
121 };
122 
123 // List of CPU names and their arches.
124 // The same CPU can have multiple arches and can be default on multiple arches.
125 // When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
126 // When this becomes table-generated, we'd probably need two tables.
127 // FIXME: TableGen this.
128 template <typename T> struct CpuNames {
129  const char *NameCStr;
130  size_t NameLength;
131  T ArchID;
132  bool Default; // is $Name the default CPU for $ArchID ?
133  unsigned DefaultExtensions;
134 
135  StringRef getName() const { return StringRef(NameCStr, NameLength); }
136 };
137 CpuNames<ARM::ArchKind> CPUNames[] = {
138 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
139  { NAME, sizeof(NAME) - 1, ARM::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
140 #include "llvm/Support/ARMTargetParser.def"
141 };
142 
143 CpuNames<AArch64::ArchKind> AArch64CPUNames[] = {
144  #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
145  { NAME, sizeof(NAME) - 1, AArch64::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
146  #include "llvm/Support/AArch64TargetParser.def"
147  };
148 
149 } // namespace
150 
151 // ======================================================= //
152 // Information by ID
153 // ======================================================= //
154 
156  if (FPUKind >= ARM::FK_LAST)
157  return StringRef();
158  return FPUNames[FPUKind].getName();
159 }
160 
162  if (FPUKind >= ARM::FK_LAST)
163  return FPUVersion::NONE;
164  return FPUNames[FPUKind].FPUVersion;
165 }
166 
168  if (FPUKind >= ARM::FK_LAST)
170  return FPUNames[FPUKind].NeonSupport;
171 }
172 
174  if (FPUKind >= ARM::FK_LAST)
176  return FPUNames[FPUKind].Restriction;
177 }
178 
180  if (CPU == "generic")
181  return ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
182 
183  return StringSwitch<unsigned>(CPU)
184 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
185  .Case(NAME, DEFAULT_FPU)
186 #include "llvm/Support/ARMTargetParser.def"
187  .Default(ARM::FK_INVALID);
188 }
189 
191  if (CPU == "generic")
192  return ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
193 
194  return StringSwitch<unsigned>(CPU)
195 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
196  .Case(NAME, ARCHNames[static_cast<unsigned>(ARM::ArchKind::ID)]\
197  .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 
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  if (Extensions & ARM::AEK_RAS)
238  Features.push_back("+ras");
239  else
240  Features.push_back("-ras");
241 
242  if (Extensions & ARM::AEK_DOTPROD)
243  Features.push_back("+dotprod");
244  else
245  Features.push_back("-dotprod");
246 
247  return getHWDivFeatures(Extensions, Features);
248 }
249 
251  std::vector<StringRef> &Features) {
252 
253  if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
254  return false;
255 
256  // fp-only-sp and d16 subtarget features are independent of each other, so we
257  // must enable/disable both.
258  switch (FPUNames[FPUKind].Restriction) {
260  Features.push_back("+fp-only-sp");
261  Features.push_back("+d16");
262  break;
264  Features.push_back("-fp-only-sp");
265  Features.push_back("+d16");
266  break;
268  Features.push_back("-fp-only-sp");
269  Features.push_back("-d16");
270  break;
271  }
272 
273  // FPU version subtarget features are inclusive of lower-numbered ones, so
274  // enable the one corresponding to this version and disable all that are
275  // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
276  // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
277  switch (FPUNames[FPUKind].FPUVersion) {
279  Features.push_back("+fp-armv8");
280  break;
282  Features.push_back("+vfp4");
283  Features.push_back("-fp-armv8");
284  break;
286  Features.push_back("+vfp3");
287  Features.push_back("+fp16");
288  Features.push_back("-vfp4");
289  Features.push_back("-fp-armv8");
290  break;
292  Features.push_back("+vfp3");
293  Features.push_back("-fp16");
294  Features.push_back("-vfp4");
295  Features.push_back("-fp-armv8");
296  break;
298  Features.push_back("+vfp2");
299  Features.push_back("-vfp3");
300  Features.push_back("-fp16");
301  Features.push_back("-vfp4");
302  Features.push_back("-fp-armv8");
303  break;
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  }
312 
313  // crypto includes neon, so we handle this similarly to FPU version.
314  switch (FPUNames[FPUKind].NeonSupport) {
316  Features.push_back("+neon");
317  Features.push_back("+crypto");
318  break;
320  Features.push_back("+neon");
321  Features.push_back("-crypto");
322  break;
324  Features.push_back("-neon");
325  Features.push_back("-crypto");
326  break;
327  }
328 
329  return true;
330 }
331 
333  return ARCHNames[static_cast<unsigned>(AK)].getName();
334 }
335 
337  return ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
338 }
339 
341  return ARCHNames[static_cast<unsigned>(AK)].getSubArch();
342 }
343 
345  return ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
346 }
347 
349  for (const auto AE : ARCHExtNames) {
350  if (ArchExtKind == AE.ID)
351  return AE.getName();
352  }
353  return StringRef();
354 }
355 
357  if (ArchExt.startswith("no")) {
358  StringRef ArchExtBase(ArchExt.substr(2));
359  for (const auto AE : ARCHExtNames) {
360  if (AE.NegFeature && ArchExtBase == AE.getName())
361  return StringRef(AE.NegFeature);
362  }
363  }
364  for (const auto AE : ARCHExtNames) {
365  if (AE.Feature && ArchExt == AE.getName())
366  return StringRef(AE.Feature);
367  }
368 
369  return StringRef();
370 }
371 
372 StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
373  for (const auto D : HWDivNames) {
374  if (HWDivKind == D.ID)
375  return D.getName();
376  }
377  return StringRef();
378 }
379 
381  ArchKind AK = parseArch(Arch);
382  if (AK == ARM::ArchKind::INVALID)
383  return StringRef();
384 
385  // Look for multiple AKs to find the default for pair AK+Name.
386  for (const auto CPU : CPUNames) {
387  if (CPU.ArchID == AK && CPU.Default)
388  return CPU.getName();
389  }
390 
391  // If we can't find a default then target the architecture instead
392  return "generic";
393 }
394 
396  return ARM::getFPUName(FPUKind);
397 }
398 
399 ARM::FPUVersion AArch64::getFPUVersion(unsigned FPUKind) {
400  return ARM::getFPUVersion(FPUKind);
401 }
402 
404  return ARM::getFPUNeonSupportLevel( FPUKind);
405 }
406 
408  return ARM::getFPURestriction(FPUKind);
409 }
410 
412  if (CPU == "generic")
413  return AArch64ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
414 
415  return StringSwitch<unsigned>(CPU)
416 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
417  .Case(NAME, DEFAULT_FPU)
418 #include "llvm/Support/AArch64TargetParser.def"
419  .Default(ARM::FK_INVALID);
420 }
421 
423  if (CPU == "generic")
424  return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
425 
426  return StringSwitch<unsigned>(CPU)
427 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
428  .Case(NAME, \
429  AArch64ARCHNames[static_cast<unsigned>(AArch64::ArchKind::ID)] \
430  .ArchBaseExtensions | \
431  DEFAULT_EXT)
432 #include "llvm/Support/AArch64TargetParser.def"
433  .Default(AArch64::AEK_INVALID);
434 }
435 
437  std::vector<StringRef> &Features) {
438 
439  if (Extensions == AArch64::AEK_INVALID)
440  return false;
441 
442  if (Extensions & AArch64::AEK_FP)
443  Features.push_back("+fp-armv8");
444  if (Extensions & AArch64::AEK_SIMD)
445  Features.push_back("+neon");
446  if (Extensions & AArch64::AEK_CRC)
447  Features.push_back("+crc");
448  if (Extensions & AArch64::AEK_CRYPTO)
449  Features.push_back("+crypto");
450  if (Extensions & AArch64::AEK_DOTPROD)
451  Features.push_back("+dotprod");
452  if (Extensions & AArch64::AEK_FP16)
453  Features.push_back("+fullfp16");
454  if (Extensions & AArch64::AEK_PROFILE)
455  Features.push_back("+spe");
456  if (Extensions & AArch64::AEK_RAS)
457  Features.push_back("+ras");
458  if (Extensions & AArch64::AEK_LSE)
459  Features.push_back("+lse");
460  if (Extensions & AArch64::AEK_RDM)
461  Features.push_back("+rdm");
462  if (Extensions & AArch64::AEK_SVE)
463  Features.push_back("+sve");
464  if (Extensions & AArch64::AEK_RCPC)
465  Features.push_back("+rcpc");
466 
467  return true;
468 }
469 
470 bool llvm::AArch64::getFPUFeatures(unsigned FPUKind,
471  std::vector<StringRef> &Features) {
472  return ARM::getFPUFeatures(FPUKind, Features);
473 }
474 
476  std::vector<StringRef> &Features) {
477  if (AK == AArch64::ArchKind::ARMV8_1A)
478  Features.push_back("+v8.1a");
479  if (AK == AArch64::ArchKind::ARMV8_2A)
480  Features.push_back("+v8.2a");
481  if (AK == AArch64::ArchKind::ARMV8_3A)
482  Features.push_back("+v8.3a");
483  if (AK == AArch64::ArchKind::ARMV8_4A)
484  Features.push_back("+v8.4a");
485 
486  return AK != AArch64::ArchKind::INVALID;
487 }
488 
490  return AArch64ARCHNames[static_cast<unsigned>(AK)].getName();
491 }
492 
494  return AArch64ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
495 }
496 
498  return AArch64ARCHNames[static_cast<unsigned>(AK)].getSubArch();
499 }
500 
502  return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
503 }
504 
506  for (const auto &AE : AArch64ARCHExtNames)
507  if (ArchExtKind == AE.ID)
508  return AE.getName();
509  return StringRef();
510 }
511 
513  if (ArchExt.startswith("no")) {
514  StringRef ArchExtBase(ArchExt.substr(2));
515  for (const auto &AE : AArch64ARCHExtNames) {
516  if (AE.NegFeature && ArchExtBase == AE.getName())
517  return StringRef(AE.NegFeature);
518  }
519  }
520 
521  for (const auto &AE : AArch64ARCHExtNames)
522  if (AE.Feature && ArchExt == AE.getName())
523  return StringRef(AE.Feature);
524  return StringRef();
525 }
526 
528  AArch64::ArchKind AK = parseArch(Arch);
529  if (AK == ArchKind::INVALID)
530  return StringRef();
531 
532  // Look for multiple AKs to find the default for pair AK+Name.
533  for (const auto &CPU : AArch64CPUNames)
534  if (CPU.ArchID == AK && CPU.Default)
535  return CPU.getName();
536 
537  // If we can't find a default then target the architecture instead
538  return "generic";
539 }
540 
542  if (Arch.size() >= 2 && Arch[0] == 'v' && std::isdigit(Arch[1]))
543  return (Arch[1] - 48);
544  return 0;
545 }
546 
547 // ======================================================= //
548 // Parsers
549 // ======================================================= //
550 
552  return StringSwitch<StringRef>(HWDiv)
553  .Case("thumb,arm", "arm,thumb")
554  .Default(HWDiv);
555 }
556 
558  return StringSwitch<StringRef>(FPU)
559  .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
560  .Case("vfp2", "vfpv2")
561  .Case("vfp3", "vfpv3")
562  .Case("vfp4", "vfpv4")
563  .Case("vfp3-d16", "vfpv3-d16")
564  .Case("vfp4-d16", "vfpv4-d16")
565  .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
566  .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
567  .Case("fp5-sp-d16", "fpv5-sp-d16")
568  .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
569  // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
570  .Case("neon-vfpv3", "neon")
571  .Default(FPU);
572 }
573 
575  return StringSwitch<StringRef>(Arch)
576  .Case("v5", "v5t")
577  .Case("v5e", "v5te")
578  .Case("v6j", "v6")
579  .Case("v6hl", "v6k")
580  .Cases("v6m", "v6sm", "v6s-m", "v6-m")
581  .Cases("v6z", "v6zk", "v6kz")
582  .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
583  .Case("v7r", "v7-r")
584  .Case("v7m", "v7-m")
585  .Case("v7em", "v7e-m")
586  .Cases("v8", "v8a", "v8l", "aarch64", "arm64", "v8-a")
587  .Case("v8.1a", "v8.1-a")
588  .Case("v8.2a", "v8.2-a")
589  .Case("v8.3a", "v8.3-a")
590  .Case("v8.4a", "v8.4-a")
591  .Case("v8r", "v8-r")
592  .Case("v8m.base", "v8-m.base")
593  .Case("v8m.main", "v8-m.main")
594  .Default(Arch);
595 }
596 
597 // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
598 // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
599 // "v.+", if the latter, return unmodified string, minus 'eb'.
600 // If invalid, return empty string.
602  size_t offset = StringRef::npos;
603  StringRef A = Arch;
604  StringRef Error = "";
605 
606  // Begins with "arm" / "thumb", move past it.
607  if (A.startswith("arm64"))
608  offset = 5;
609  else if (A.startswith("arm"))
610  offset = 3;
611  else if (A.startswith("thumb"))
612  offset = 5;
613  else if (A.startswith("aarch64")) {
614  offset = 7;
615  // AArch64 uses "_be", not "eb" suffix.
616  if (A.find("eb") != StringRef::npos)
617  return Error;
618  if (A.substr(offset, 3) == "_be")
619  offset += 3;
620  }
621 
622  // Ex. "armebv7", move past the "eb".
623  if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
624  offset += 2;
625  // Or, if it ends with eb ("armv7eb"), chop it off.
626  else if (A.endswith("eb"))
627  A = A.substr(0, A.size() - 2);
628  // Trim the head
629  if (offset != StringRef::npos)
630  A = A.substr(offset);
631 
632  // Empty string means offset reached the end, which means it's valid.
633  if (A.empty())
634  return Arch;
635 
636  // Only match non-marketing names
637  if (offset != StringRef::npos) {
638  // Must start with 'vN'.
639  if (A.size() >= 2 && (A[0] != 'v' || !std::isdigit(A[1])))
640  return Error;
641  // Can't have an extra 'eb'.
642  if (A.find("eb") != StringRef::npos)
643  return Error;
644  }
645 
646  // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
647  return A;
648 }
649 
651  StringRef Syn = getHWDivSynonym(HWDiv);
652  for (const auto D : HWDivNames) {
653  if (Syn == D.getName())
654  return D.ID;
655  }
656  return ARM::AEK_INVALID;
657 }
658 
660  StringRef Syn = getFPUSynonym(FPU);
661  for (const auto F : FPUNames) {
662  if (Syn == F.getName())
663  return F.ID;
664  }
665  return ARM::FK_INVALID;
666 }
667 
668 // Allows partial match, ex. "v7a" matches "armv7a".
670  Arch = getCanonicalArchName(Arch);
671  StringRef Syn = getArchSynonym(Arch);
672  for (const auto A : ARCHNames) {
673  if (A.getName().endswith(Syn))
674  return A.ID;
675  }
676  return ARM::ArchKind::INVALID;
677 }
678 
680  for (const auto A : ARCHExtNames) {
681  if (ArchExt == A.getName())
682  return A.ID;
683  }
684  return ARM::AEK_INVALID;
685 }
686 
688  for (const auto C : CPUNames) {
689  if (CPU == C.getName())
690  return C.ArchID;
691  }
692  return ARM::ArchKind::INVALID;
693 }
694 
696  for (const CpuNames<ARM::ArchKind> &Arch : CPUNames) {
697  if (Arch.ArchID != ARM::ArchKind::INVALID)
698  Values.push_back(Arch.getName());
699  }
700 }
701 
703  for (const CpuNames<AArch64::ArchKind> &Arch : AArch64CPUNames) {
704  if (Arch.ArchID != AArch64::ArchKind::INVALID)
705  Values.push_back(Arch.getName());
706  }
707 }
708 
709 // ARM, Thumb, AArch64
711  return StringSwitch<ARM::ISAKind>(Arch)
712  .StartsWith("aarch64", ARM::ISAKind::AARCH64)
717 }
718 
719 // Little/Big endian
721  if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
722  Arch.startswith("aarch64_be"))
723  return ARM::EndianKind::BIG;
724 
725  if (Arch.startswith("arm") || Arch.startswith("thumb")) {
726  if (Arch.endswith("eb"))
727  return ARM::EndianKind::BIG;
728  else
730  }
731 
732  if (Arch.startswith("aarch64"))
734 
736 }
737 
738 // Profile A/R/M
740  Arch = getCanonicalArchName(Arch);
741  switch (parseArch(Arch)) {
742  case ARM::ArchKind::ARMV6M:
743  case ARM::ArchKind::ARMV7M:
744  case ARM::ArchKind::ARMV7EM:
745  case ARM::ArchKind::ARMV8MMainline:
746  case ARM::ArchKind::ARMV8MBaseline:
747  return ARM::ProfileKind::M;
748  case ARM::ArchKind::ARMV7R:
749  case ARM::ArchKind::ARMV8R:
750  return ARM::ProfileKind::R;
751  case ARM::ArchKind::ARMV7A:
752  case ARM::ArchKind::ARMV7VE:
753  case ARM::ArchKind::ARMV7K:
754  case ARM::ArchKind::ARMV8A:
755  case ARM::ArchKind::ARMV8_1A:
756  case ARM::ArchKind::ARMV8_2A:
757  case ARM::ArchKind::ARMV8_3A:
758  case ARM::ArchKind::ARMV8_4A:
759  return ARM::ProfileKind::A;
760  case ARM::ArchKind::ARMV2:
761  case ARM::ArchKind::ARMV2A:
762  case ARM::ArchKind::ARMV3:
763  case ARM::ArchKind::ARMV3M:
764  case ARM::ArchKind::ARMV4:
765  case ARM::ArchKind::ARMV4T:
766  case ARM::ArchKind::ARMV5T:
767  case ARM::ArchKind::ARMV5TE:
768  case ARM::ArchKind::ARMV5TEJ:
769  case ARM::ArchKind::ARMV6:
770  case ARM::ArchKind::ARMV6K:
771  case ARM::ArchKind::ARMV6T2:
772  case ARM::ArchKind::ARMV6KZ:
773  case ARM::ArchKind::ARMV7S:
774  case ARM::ArchKind::IWMMXT:
775  case ARM::ArchKind::IWMMXT2:
776  case ARM::ArchKind::XSCALE:
779  }
780  llvm_unreachable("Unhandled architecture");
781 }
782 
783 // Version number (ex. v7 = 7).
785  Arch = getCanonicalArchName(Arch);
786  switch (parseArch(Arch)) {
787  case ARM::ArchKind::ARMV2:
788  case ARM::ArchKind::ARMV2A:
789  return 2;
790  case ARM::ArchKind::ARMV3:
791  case ARM::ArchKind::ARMV3M:
792  return 3;
793  case ARM::ArchKind::ARMV4:
794  case ARM::ArchKind::ARMV4T:
795  return 4;
796  case ARM::ArchKind::ARMV5T:
797  case ARM::ArchKind::ARMV5TE:
798  case ARM::ArchKind::IWMMXT:
799  case ARM::ArchKind::IWMMXT2:
800  case ARM::ArchKind::XSCALE:
801  case ARM::ArchKind::ARMV5TEJ:
802  return 5;
803  case ARM::ArchKind::ARMV6:
804  case ARM::ArchKind::ARMV6K:
805  case ARM::ArchKind::ARMV6T2:
806  case ARM::ArchKind::ARMV6KZ:
807  case ARM::ArchKind::ARMV6M:
808  return 6;
809  case ARM::ArchKind::ARMV7A:
810  case ARM::ArchKind::ARMV7VE:
811  case ARM::ArchKind::ARMV7R:
812  case ARM::ArchKind::ARMV7M:
813  case ARM::ArchKind::ARMV7S:
814  case ARM::ArchKind::ARMV7EM:
815  case ARM::ArchKind::ARMV7K:
816  return 7;
817  case ARM::ArchKind::ARMV8A:
818  case ARM::ArchKind::ARMV8_1A:
819  case ARM::ArchKind::ARMV8_2A:
820  case ARM::ArchKind::ARMV8_3A:
821  case ARM::ArchKind::ARMV8_4A:
822  case ARM::ArchKind::ARMV8R:
823  case ARM::ArchKind::ARMV8MBaseline:
824  case ARM::ArchKind::ARMV8MMainline:
825  return 8;
827  return 0;
828  }
829  llvm_unreachable("Unhandled architecture");
830 }
831 
833  StringRef ArchName =
835 
836  if (TT.isOSBinFormatMachO()) {
837  if (TT.getEnvironment() == Triple::EABI ||
838  TT.getOS() == Triple::UnknownOS ||
840  return "aapcs";
841  if (TT.isWatchABI())
842  return "aapcs16";
843  return "apcs-gnu";
844  } else if (TT.isOSWindows())
845  // FIXME: this is invalid for WindowsCE.
846  return "aapcs";
847 
848  // Select the default based on the platform.
849  switch (TT.getEnvironment()) {
850  case Triple::Android:
851  case Triple::GNUEABI:
852  case Triple::GNUEABIHF:
853  case Triple::MuslEABI:
854  case Triple::MuslEABIHF:
855  return "aapcs-linux";
856  case Triple::EABIHF:
857  case Triple::EABI:
858  return "aapcs";
859  default:
860  if (TT.isOSNetBSD())
861  return "apcs-gnu";
862  if (TT.isOSOpenBSD())
863  return "aapcs-linux";
864  return "aapcs";
865  }
866 }
867 
869  return ARM::getCanonicalArchName(Arch);
870 }
871 
872 unsigned llvm::AArch64::parseFPU(StringRef FPU) {
873  return ARM::parseFPU(FPU);
874 }
875 
876 // Allows partial match, ex. "v8a" matches "armv8a".
878  Arch = getCanonicalArchName(Arch);
879  if (checkArchVersion(Arch) < 8)
880  return ArchKind::INVALID;
881 
882  StringRef Syn = getArchSynonym(Arch);
883  for (const auto A : AArch64ARCHNames) {
884  if (A.getName().endswith(Syn))
885  return A.ID;
886  }
887  return ArchKind::INVALID;
888 }
889 
891  for (const auto A : AArch64ARCHExtNames) {
892  if (ArchExt == A.getName())
893  return static_cast<ArchExtKind>(A.ID);
894  }
895  return AArch64::AEK_INVALID;
896 }
897 
899  for (const auto C : AArch64CPUNames) {
900  if (CPU == C.getName())
901  return C.ArchID;
902  }
903  return ArchKind::INVALID;
904 }
905 
906 // ARM, Thumb, AArch64
908  return ARM::parseArchISA(Arch);
909 }
910 
911 // Little/Big endian
913  return ARM::parseArchEndian(Arch);
914 }
915 
916 // Profile A/R/M
918  return ARM::parseArchProfile(Arch);
919 }
920 
921 // Version number (ex. v8 = 8).
923  return ARM::parseArchVersion(Arch);
924 }
925 
927  return TT.isOSDarwin() || TT.isOSFuchsia() || TT.isOSWindows();
928 }
unsigned getArchAttr(ArchKind AK)
uint64_t CallInst * C
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
Definition: Triple.h:470
void push_back(const T &Elt)
Definition: SmallVector.h:213
ArchKind parseCPUArch(StringRef CPU)
void fillValidCPUArchList(SmallVectorImpl< StringRef > &Values)
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
unsigned checkArchVersion(StringRef Arch)
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:294
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:138
ARM::FPUVersion getFPUVersion(unsigned FPUKind)
StringRef getArchExtFeature(StringRef ArchExt)
StringRef getDefaultCPU(StringRef Arch)
F(f)
bool isOSFuchsia() const
Definition: Triple.h:490
unsigned parseArchExt(StringRef ArchExt)
StringRef getCPUAttr(ArchKind AK)
ARM::NeonSupportLevel getFPUNeonSupportLevel(unsigned FPUKind)
unsigned parseFPU(StringRef FPU)
static StringRef getHWDivSynonym(StringRef HWDiv)
StringRef getCPUAttr(ArchKind AK)
StringRef getArchExtName(unsigned ArchExtKind)
unsigned getDefaultFPU(StringRef CPU, ArchKind AK)
StringRef getFPUName(unsigned FPUKind)
bool getHWDivFeatures(unsigned HWDivKind, std::vector< StringRef > &Features)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:279
ArchKind parseCPUArch(StringRef CPU)
StringRef getArchExtName(unsigned ArchExtKind)
unsigned getDefaultFPU(StringRef CPU, ArchKind AK)
ISAKind parseArchISA(StringRef Arch)
StringRef getArchName(ArchKind AK)
StringRef getArchExtFeature(StringRef ArchExt)
static StringRef getName(Value *V)
bool getExtensionFeatures(unsigned Extensions, std::vector< StringRef > &Features)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
Definition: StringSwitch.h:203
AArch64::ArchKind parseArch(StringRef Arch)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:267
static StringRef getArchSynonym(StringRef Arch)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:598
bool isOSNetBSD() const
Definition: Triple.h:478
unsigned parseArchVersion(StringRef Arch)
StringRef getArchName(ArchKind AK)
bool isOSWindows() const
Tests whether the OS is Windows.
Definition: Triple.h:562
FPUVersion getFPUVersion(unsigned FPUKind)
ARM::EndianKind parseArchEndian(StringRef Arch)
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
StringRef getCanonicalArchName(StringRef Arch)
bool isOSOpenBSD() const
Definition: Triple.h:482
bool isX18ReservedByDefault(const Triple &TT)
bool isWatchABI() const
Definition: Triple.h:465
ARM::FPURestriction getFPURestriction(unsigned FPUKind)
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:598
bool getFPUFeatures(unsigned FPUKind, std::vector< StringRef > &Features)
static StringRef getFPUSynonym(StringRef FPU)
bool getExtensionFeatures(unsigned Extensions, std::vector< StringRef > &Features)
EndianKind parseArchEndian(StringRef Arch)
Only single-precision instructions, with 16 D registers.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & StartsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:86
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool getFPUFeatures(unsigned FPUKind, std::vector< StringRef > &Features)
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
StringRef getArchName() const
getArchName - Get the architecture (first) component of the triple.
Definition: Triple.cpp:942
ARM::ProfileKind parseArchProfile(StringRef Arch)
static const struct @374 Extensions[]
void fillValidCPUArchList(SmallVectorImpl< StringRef > &Values)
StringRef computeDefaultTargetABI(const Triple &TT, StringRef CPU)
ARM::ISAKind parseArchISA(StringRef Arch)
EnvironmentType getEnvironment() const
getEnvironment - Get the parsed environment type of this triple.
Definition: Triple.h:303
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)
StringRef getHWDivName(unsigned HWDivKind)
ProfileKind parseArchProfile(StringRef Arch)
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:70
static const size_t npos
Definition: StringRef.h:51
NeonSupportLevel getFPUNeonSupportLevel(unsigned FPUKind)
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:224
Only 16 D registers.
#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Definition: StringSwitch.h:94
FPURestriction getFPURestriction(unsigned FPUKind)
unsigned getDefaultExtensions(StringRef CPU, ArchKind AK)
StringRef getSubArch(ArchKind AK)
ArchKind parseArch(StringRef Arch)
StringRef getSubArch(ArchKind AK)
unsigned parseFPU(StringRef FPU)
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
const FeatureBitset Features
unsigned parseHWDiv(StringRef HWDiv)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
StringRef getCanonicalArchName(StringRef Arch)
unsigned getArchAttr(ArchKind AK)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:298
ArchExtKind parseArchExt(StringRef ArchExt)
bool getArchFeatures(ArchKind AK, std::vector< StringRef > &Features)
StringRef getDefaultCPU(StringRef Arch)
StringRef getFPUName(unsigned FPUKind)
unsigned getDefaultExtensions(StringRef CPU, ArchKind AK)
unsigned parseArchVersion(StringRef Arch)