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 
484  return AK != AArch64::ArchKind::INVALID;
485 }
486 
488  return AArch64ARCHNames[static_cast<unsigned>(AK)].getName();
489 }
490 
492  return AArch64ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
493 }
494 
496  return AArch64ARCHNames[static_cast<unsigned>(AK)].getSubArch();
497 }
498 
500  return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
501 }
502 
504  for (const auto &AE : AArch64ARCHExtNames)
505  if (ArchExtKind == AE.ID)
506  return AE.getName();
507  return StringRef();
508 }
509 
511  if (ArchExt.startswith("no")) {
512  StringRef ArchExtBase(ArchExt.substr(2));
513  for (const auto &AE : AArch64ARCHExtNames) {
514  if (AE.NegFeature && ArchExtBase == AE.getName())
515  return StringRef(AE.NegFeature);
516  }
517  }
518 
519  for (const auto &AE : AArch64ARCHExtNames)
520  if (AE.Feature && ArchExt == AE.getName())
521  return StringRef(AE.Feature);
522  return StringRef();
523 }
524 
526  AArch64::ArchKind AK = parseArch(Arch);
527  if (AK == ArchKind::INVALID)
528  return StringRef();
529 
530  // Look for multiple AKs to find the default for pair AK+Name.
531  for (const auto &CPU : AArch64CPUNames)
532  if (CPU.ArchID == AK && CPU.Default)
533  return CPU.getName();
534 
535  // If we can't find a default then target the architecture instead
536  return "generic";
537 }
538 
540  if (Arch.size() >= 2 && Arch[0] == 'v' && std::isdigit(Arch[1]))
541  return (Arch[1] - 48);
542  return 0;
543 }
544 
545 // ======================================================= //
546 // Parsers
547 // ======================================================= //
548 
550  return StringSwitch<StringRef>(HWDiv)
551  .Case("thumb,arm", "arm,thumb")
552  .Default(HWDiv);
553 }
554 
556  return StringSwitch<StringRef>(FPU)
557  .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
558  .Case("vfp2", "vfpv2")
559  .Case("vfp3", "vfpv3")
560  .Case("vfp4", "vfpv4")
561  .Case("vfp3-d16", "vfpv3-d16")
562  .Case("vfp4-d16", "vfpv4-d16")
563  .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
564  .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
565  .Case("fp5-sp-d16", "fpv5-sp-d16")
566  .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
567  // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
568  .Case("neon-vfpv3", "neon")
569  .Default(FPU);
570 }
571 
573  return StringSwitch<StringRef>(Arch)
574  .Case("v5", "v5t")
575  .Case("v5e", "v5te")
576  .Case("v6j", "v6")
577  .Case("v6hl", "v6k")
578  .Cases("v6m", "v6sm", "v6s-m", "v6-m")
579  .Cases("v6z", "v6zk", "v6kz")
580  .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
581  .Case("v7r", "v7-r")
582  .Case("v7m", "v7-m")
583  .Case("v7em", "v7e-m")
584  .Cases("v8", "v8a", "v8l", "aarch64", "arm64", "v8-a")
585  .Case("v8.1a", "v8.1-a")
586  .Case("v8.2a", "v8.2-a")
587  .Case("v8.3a", "v8.3-a")
588  .Case("v8r", "v8-r")
589  .Case("v8m.base", "v8-m.base")
590  .Case("v8m.main", "v8-m.main")
591  .Default(Arch);
592 }
593 
594 // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
595 // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
596 // "v.+", if the latter, return unmodified string, minus 'eb'.
597 // If invalid, return empty string.
599  size_t offset = StringRef::npos;
600  StringRef A = Arch;
601  StringRef Error = "";
602 
603  // Begins with "arm" / "thumb", move past it.
604  if (A.startswith("arm64"))
605  offset = 5;
606  else if (A.startswith("arm"))
607  offset = 3;
608  else if (A.startswith("thumb"))
609  offset = 5;
610  else if (A.startswith("aarch64")) {
611  offset = 7;
612  // AArch64 uses "_be", not "eb" suffix.
613  if (A.find("eb") != StringRef::npos)
614  return Error;
615  if (A.substr(offset, 3) == "_be")
616  offset += 3;
617  }
618 
619  // Ex. "armebv7", move past the "eb".
620  if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
621  offset += 2;
622  // Or, if it ends with eb ("armv7eb"), chop it off.
623  else if (A.endswith("eb"))
624  A = A.substr(0, A.size() - 2);
625  // Trim the head
626  if (offset != StringRef::npos)
627  A = A.substr(offset);
628 
629  // Empty string means offset reached the end, which means it's valid.
630  if (A.empty())
631  return Arch;
632 
633  // Only match non-marketing names
634  if (offset != StringRef::npos) {
635  // Must start with 'vN'.
636  if (A.size() >= 2 && (A[0] != 'v' || !std::isdigit(A[1])))
637  return Error;
638  // Can't have an extra 'eb'.
639  if (A.find("eb") != StringRef::npos)
640  return Error;
641  }
642 
643  // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
644  return A;
645 }
646 
648  StringRef Syn = getHWDivSynonym(HWDiv);
649  for (const auto D : HWDivNames) {
650  if (Syn == D.getName())
651  return D.ID;
652  }
653  return ARM::AEK_INVALID;
654 }
655 
657  StringRef Syn = getFPUSynonym(FPU);
658  for (const auto F : FPUNames) {
659  if (Syn == F.getName())
660  return F.ID;
661  }
662  return ARM::FK_INVALID;
663 }
664 
665 // Allows partial match, ex. "v7a" matches "armv7a".
667  Arch = getCanonicalArchName(Arch);
668  StringRef Syn = getArchSynonym(Arch);
669  for (const auto A : ARCHNames) {
670  if (A.getName().endswith(Syn))
671  return A.ID;
672  }
673  return ARM::ArchKind::INVALID;
674 }
675 
677  for (const auto A : ARCHExtNames) {
678  if (ArchExt == A.getName())
679  return A.ID;
680  }
681  return ARM::AEK_INVALID;
682 }
683 
685  for (const auto C : CPUNames) {
686  if (CPU == C.getName())
687  return C.ArchID;
688  }
689  return ARM::ArchKind::INVALID;
690 }
691 
693  for (const CpuNames<ARM::ArchKind> &Arch : CPUNames) {
694  if (Arch.ArchID != ARM::ArchKind::INVALID)
695  Values.push_back(Arch.getName());
696  }
697 }
698 
700  for (const CpuNames<AArch64::ArchKind> &Arch : AArch64CPUNames) {
701  if (Arch.ArchID != AArch64::ArchKind::INVALID)
702  Values.push_back(Arch.getName());
703  }
704 }
705 
706 // ARM, Thumb, AArch64
708  return StringSwitch<ARM::ISAKind>(Arch)
709  .StartsWith("aarch64", ARM::ISAKind::AARCH64)
714 }
715 
716 // Little/Big endian
718  if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
719  Arch.startswith("aarch64_be"))
720  return ARM::EndianKind::BIG;
721 
722  if (Arch.startswith("arm") || Arch.startswith("thumb")) {
723  if (Arch.endswith("eb"))
724  return ARM::EndianKind::BIG;
725  else
727  }
728 
729  if (Arch.startswith("aarch64"))
731 
733 }
734 
735 // Profile A/R/M
737  Arch = getCanonicalArchName(Arch);
738  switch (parseArch(Arch)) {
739  case ARM::ArchKind::ARMV6M:
740  case ARM::ArchKind::ARMV7M:
741  case ARM::ArchKind::ARMV7EM:
742  case ARM::ArchKind::ARMV8MMainline:
743  case ARM::ArchKind::ARMV8MBaseline:
744  return ARM::ProfileKind::M;
745  case ARM::ArchKind::ARMV7R:
746  case ARM::ArchKind::ARMV8R:
747  return ARM::ProfileKind::R;
748  case ARM::ArchKind::ARMV7A:
749  case ARM::ArchKind::ARMV7VE:
750  case ARM::ArchKind::ARMV7K:
751  case ARM::ArchKind::ARMV8A:
752  case ARM::ArchKind::ARMV8_1A:
753  case ARM::ArchKind::ARMV8_2A:
754  case ARM::ArchKind::ARMV8_3A:
755  return ARM::ProfileKind::A;
756  case ARM::ArchKind::ARMV2:
757  case ARM::ArchKind::ARMV2A:
758  case ARM::ArchKind::ARMV3:
759  case ARM::ArchKind::ARMV3M:
760  case ARM::ArchKind::ARMV4:
761  case ARM::ArchKind::ARMV4T:
762  case ARM::ArchKind::ARMV5T:
763  case ARM::ArchKind::ARMV5TE:
764  case ARM::ArchKind::ARMV5TEJ:
765  case ARM::ArchKind::ARMV6:
766  case ARM::ArchKind::ARMV6K:
767  case ARM::ArchKind::ARMV6T2:
768  case ARM::ArchKind::ARMV6KZ:
769  case ARM::ArchKind::ARMV7S:
770  case ARM::ArchKind::IWMMXT:
771  case ARM::ArchKind::IWMMXT2:
772  case ARM::ArchKind::XSCALE:
775  }
776  llvm_unreachable("Unhandled architecture");
777 }
778 
779 // Version number (ex. v7 = 7).
781  Arch = getCanonicalArchName(Arch);
782  switch (parseArch(Arch)) {
783  case ARM::ArchKind::ARMV2:
784  case ARM::ArchKind::ARMV2A:
785  return 2;
786  case ARM::ArchKind::ARMV3:
787  case ARM::ArchKind::ARMV3M:
788  return 3;
789  case ARM::ArchKind::ARMV4:
790  case ARM::ArchKind::ARMV4T:
791  return 4;
792  case ARM::ArchKind::ARMV5T:
793  case ARM::ArchKind::ARMV5TE:
794  case ARM::ArchKind::IWMMXT:
795  case ARM::ArchKind::IWMMXT2:
796  case ARM::ArchKind::XSCALE:
797  case ARM::ArchKind::ARMV5TEJ:
798  return 5;
799  case ARM::ArchKind::ARMV6:
800  case ARM::ArchKind::ARMV6K:
801  case ARM::ArchKind::ARMV6T2:
802  case ARM::ArchKind::ARMV6KZ:
803  case ARM::ArchKind::ARMV6M:
804  return 6;
805  case ARM::ArchKind::ARMV7A:
806  case ARM::ArchKind::ARMV7VE:
807  case ARM::ArchKind::ARMV7R:
808  case ARM::ArchKind::ARMV7M:
809  case ARM::ArchKind::ARMV7S:
810  case ARM::ArchKind::ARMV7EM:
811  case ARM::ArchKind::ARMV7K:
812  return 7;
813  case ARM::ArchKind::ARMV8A:
814  case ARM::ArchKind::ARMV8_1A:
815  case ARM::ArchKind::ARMV8_2A:
816  case ARM::ArchKind::ARMV8_3A:
817  case ARM::ArchKind::ARMV8R:
818  case ARM::ArchKind::ARMV8MBaseline:
819  case ARM::ArchKind::ARMV8MMainline:
820  return 8;
822  return 0;
823  }
824  llvm_unreachable("Unhandled architecture");
825 }
826 
828  StringRef ArchName =
830 
831  if (TT.isOSBinFormatMachO()) {
832  if (TT.getEnvironment() == Triple::EABI ||
833  TT.getOS() == Triple::UnknownOS ||
835  return "aapcs";
836  if (TT.isWatchABI())
837  return "aapcs16";
838  return "apcs-gnu";
839  } else if (TT.isOSWindows())
840  // FIXME: this is invalid for WindowsCE.
841  return "aapcs";
842 
843  // Select the default based on the platform.
844  switch (TT.getEnvironment()) {
845  case Triple::Android:
846  case Triple::GNUEABI:
847  case Triple::GNUEABIHF:
848  case Triple::MuslEABI:
849  case Triple::MuslEABIHF:
850  return "aapcs-linux";
851  case Triple::EABIHF:
852  case Triple::EABI:
853  return "aapcs";
854  default:
855  if (TT.isOSNetBSD())
856  return "apcs-gnu";
857  if (TT.isOSOpenBSD())
858  return "aapcs-linux";
859  return "aapcs";
860  }
861 }
862 
864  return ARM::getCanonicalArchName(Arch);
865 }
866 
867 unsigned llvm::AArch64::parseFPU(StringRef FPU) {
868  return ARM::parseFPU(FPU);
869 }
870 
871 // Allows partial match, ex. "v8a" matches "armv8a".
873  Arch = getCanonicalArchName(Arch);
874  if (checkArchVersion(Arch) < 8)
875  return ArchKind::INVALID;
876 
877  StringRef Syn = getArchSynonym(Arch);
878  for (const auto A : AArch64ARCHNames) {
879  if (A.getName().endswith(Syn))
880  return A.ID;
881  }
882  return ArchKind::INVALID;
883 }
884 
886  for (const auto A : AArch64ARCHExtNames) {
887  if (ArchExt == A.getName())
888  return static_cast<ArchExtKind>(A.ID);
889  }
890  return AArch64::AEK_INVALID;
891 }
892 
894  for (const auto C : AArch64CPUNames) {
895  if (CPU == C.getName())
896  return C.ArchID;
897  }
898  return ArchKind::INVALID;
899 }
900 
901 // ARM, Thumb, AArch64
903  return ARM::parseArchISA(Arch);
904 }
905 
906 // Little/Big endian
908  return ARM::parseArchEndian(Arch);
909 }
910 
911 // Profile A/R/M
913  return ARM::parseArchProfile(Arch);
914 }
915 
916 // Version number (ex. v8 = 8).
918  return ARM::parseArchVersion(Arch);
919 }
920 
922  return TT.isOSDarwin() || TT.isOSFuchsia() || TT.isOSWindows();
923 }
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:468
void push_back(const T &Elt)
Definition: SmallVector.h:212
ArchKind parseCPUArch(StringRef CPU)
static const struct @370 Extensions[]
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:292
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:488
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:476
unsigned parseArchVersion(StringRef Arch)
StringRef getArchName(ArchKind AK)
bool isOSWindows() const
Tests whether the OS is Windows.
Definition: Triple.h:560
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:480
bool isX18ReservedByDefault(const Triple &TT)
bool isWatchABI() const
Definition: Triple.h:463
ARM::FPURestriction getFPURestriction(unsigned FPUKind)
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:596
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:938
ARM::ProfileKind parseArchProfile(StringRef Arch)
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:301
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)