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 
692 // ARM, Thumb, AArch64
694  return StringSwitch<ARM::ISAKind>(Arch)
695  .StartsWith("aarch64", ARM::ISAKind::AARCH64)
700 }
701 
702 // Little/Big endian
704  if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
705  Arch.startswith("aarch64_be"))
706  return ARM::EndianKind::BIG;
707 
708  if (Arch.startswith("arm") || Arch.startswith("thumb")) {
709  if (Arch.endswith("eb"))
710  return ARM::EndianKind::BIG;
711  else
713  }
714 
715  if (Arch.startswith("aarch64"))
717 
719 }
720 
721 // Profile A/R/M
723  Arch = getCanonicalArchName(Arch);
724  switch (parseArch(Arch)) {
725  case ARM::ArchKind::ARMV6M:
726  case ARM::ArchKind::ARMV7M:
727  case ARM::ArchKind::ARMV7EM:
728  case ARM::ArchKind::ARMV8MMainline:
729  case ARM::ArchKind::ARMV8MBaseline:
730  return ARM::ProfileKind::M;
731  case ARM::ArchKind::ARMV7R:
732  case ARM::ArchKind::ARMV8R:
733  return ARM::ProfileKind::R;
734  case ARM::ArchKind::ARMV7A:
735  case ARM::ArchKind::ARMV7VE:
736  case ARM::ArchKind::ARMV7K:
737  case ARM::ArchKind::ARMV8A:
738  case ARM::ArchKind::ARMV8_1A:
739  case ARM::ArchKind::ARMV8_2A:
740  case ARM::ArchKind::ARMV8_3A:
741  return ARM::ProfileKind::A;
742  case ARM::ArchKind::ARMV2:
743  case ARM::ArchKind::ARMV2A:
744  case ARM::ArchKind::ARMV3:
745  case ARM::ArchKind::ARMV3M:
746  case ARM::ArchKind::ARMV4:
747  case ARM::ArchKind::ARMV4T:
748  case ARM::ArchKind::ARMV5T:
749  case ARM::ArchKind::ARMV5TE:
750  case ARM::ArchKind::ARMV5TEJ:
751  case ARM::ArchKind::ARMV6:
752  case ARM::ArchKind::ARMV6K:
753  case ARM::ArchKind::ARMV6T2:
754  case ARM::ArchKind::ARMV6KZ:
755  case ARM::ArchKind::ARMV7S:
756  case ARM::ArchKind::IWMMXT:
757  case ARM::ArchKind::IWMMXT2:
758  case ARM::ArchKind::XSCALE:
761  }
762  llvm_unreachable("Unhandled architecture");
763 }
764 
765 // Version number (ex. v7 = 7).
767  Arch = getCanonicalArchName(Arch);
768  switch (parseArch(Arch)) {
769  case ARM::ArchKind::ARMV2:
770  case ARM::ArchKind::ARMV2A:
771  return 2;
772  case ARM::ArchKind::ARMV3:
773  case ARM::ArchKind::ARMV3M:
774  return 3;
775  case ARM::ArchKind::ARMV4:
776  case ARM::ArchKind::ARMV4T:
777  return 4;
778  case ARM::ArchKind::ARMV5T:
779  case ARM::ArchKind::ARMV5TE:
780  case ARM::ArchKind::IWMMXT:
781  case ARM::ArchKind::IWMMXT2:
782  case ARM::ArchKind::XSCALE:
783  case ARM::ArchKind::ARMV5TEJ:
784  return 5;
785  case ARM::ArchKind::ARMV6:
786  case ARM::ArchKind::ARMV6K:
787  case ARM::ArchKind::ARMV6T2:
788  case ARM::ArchKind::ARMV6KZ:
789  case ARM::ArchKind::ARMV6M:
790  return 6;
791  case ARM::ArchKind::ARMV7A:
792  case ARM::ArchKind::ARMV7VE:
793  case ARM::ArchKind::ARMV7R:
794  case ARM::ArchKind::ARMV7M:
795  case ARM::ArchKind::ARMV7S:
796  case ARM::ArchKind::ARMV7EM:
797  case ARM::ArchKind::ARMV7K:
798  return 7;
799  case ARM::ArchKind::ARMV8A:
800  case ARM::ArchKind::ARMV8_1A:
801  case ARM::ArchKind::ARMV8_2A:
802  case ARM::ArchKind::ARMV8_3A:
803  case ARM::ArchKind::ARMV8R:
804  case ARM::ArchKind::ARMV8MBaseline:
805  case ARM::ArchKind::ARMV8MMainline:
806  return 8;
808  return 0;
809  }
810  llvm_unreachable("Unhandled architecture");
811 }
812 
814  StringRef ArchName =
816 
817  if (TT.isOSBinFormatMachO()) {
818  if (TT.getEnvironment() == Triple::EABI ||
819  TT.getOS() == Triple::UnknownOS ||
821  return "aapcs";
822  if (TT.isWatchABI())
823  return "aapcs16";
824  return "apcs-gnu";
825  } else if (TT.isOSWindows())
826  // FIXME: this is invalid for WindowsCE.
827  return "aapcs";
828 
829  // Select the default based on the platform.
830  switch (TT.getEnvironment()) {
831  case Triple::Android:
832  case Triple::GNUEABI:
833  case Triple::GNUEABIHF:
834  case Triple::MuslEABI:
835  case Triple::MuslEABIHF:
836  return "aapcs-linux";
837  case Triple::EABIHF:
838  case Triple::EABI:
839  return "aapcs";
840  default:
841  if (TT.isOSNetBSD())
842  return "apcs-gnu";
843  if (TT.isOSOpenBSD())
844  return "aapcs-linux";
845  return "aapcs";
846  }
847 }
848 
850  return ARM::getCanonicalArchName(Arch);
851 }
852 
853 unsigned llvm::AArch64::parseFPU(StringRef FPU) {
854  return ARM::parseFPU(FPU);
855 }
856 
857 // Allows partial match, ex. "v8a" matches "armv8a".
859  Arch = getCanonicalArchName(Arch);
860  if (checkArchVersion(Arch) < 8)
861  return ArchKind::INVALID;
862 
863  StringRef Syn = getArchSynonym(Arch);
864  for (const auto A : AArch64ARCHNames) {
865  if (A.getName().endswith(Syn))
866  return A.ID;
867  }
868  return ArchKind::INVALID;
869 }
870 
872  for (const auto A : AArch64ARCHExtNames) {
873  if (ArchExt == A.getName())
874  return static_cast<ArchExtKind>(A.ID);
875  }
876  return AArch64::AEK_INVALID;
877 }
878 
880  for (const auto C : AArch64CPUNames) {
881  if (CPU == C.getName())
882  return C.ArchID;
883  }
884  return ArchKind::INVALID;
885 }
886 
887 // ARM, Thumb, AArch64
889  return ARM::parseArchISA(Arch);
890 }
891 
892 // Little/Big endian
894  return ARM::parseArchEndian(Arch);
895 }
896 
897 // Profile A/R/M
899  return ARM::parseArchProfile(Arch);
900 }
901 
902 // Version number (ex. v8 = 8).
904  return ARM::parseArchVersion(Arch);
905 }
unsigned getArchAttr(ArchKind AK)
uint64_t CallInst * C
ArchKind parseCPUArch(StringRef CPU)
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)
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)
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
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:74
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 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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool getFPUFeatures(unsigned FPUKind, std::vector< StringRef > &Features)
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
Definition: StringSwitch.h:244
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:940
ARM::ProfileKind parseArchProfile(StringRef Arch)
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 & Cases(const char(&S0)[N0], const char(&S1)[N1], const T &Value)
Definition: StringSwitch.h:107
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)
FPURestriction getFPURestriction(unsigned FPUKind)
unsigned getDefaultExtensions(StringRef CPU, ArchKind AK)
static const struct @369 Extensions[]
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_ATTRIBUTE_ALWAYS_INLINE StringSwitch & StartsWith(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:96
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)