LLVM  6.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/StringExtras.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/ADT/Twine.h"
20 #include <cctype>
21 
22 using namespace llvm;
23 using namespace ARM;
24 using namespace AArch64;
25 
26 namespace {
27 
28 // List of canonical FPU names (use getFPUSynonym) and which architectural
29 // features they correspond to (use getFPUFeatures).
30 // FIXME: TableGen this.
31 // The entries must appear in the order listed in ARM::FPUKind for correct indexing
32 static const struct {
33  const char *NameCStr;
34  size_t NameLength;
37  ARM::NeonSupportLevel NeonSupport;
38  ARM::FPURestriction Restriction;
39 
40  StringRef getName() const { return StringRef(NameCStr, NameLength); }
41 } FPUNames[] = {
42 #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
43  { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION },
44 #include "llvm/Support/ARMTargetParser.def"
45 };
46 
47 // List of canonical arch names (use getArchSynonym).
48 // This table also provides the build attribute fields for CPU arch
49 // and Arch ID, according to the Addenda to the ARM ABI, chapters
50 // 2.4 and 2.3.5.2 respectively.
51 // FIXME: SubArch values were simplified to fit into the expectations
52 // of the triples and are not conforming with their official names.
53 // Check to see if the expectation should be changed.
54 // FIXME: TableGen this.
55 template <typename T> struct ArchNames {
56  const char *NameCStr;
57  size_t NameLength;
58  const char *CPUAttrCStr;
59  size_t CPUAttrLength;
60  const char *SubArchCStr;
61  size_t SubArchLength;
62  unsigned DefaultFPU;
63  unsigned ArchBaseExtensions;
64  T ID;
65  ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
66 
67  StringRef getName() const { return StringRef(NameCStr, NameLength); }
68 
69  // CPU class in build attributes.
70  StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
71 
72  // Sub-Arch name.
73  StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
74 };
75 ArchNames<ARM::ArchKind> ARCHNames[] = {
76 #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
77  {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
78  sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ARM::ArchKind::ID, ARCH_ATTR},
79 #include "llvm/Support/ARMTargetParser.def"
80 };
81 
82 ArchNames<AArch64::ArchKind> AArch64ARCHNames[] = {
83  #define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
84  {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
85  sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, AArch64::ArchKind::ID, ARCH_ATTR},
86  #include "llvm/Support/AArch64TargetParser.def"
87  };
88 
89 
90 // List of Arch Extension names.
91 // FIXME: TableGen this.
92 static const struct {
93  const char *NameCStr;
94  size_t NameLength;
95  unsigned ID;
96  const char *Feature;
97  const char *NegFeature;
98 
99  StringRef getName() const { return StringRef(NameCStr, NameLength); }
100 } ARCHExtNames[] = {
101 #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
102  { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
103 #include "llvm/Support/ARMTargetParser.def"
104 },AArch64ARCHExtNames[] = {
105 #define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \
106  { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },
107 #include "llvm/Support/AArch64TargetParser.def"
108 };
109 
110 // List of HWDiv names (use getHWDivSynonym) and which architectural
111 // features they correspond to (use getHWDivFeatures).
112 // FIXME: TableGen this.
113 static const struct {
114  const char *NameCStr;
115  size_t NameLength;
116  unsigned ID;
117 
118  StringRef getName() const { return StringRef(NameCStr, NameLength); }
119 } HWDivNames[] = {
120 #define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
121 #include "llvm/Support/ARMTargetParser.def"
122 };
123 
124 // List of CPU names and their arches.
125 // The same CPU can have multiple arches and can be default on multiple arches.
126 // When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
127 // When this becomes table-generated, we'd probably need two tables.
128 // FIXME: TableGen this.
129 template <typename T> struct CpuNames {
130  const char *NameCStr;
131  size_t NameLength;
132  T ArchID;
133  bool Default; // is $Name the default CPU for $ArchID ?
134  unsigned DefaultExtensions;
135 
136  StringRef getName() const { return StringRef(NameCStr, NameLength); }
137 };
138 CpuNames<ARM::ArchKind> CPUNames[] = {
139 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
140  { NAME, sizeof(NAME) - 1, ARM::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
141 #include "llvm/Support/ARMTargetParser.def"
142 };
143 
144 CpuNames<AArch64::ArchKind> AArch64CPUNames[] = {
145  #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
146  { NAME, sizeof(NAME) - 1, AArch64::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
147  #include "llvm/Support/AArch64TargetParser.def"
148  };
149 
150 } // namespace
151 
152 // ======================================================= //
153 // Information by ID
154 // ======================================================= //
155 
157  if (FPUKind >= ARM::FK_LAST)
158  return StringRef();
159  return FPUNames[FPUKind].getName();
160 }
161 
163  if (FPUKind >= ARM::FK_LAST)
164  return FPUVersion::NONE;
165  return FPUNames[FPUKind].FPUVersion;
166 }
167 
169  if (FPUKind >= ARM::FK_LAST)
171  return FPUNames[FPUKind].NeonSupport;
172 }
173 
175  if (FPUKind >= ARM::FK_LAST)
177  return FPUNames[FPUKind].Restriction;
178 }
179 
181  if (CPU == "generic")
182  return ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
183 
184  return StringSwitch<unsigned>(CPU)
185 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
186  .Case(NAME, DEFAULT_FPU)
187 #include "llvm/Support/ARMTargetParser.def"
188  .Default(ARM::FK_INVALID);
189 }
190 
192  if (CPU == "generic")
193  return ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
194 
195  return StringSwitch<unsigned>(CPU)
196 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
197  .Case(NAME, ARCHNames[static_cast<unsigned>(ARM::ArchKind::ID)]\
198  .ArchBaseExtensions | DEFAULT_EXT)
199 #include "llvm/Support/ARMTargetParser.def"
200  .Default(ARM::AEK_INVALID);
201 }
202 
203 bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
204  std::vector<StringRef> &Features) {
205 
206  if (HWDivKind == ARM::AEK_INVALID)
207  return false;
208 
209  if (HWDivKind & ARM::AEK_HWDIVARM)
210  Features.push_back("+hwdiv-arm");
211  else
212  Features.push_back("-hwdiv-arm");
213 
214  if (HWDivKind & ARM::AEK_HWDIVTHUMB)
215  Features.push_back("+hwdiv");
216  else
217  Features.push_back("-hwdiv");
218 
219  return true;
220 }
221 
223  std::vector<StringRef> &Features) {
224 
225  if (Extensions == ARM::AEK_INVALID)
226  return false;
227 
228  if (Extensions & ARM::AEK_CRC)
229  Features.push_back("+crc");
230  else
231  Features.push_back("-crc");
232 
233  if (Extensions & ARM::AEK_DSP)
234  Features.push_back("+dsp");
235  else
236  Features.push_back("-dsp");
237 
238  if (Extensions & ARM::AEK_RAS)
239  Features.push_back("+ras");
240  else
241  Features.push_back("-ras");
242 
243  if (Extensions & ARM::AEK_DOTPROD)
244  Features.push_back("+dotprod");
245  else
246  Features.push_back("-dotprod");
247 
248  return getHWDivFeatures(Extensions, Features);
249 }
250 
252  std::vector<StringRef> &Features) {
253 
254  if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
255  return false;
256 
257  // fp-only-sp and d16 subtarget features are independent of each other, so we
258  // must enable/disable both.
259  switch (FPUNames[FPUKind].Restriction) {
261  Features.push_back("+fp-only-sp");
262  Features.push_back("+d16");
263  break;
265  Features.push_back("-fp-only-sp");
266  Features.push_back("+d16");
267  break;
269  Features.push_back("-fp-only-sp");
270  Features.push_back("-d16");
271  break;
272  }
273 
274  // FPU version subtarget features are inclusive of lower-numbered ones, so
275  // enable the one corresponding to this version and disable all that are
276  // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
277  // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
278  switch (FPUNames[FPUKind].FPUVersion) {
280  Features.push_back("+fp-armv8");
281  break;
283  Features.push_back("+vfp4");
284  Features.push_back("-fp-armv8");
285  break;
287  Features.push_back("+vfp3");
288  Features.push_back("+fp16");
289  Features.push_back("-vfp4");
290  Features.push_back("-fp-armv8");
291  break;
293  Features.push_back("+vfp3");
294  Features.push_back("-fp16");
295  Features.push_back("-vfp4");
296  Features.push_back("-fp-armv8");
297  break;
299  Features.push_back("+vfp2");
300  Features.push_back("-vfp3");
301  Features.push_back("-fp16");
302  Features.push_back("-vfp4");
303  Features.push_back("-fp-armv8");
304  break;
306  Features.push_back("-vfp2");
307  Features.push_back("-vfp3");
308  Features.push_back("-fp16");
309  Features.push_back("-vfp4");
310  Features.push_back("-fp-armv8");
311  break;
312  }
313 
314  // crypto includes neon, so we handle this similarly to FPU version.
315  switch (FPUNames[FPUKind].NeonSupport) {
317  Features.push_back("+neon");
318  Features.push_back("+crypto");
319  break;
321  Features.push_back("+neon");
322  Features.push_back("-crypto");
323  break;
325  Features.push_back("-neon");
326  Features.push_back("-crypto");
327  break;
328  }
329 
330  return true;
331 }
332 
334  return ARCHNames[static_cast<unsigned>(AK)].getName();
335 }
336 
338  return ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
339 }
340 
342  return ARCHNames[static_cast<unsigned>(AK)].getSubArch();
343 }
344 
346  return ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
347 }
348 
350  for (const auto AE : ARCHExtNames) {
351  if (ArchExtKind == AE.ID)
352  return AE.getName();
353  }
354  return StringRef();
355 }
356 
358  if (ArchExt.startswith("no")) {
359  StringRef ArchExtBase(ArchExt.substr(2));
360  for (const auto AE : ARCHExtNames) {
361  if (AE.NegFeature && ArchExtBase == AE.getName())
362  return StringRef(AE.NegFeature);
363  }
364  }
365  for (const auto AE : ARCHExtNames) {
366  if (AE.Feature && ArchExt == AE.getName())
367  return StringRef(AE.Feature);
368  }
369 
370  return StringRef();
371 }
372 
373 StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
374  for (const auto D : HWDivNames) {
375  if (HWDivKind == D.ID)
376  return D.getName();
377  }
378  return StringRef();
379 }
380 
382  ArchKind AK = parseArch(Arch);
383  if (AK == ARM::ArchKind::INVALID)
384  return StringRef();
385 
386  // Look for multiple AKs to find the default for pair AK+Name.
387  for (const auto CPU : CPUNames) {
388  if (CPU.ArchID == AK && CPU.Default)
389  return CPU.getName();
390  }
391 
392  // If we can't find a default then target the architecture instead
393  return "generic";
394 }
395 
397  return ARM::getFPUName(FPUKind);
398 }
399 
400 ARM::FPUVersion AArch64::getFPUVersion(unsigned FPUKind) {
401  return ARM::getFPUVersion(FPUKind);
402 }
403 
405  return ARM::getFPUNeonSupportLevel( FPUKind);
406 }
407 
409  return ARM::getFPURestriction(FPUKind);
410 }
411 
413  if (CPU == "generic")
414  return AArch64ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
415 
416  return StringSwitch<unsigned>(CPU)
417 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
418  .Case(NAME, DEFAULT_FPU)
419 #include "llvm/Support/AArch64TargetParser.def"
420  .Default(ARM::FK_INVALID);
421 }
422 
424  if (CPU == "generic")
425  return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
426 
427  return StringSwitch<unsigned>(CPU)
428 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
429  .Case(NAME, \
430  AArch64ARCHNames[static_cast<unsigned>(AArch64::ArchKind::ID)] \
431  .ArchBaseExtensions | \
432  DEFAULT_EXT)
433 #include "llvm/Support/AArch64TargetParser.def"
434  .Default(AArch64::AEK_INVALID);
435 }
436 
438  std::vector<StringRef> &Features) {
439 
440  if (Extensions == AArch64::AEK_INVALID)
441  return false;
442 
443  if (Extensions & AArch64::AEK_FP)
444  Features.push_back("+fp-armv8");
445  if (Extensions & AArch64::AEK_SIMD)
446  Features.push_back("+neon");
447  if (Extensions & AArch64::AEK_CRC)
448  Features.push_back("+crc");
449  if (Extensions & AArch64::AEK_CRYPTO)
450  Features.push_back("+crypto");
451  if (Extensions & AArch64::AEK_DOTPROD)
452  Features.push_back("+dotprod");
453  if (Extensions & AArch64::AEK_FP16)
454  Features.push_back("+fullfp16");
455  if (Extensions & AArch64::AEK_PROFILE)
456  Features.push_back("+spe");
457  if (Extensions & AArch64::AEK_RAS)
458  Features.push_back("+ras");
459  if (Extensions & AArch64::AEK_LSE)
460  Features.push_back("+lse");
461  if (Extensions & AArch64::AEK_RDM)
462  Features.push_back("+rdm");
463  if (Extensions & AArch64::AEK_SVE)
464  Features.push_back("+sve");
465  if (Extensions & AArch64::AEK_RCPC)
466  Features.push_back("+rcpc");
467 
468  return true;
469 }
470 
471 bool llvm::AArch64::getFPUFeatures(unsigned FPUKind,
472  std::vector<StringRef> &Features) {
473  return ARM::getFPUFeatures(FPUKind, Features);
474 }
475 
477  std::vector<StringRef> &Features) {
478  if (AK == AArch64::ArchKind::ARMV8_1A)
479  Features.push_back("+v8.1a");
480  if (AK == AArch64::ArchKind::ARMV8_2A)
481  Features.push_back("+v8.2a");
482  if (AK == AArch64::ArchKind::ARMV8_3A)
483  Features.push_back("+v8.3a");
484 
485  return AK != AArch64::ArchKind::INVALID;
486 }
487 
489  return AArch64ARCHNames[static_cast<unsigned>(AK)].getName();
490 }
491 
493  return AArch64ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
494 }
495 
497  return AArch64ARCHNames[static_cast<unsigned>(AK)].getSubArch();
498 }
499 
501  return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
502 }
503 
505  for (const auto &AE : AArch64ARCHExtNames)
506  if (ArchExtKind == AE.ID)
507  return AE.getName();
508  return StringRef();
509 }
510 
512  if (ArchExt.startswith("no")) {
513  StringRef ArchExtBase(ArchExt.substr(2));
514  for (const auto &AE : AArch64ARCHExtNames) {
515  if (AE.NegFeature && ArchExtBase == AE.getName())
516  return StringRef(AE.NegFeature);
517  }
518  }
519 
520  for (const auto &AE : AArch64ARCHExtNames)
521  if (AE.Feature && ArchExt == AE.getName())
522  return StringRef(AE.Feature);
523  return StringRef();
524 }
525 
527  AArch64::ArchKind AK = parseArch(Arch);
528  if (AK == ArchKind::INVALID)
529  return StringRef();
530 
531  // Look for multiple AKs to find the default for pair AK+Name.
532  for (const auto &CPU : AArch64CPUNames)
533  if (CPU.ArchID == AK && CPU.Default)
534  return CPU.getName();
535 
536  // If we can't find a default then target the architecture instead
537  return "generic";
538 }
539 
541  if (Arch[0] == 'v' && std::isdigit(Arch[1]))
542  return (Arch[1] - 48);
543  return 0;
544 }
545 
546 // ======================================================= //
547 // Parsers
548 // ======================================================= //
549 
551  return StringSwitch<StringRef>(HWDiv)
552  .Case("thumb,arm", "arm,thumb")
553  .Default(HWDiv);
554 }
555 
557  return StringSwitch<StringRef>(FPU)
558  .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
559  .Case("vfp2", "vfpv2")
560  .Case("vfp3", "vfpv3")
561  .Case("vfp4", "vfpv4")
562  .Case("vfp3-d16", "vfpv3-d16")
563  .Case("vfp4-d16", "vfpv4-d16")
564  .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
565  .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
566  .Case("fp5-sp-d16", "fpv5-sp-d16")
567  .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
568  // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
569  .Case("neon-vfpv3", "neon")
570  .Default(FPU);
571 }
572 
574  return StringSwitch<StringRef>(Arch)
575  .Case("v5", "v5t")
576  .Case("v5e", "v5te")
577  .Case("v6j", "v6")
578  .Case("v6hl", "v6k")
579  .Cases("v6m", "v6sm", "v6s-m", "v6-m")
580  .Cases("v6z", "v6zk", "v6kz")
581  .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
582  .Case("v7r", "v7-r")
583  .Case("v7m", "v7-m")
584  .Case("v7em", "v7e-m")
585  .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
586  .Case("v8.1a", "v8.1-a")
587  .Case("v8.2a", "v8.2-a")
588  .Case("v8.3a", "v8.3-a")
589  .Case("v8r", "v8-r")
590  .Case("v8m.base", "v8-m.base")
591  .Case("v8m.main", "v8-m.main")
592  .Default(Arch);
593 }
594 
595 // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
596 // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
597 // "v.+", if the latter, return unmodified string, minus 'eb'.
598 // If invalid, return empty string.
600  size_t offset = StringRef::npos;
601  StringRef A = Arch;
602  StringRef Error = "";
603 
604  // Begins with "arm" / "thumb", move past it.
605  if (A.startswith("arm64"))
606  offset = 5;
607  else if (A.startswith("arm"))
608  offset = 3;
609  else if (A.startswith("thumb"))
610  offset = 5;
611  else if (A.startswith("aarch64")) {
612  offset = 7;
613  // AArch64 uses "_be", not "eb" suffix.
614  if (A.find("eb") != StringRef::npos)
615  return Error;
616  if (A.substr(offset, 3) == "_be")
617  offset += 3;
618  }
619 
620  // Ex. "armebv7", move past the "eb".
621  if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
622  offset += 2;
623  // Or, if it ends with eb ("armv7eb"), chop it off.
624  else if (A.endswith("eb"))
625  A = A.substr(0, A.size() - 2);
626  // Trim the head
627  if (offset != StringRef::npos)
628  A = A.substr(offset);
629 
630  // Empty string means offset reached the end, which means it's valid.
631  if (A.empty())
632  return Arch;
633 
634  // Only match non-marketing names
635  if (offset != StringRef::npos) {
636  // Must start with 'vN'.
637  if (A[0] != 'v' || !std::isdigit(A[1]))
638  return Error;
639  // Can't have an extra 'eb'.
640  if (A.find("eb") != StringRef::npos)
641  return Error;
642  }
643 
644  // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
645  return A;
646 }
647 
649  StringRef Syn = getHWDivSynonym(HWDiv);
650  for (const auto D : HWDivNames) {
651  if (Syn == D.getName())
652  return D.ID;
653  }
654  return ARM::AEK_INVALID;
655 }
656 
658  StringRef Syn = getFPUSynonym(FPU);
659  for (const auto F : FPUNames) {
660  if (Syn == F.getName())
661  return F.ID;
662  }
663  return ARM::FK_INVALID;
664 }
665 
666 // Allows partial match, ex. "v7a" matches "armv7a".
668  Arch = getCanonicalArchName(Arch);
669  StringRef Syn = getArchSynonym(Arch);
670  for (const auto A : ARCHNames) {
671  if (A.getName().endswith(Syn))
672  return A.ID;
673  }
674  return ARM::ArchKind::INVALID;
675 }
676 
678  for (const auto A : ARCHExtNames) {
679  if (ArchExt == A.getName())
680  return A.ID;
681  }
682  return ARM::AEK_INVALID;
683 }
684 
686  for (const auto C : CPUNames) {
687  if (CPU == C.getName())
688  return C.ArchID;
689  }
690  return ARM::ArchKind::INVALID;
691 }
692 
693 // ARM, Thumb, AArch64
695  return StringSwitch<ARM::ISAKind>(Arch)
696  .StartsWith("aarch64", ARM::ISAKind::AARCH64)
701 }
702 
703 // Little/Big endian
705  if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
706  Arch.startswith("aarch64_be"))
707  return ARM::EndianKind::BIG;
708 
709  if (Arch.startswith("arm") || Arch.startswith("thumb")) {
710  if (Arch.endswith("eb"))
711  return ARM::EndianKind::BIG;
712  else
714  }
715 
716  if (Arch.startswith("aarch64"))
718 
720 }
721 
722 // Profile A/R/M
724  Arch = getCanonicalArchName(Arch);
725  switch (parseArch(Arch)) {
726  case ARM::ArchKind::ARMV6M:
727  case ARM::ArchKind::ARMV7M:
728  case ARM::ArchKind::ARMV7EM:
729  case ARM::ArchKind::ARMV8MMainline:
730  case ARM::ArchKind::ARMV8MBaseline:
731  return ARM::ProfileKind::M;
732  case ARM::ArchKind::ARMV7R:
733  case ARM::ArchKind::ARMV8R:
734  return ARM::ProfileKind::R;
735  case ARM::ArchKind::ARMV7A:
736  case ARM::ArchKind::ARMV7VE:
737  case ARM::ArchKind::ARMV7K:
738  case ARM::ArchKind::ARMV8A:
739  case ARM::ArchKind::ARMV8_1A:
740  case ARM::ArchKind::ARMV8_2A:
741  case ARM::ArchKind::ARMV8_3A:
742  return ARM::ProfileKind::A;
744  case ARM::ArchKind::ARMV2:
745  case ARM::ArchKind::ARMV2A:
746  case ARM::ArchKind::ARMV3:
747  case ARM::ArchKind::ARMV3M:
748  case ARM::ArchKind::ARMV4:
749  case ARM::ArchKind::ARMV4T:
750  case ARM::ArchKind::ARMV5T:
751  case ARM::ArchKind::ARMV5TE:
752  case ARM::ArchKind::ARMV5TEJ:
753  case ARM::ArchKind::ARMV6:
754  case ARM::ArchKind::ARMV6K:
755  case ARM::ArchKind::ARMV6T2:
756  case ARM::ArchKind::ARMV6KZ:
757  case ARM::ArchKind::ARMV7S:
758  case ARM::ArchKind::IWMMXT:
759  case ARM::ArchKind::IWMMXT2:
760  case ARM::ArchKind::XSCALE:
763  }
764  llvm_unreachable("Unhandled architecture");
765 }
766 
767 // Version number (ex. v7 = 7).
769  Arch = getCanonicalArchName(Arch);
770  switch (parseArch(Arch)) {
771  case ARM::ArchKind::ARMV2:
772  case ARM::ArchKind::ARMV2A:
773  return 2;
774  case ARM::ArchKind::ARMV3:
775  case ARM::ArchKind::ARMV3M:
776  return 3;
777  case ARM::ArchKind::ARMV4:
778  case ARM::ArchKind::ARMV4T:
779  return 4;
780  case ARM::ArchKind::ARMV5T:
781  case ARM::ArchKind::ARMV5TE:
782  case ARM::ArchKind::IWMMXT:
783  case ARM::ArchKind::IWMMXT2:
784  case ARM::ArchKind::XSCALE:
785  case ARM::ArchKind::ARMV5TEJ:
786  return 5;
787  case ARM::ArchKind::ARMV6:
788  case ARM::ArchKind::ARMV6K:
789  case ARM::ArchKind::ARMV6T2:
790  case ARM::ArchKind::ARMV6KZ:
791  case ARM::ArchKind::ARMV6M:
792  return 6;
793  case ARM::ArchKind::ARMV7A:
794  case ARM::ArchKind::ARMV7VE:
795  case ARM::ArchKind::ARMV7R:
796  case ARM::ArchKind::ARMV7M:
797  case ARM::ArchKind::ARMV7S:
798  case ARM::ArchKind::ARMV7EM:
799  case ARM::ArchKind::ARMV7K:
800  return 7;
801  case ARM::ArchKind::ARMV8A:
802  case ARM::ArchKind::ARMV8_1A:
803  case ARM::ArchKind::ARMV8_2A:
804  case ARM::ArchKind::ARMV8_3A:
805  case ARM::ArchKind::ARMV8R:
806  case ARM::ArchKind::ARMV8MBaseline:
807  case ARM::ArchKind::ARMV8MMainline:
808  return 8;
810  return 0;
811  }
812  llvm_unreachable("Unhandled architecture");
813 }
814 
816  StringRef ArchName =
818 
819  if (TT.isOSBinFormatMachO()) {
820  if (TT.getEnvironment() == Triple::EABI ||
821  TT.getOS() == Triple::UnknownOS ||
823  return "aapcs";
824  if (TT.isWatchABI())
825  return "aapcs16";
826  return "apcs-gnu";
827  } else if (TT.isOSWindows())
828  // FIXME: this is invalid for WindowsCE.
829  return "aapcs";
830 
831  // Select the default based on the platform.
832  switch (TT.getEnvironment()) {
833  case Triple::Android:
834  case Triple::GNUEABI:
835  case Triple::GNUEABIHF:
836  case Triple::MuslEABI:
837  case Triple::MuslEABIHF:
838  return "aapcs-linux";
839  case Triple::EABIHF:
840  case Triple::EABI:
841  return "aapcs";
842  default:
843  if (TT.isOSNetBSD())
844  return "apcs-gnu";
845  if (TT.isOSOpenBSD())
846  return "aapcs-linux";
847  return "aapcs";
848  }
849 }
850 
852  return ARM::getCanonicalArchName(Arch);
853 }
854 
855 unsigned llvm::AArch64::parseFPU(StringRef FPU) {
856  return ARM::parseFPU(FPU);
857 }
858 
859 // Allows partial match, ex. "v8a" matches "armv8a".
861  Arch = getCanonicalArchName(Arch);
862  if (checkArchVersion(Arch) < 8)
863  return ArchKind::INVALID;
864 
865  StringRef Syn = getArchSynonym(Arch);
866  for (const auto A : AArch64ARCHNames) {
867  if (A.getName().endswith(Syn))
868  return A.ID;
869  }
870  return ArchKind::INVALID;
871 }
872 
873 unsigned llvm::AArch64::parseArchExt(StringRef ArchExt) {
874  for (const auto A : AArch64ARCHExtNames) {
875  if (ArchExt == A.getName())
876  return A.ID;
877  }
878  return AArch64::AEK_INVALID;
879 }
880 
882  for (const auto C : AArch64CPUNames) {
883  if (CPU == C.getName())
884  return C.ArchID;
885  }
886  return ArchKind::INVALID;
887 }
888 
889 // ARM, Thumb, AArch64
891  return ARM::parseArchISA(Arch);
892 }
893 
894 // Little/Big endian
896  return ARM::parseArchEndian(Arch);
897 }
898 
899 // Profile A/R/M
901  return ARM::parseArchProfile(Arch);
902 }
903 
904 // Version number (ex. v8 = 8).
906  return ARM::parseArchVersion(Arch);
907 }
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)
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)
unsigned parseArchExt(StringRef ArchExt)
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
static const struct @364 Extensions[]
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:220
Only 16 D registers.
#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)
unsigned parseArchExt(StringRef ArchExt)
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)
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:235
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
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)