LLVM  4.0.0
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, 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, 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 
162 unsigned llvm::ARM::getFPUVersion(unsigned FPUKind) {
163  if (FPUKind >= ARM::FK_LAST)
164  return 0;
165  return FPUNames[FPUKind].FPUVersion;
166 }
167 
169  if (FPUKind >= ARM::FK_LAST)
170  return 0;
171  return FPUNames[FPUKind].NeonSupport;
172 }
173 
175  if (FPUKind >= ARM::FK_LAST)
176  return 0;
177  return FPUNames[FPUKind].Restriction;
178 }
179 
180 unsigned llvm::ARM::getDefaultFPU(StringRef CPU, unsigned ArchKind) {
181  if (CPU == "generic")
182  return ARCHNames[ArchKind].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[ArchKind].ArchBaseExtensions;
194 
195  return StringSwitch<unsigned>(CPU)
196 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
197  .Case(NAME, ARCHNames[ID].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_HWDIV)
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  return getHWDivFeatures(Extensions, Features);
238 }
239 
241  std::vector<StringRef> &Features) {
242 
243  if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
244  return false;
245 
246  // fp-only-sp and d16 subtarget features are independent of each other, so we
247  // must enable/disable both.
248  switch (FPUNames[FPUKind].Restriction) {
249  case ARM::FR_SP_D16:
250  Features.push_back("+fp-only-sp");
251  Features.push_back("+d16");
252  break;
253  case ARM::FR_D16:
254  Features.push_back("-fp-only-sp");
255  Features.push_back("+d16");
256  break;
257  case ARM::FR_None:
258  Features.push_back("-fp-only-sp");
259  Features.push_back("-d16");
260  break;
261  }
262 
263  // FPU version subtarget features are inclusive of lower-numbered ones, so
264  // enable the one corresponding to this version and disable all that are
265  // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
266  // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
267  switch (FPUNames[FPUKind].FPUVersion) {
268  case ARM::FV_VFPV5:
269  Features.push_back("+fp-armv8");
270  break;
271  case ARM::FV_VFPV4:
272  Features.push_back("+vfp4");
273  Features.push_back("-fp-armv8");
274  break;
275  case ARM::FV_VFPV3_FP16:
276  Features.push_back("+vfp3");
277  Features.push_back("+fp16");
278  Features.push_back("-vfp4");
279  Features.push_back("-fp-armv8");
280  break;
281  case ARM::FV_VFPV3:
282  Features.push_back("+vfp3");
283  Features.push_back("-fp16");
284  Features.push_back("-vfp4");
285  Features.push_back("-fp-armv8");
286  break;
287  case ARM::FV_VFPV2:
288  Features.push_back("+vfp2");
289  Features.push_back("-vfp3");
290  Features.push_back("-fp16");
291  Features.push_back("-vfp4");
292  Features.push_back("-fp-armv8");
293  break;
294  case ARM::FV_NONE:
295  Features.push_back("-vfp2");
296  Features.push_back("-vfp3");
297  Features.push_back("-fp16");
298  Features.push_back("-vfp4");
299  Features.push_back("-fp-armv8");
300  break;
301  }
302 
303  // crypto includes neon, so we handle this similarly to FPU version.
304  switch (FPUNames[FPUKind].NeonSupport) {
305  case ARM::NS_Crypto:
306  Features.push_back("+neon");
307  Features.push_back("+crypto");
308  break;
309  case ARM::NS_Neon:
310  Features.push_back("+neon");
311  Features.push_back("-crypto");
312  break;
313  case ARM::NS_None:
314  Features.push_back("-neon");
315  Features.push_back("-crypto");
316  break;
317  }
318 
319  return true;
320 }
321 
323  if (ArchKind >= ARM::AK_LAST)
324  return StringRef();
325  return ARCHNames[ArchKind].getName();
326 }
327 
329  if (ArchKind == ARM::AK_INVALID || ArchKind >= ARM::AK_LAST)
330  return StringRef();
331  return ARCHNames[ArchKind].getCPUAttr();
332 }
333 
335  if (ArchKind == ARM::AK_INVALID || ArchKind >= ARM::AK_LAST)
336  return StringRef();
337  return ARCHNames[ArchKind].getSubArch();
338 }
339 
340 unsigned llvm::ARM::getArchAttr(unsigned ArchKind) {
341  if (ArchKind >= ARM::AK_LAST)
343  return ARCHNames[ArchKind].ArchAttr;
344 }
345 
347  for (const auto AE : ARCHExtNames) {
348  if (ArchExtKind == AE.ID)
349  return AE.getName();
350  }
351  return StringRef();
352 }
353 
355  if (ArchExt.startswith("no")) {
356  StringRef ArchExtBase(ArchExt.substr(2));
357  for (const auto AE : ARCHExtNames) {
358  if (AE.NegFeature && ArchExtBase == AE.getName())
359  return StringRef(AE.NegFeature);
360  }
361  }
362  for (const auto AE : ARCHExtNames) {
363  if (AE.Feature && ArchExt == AE.getName())
364  return StringRef(AE.Feature);
365  }
366 
367  return StringRef();
368 }
369 
370 StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
371  for (const auto D : HWDivNames) {
372  if (HWDivKind == D.ID)
373  return D.getName();
374  }
375  return StringRef();
376 }
377 
379  unsigned AK = parseArch(Arch);
380  if (AK == ARM::AK_INVALID)
381  return StringRef();
382 
383  // Look for multiple AKs to find the default for pair AK+Name.
384  for (const auto CPU : CPUNames) {
385  if (CPU.ArchID == AK && CPU.Default)
386  return CPU.getName();
387  }
388 
389  // If we can't find a default then target the architecture instead
390  return "generic";
391 }
392 
394  return ARM::getFPUName(FPUKind);
395 }
396 
397 unsigned llvm::AArch64::getFPUVersion(unsigned FPUKind) {
398  return ARM::getFPUVersion(FPUKind);
399 }
400 
402  return ARM::getFPUNeonSupportLevel( FPUKind);
403 }
404 
405 unsigned llvm::AArch64::getFPURestriction(unsigned FPUKind) {
406  return ARM::getFPURestriction(FPUKind);
407 }
408 
409 unsigned llvm::AArch64::getDefaultFPU(StringRef CPU, unsigned ArchKind) {
410  if (CPU == "generic")
411  return AArch64ARCHNames[ArchKind].DefaultFPU;
412 
413  return StringSwitch<unsigned>(CPU)
414 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
415  .Case(NAME, DEFAULT_FPU)
416 #include "llvm/Support/AArch64TargetParser.def"
417  .Default(ARM::FK_INVALID);
418 }
419 
420 unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, unsigned ArchKind) {
421  if (CPU == "generic")
422  return AArch64ARCHNames[ArchKind].ArchBaseExtensions;
423 
424  return StringSwitch<unsigned>(CPU)
425 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
426  .Case(NAME, DEFAULT_EXT)
427 #include "llvm/Support/AArch64TargetParser.def"
428  .Default(AArch64::AEK_INVALID);
429 }
430 
432  std::vector<StringRef> &Features) {
433 
434  if (Extensions == AArch64::AEK_INVALID)
435  return false;
436 
437  if (Extensions & AArch64::AEK_FP)
438  Features.push_back("+fp-armv8");
439  if (Extensions & AArch64::AEK_SIMD)
440  Features.push_back("+neon");
441  if (Extensions & AArch64::AEK_CRC)
442  Features.push_back("+crc");
443  if (Extensions & AArch64::AEK_CRYPTO)
444  Features.push_back("+crypto");
445  if (Extensions & AArch64::AEK_FP16)
446  Features.push_back("+fullfp16");
447  if (Extensions & AArch64::AEK_PROFILE)
448  Features.push_back("+spe");
449  if (Extensions & AArch64::AEK_RAS)
450  Features.push_back("+ras");
451 
452  return true;
453 }
454 
456  std::vector<StringRef> &Features) {
457  return ARM::getFPUFeatures(FPUKind, Features);
458 }
459 
460 bool llvm::AArch64::getArchFeatures(unsigned ArchKind,
461  std::vector<StringRef> &Features) {
462  if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_ARMV8_1A))
463  Features.push_back("+v8.1a");
464  if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_ARMV8_2A))
465  Features.push_back("+v8.2a");
466 
467  return ArchKind > static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) &&
468  ArchKind < static_cast<unsigned>(AArch64::ArchKind::AK_LAST);
469 }
470 
471 StringRef llvm::AArch64::getArchName(unsigned ArchKind) {
472  if (ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
473  return StringRef();
474  return AArch64ARCHNames[ArchKind].getName();
475 }
476 
477 StringRef llvm::AArch64::getCPUAttr(unsigned ArchKind) {
478  if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
479  ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
480  return StringRef();
481  return AArch64ARCHNames[ArchKind].getCPUAttr();
482 }
483 
484 StringRef llvm::AArch64::getSubArch(unsigned ArchKind) {
485  if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
486  ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
487  return StringRef();
488  return AArch64ARCHNames[ArchKind].getSubArch();
489 }
490 
491 unsigned llvm::AArch64::getArchAttr(unsigned ArchKind) {
492  if (ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
494  return AArch64ARCHNames[ArchKind].ArchAttr;
495 }
496 
498  for (const auto &AE : AArch64ARCHExtNames)
499  if (ArchExtKind == AE.ID)
500  return AE.getName();
501  return StringRef();
502 }
503 
505  if (ArchExt.startswith("no")) {
506  StringRef ArchExtBase(ArchExt.substr(2));
507  for (const auto &AE : AArch64ARCHExtNames) {
508  if (AE.NegFeature && ArchExtBase == AE.getName())
509  return StringRef(AE.NegFeature);
510  }
511  }
512 
513  for (const auto &AE : AArch64ARCHExtNames)
514  if (AE.Feature && ArchExt == AE.getName())
515  return StringRef(AE.Feature);
516  return StringRef();
517 }
518 
520  unsigned AK = parseArch(Arch);
521  if (AK == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID))
522  return StringRef();
523 
524  // Look for multiple AKs to find the default for pair AK+Name.
525  for (const auto &CPU : AArch64CPUNames)
526  if (static_cast<unsigned>(CPU.ArchID) == AK && CPU.Default)
527  return CPU.getName();
528 
529  // If we can't find a default then target the architecture instead
530  return "generic";
531 }
532 
534  if (Arch[0] == 'v' && std::isdigit(Arch[1]))
535  return (Arch[1] - 48);
536  return 0;
537 }
538 
539 // ======================================================= //
540 // Parsers
541 // ======================================================= //
542 
544  return StringSwitch<StringRef>(HWDiv)
545  .Case("thumb,arm", "arm,thumb")
546  .Default(HWDiv);
547 }
548 
550  return StringSwitch<StringRef>(FPU)
551  .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
552  .Case("vfp2", "vfpv2")
553  .Case("vfp3", "vfpv3")
554  .Case("vfp4", "vfpv4")
555  .Case("vfp3-d16", "vfpv3-d16")
556  .Case("vfp4-d16", "vfpv4-d16")
557  .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
558  .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
559  .Case("fp5-sp-d16", "fpv5-sp-d16")
560  .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
561  // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
562  .Case("neon-vfpv3", "neon")
563  .Default(FPU);
564 }
565 
567  return StringSwitch<StringRef>(Arch)
568  .Case("v5", "v5t")
569  .Case("v5e", "v5te")
570  .Case("v6j", "v6")
571  .Case("v6hl", "v6k")
572  .Cases("v6m", "v6sm", "v6s-m", "v6-m")
573  .Cases("v6z", "v6zk", "v6kz")
574  .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
575  .Case("v7r", "v7-r")
576  .Case("v7m", "v7-m")
577  .Case("v7em", "v7e-m")
578  .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
579  .Case("v8.1a", "v8.1-a")
580  .Case("v8.2a", "v8.2-a")
581  .Case("v8r", "v8-r")
582  .Case("v8m.base", "v8-m.base")
583  .Case("v8m.main", "v8-m.main")
584  .Default(Arch);
585 }
586 
587 // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
588 // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
589 // "v.+", if the latter, return unmodified string, minus 'eb'.
590 // If invalid, return empty string.
592  size_t offset = StringRef::npos;
593  StringRef A = Arch;
594  StringRef Error = "";
595 
596  // Begins with "arm" / "thumb", move past it.
597  if (A.startswith("arm64"))
598  offset = 5;
599  else if (A.startswith("arm"))
600  offset = 3;
601  else if (A.startswith("thumb"))
602  offset = 5;
603  else if (A.startswith("aarch64")) {
604  offset = 7;
605  // AArch64 uses "_be", not "eb" suffix.
606  if (A.find("eb") != StringRef::npos)
607  return Error;
608  if (A.substr(offset, 3) == "_be")
609  offset += 3;
610  }
611 
612  // Ex. "armebv7", move past the "eb".
613  if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
614  offset += 2;
615  // Or, if it ends with eb ("armv7eb"), chop it off.
616  else if (A.endswith("eb"))
617  A = A.substr(0, A.size() - 2);
618  // Trim the head
619  if (offset != StringRef::npos)
620  A = A.substr(offset);
621 
622  // Empty string means offset reached the end, which means it's valid.
623  if (A.empty())
624  return Arch;
625 
626  // Only match non-marketing names
627  if (offset != StringRef::npos) {
628  // Must start with 'vN'.
629  if (A[0] != 'v' || !std::isdigit(A[1]))
630  return Error;
631  // Can't have an extra 'eb'.
632  if (A.find("eb") != StringRef::npos)
633  return Error;
634  }
635 
636  // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
637  return A;
638 }
639 
641  StringRef Syn = getHWDivSynonym(HWDiv);
642  for (const auto D : HWDivNames) {
643  if (Syn == D.getName())
644  return D.ID;
645  }
646  return ARM::AEK_INVALID;
647 }
648 
650  StringRef Syn = getFPUSynonym(FPU);
651  for (const auto F : FPUNames) {
652  if (Syn == F.getName())
653  return F.ID;
654  }
655  return ARM::FK_INVALID;
656 }
657 
658 // Allows partial match, ex. "v7a" matches "armv7a".
660  Arch = getCanonicalArchName(Arch);
661  StringRef Syn = getArchSynonym(Arch);
662  for (const auto A : ARCHNames) {
663  if (A.getName().endswith(Syn))
664  return A.ID;
665  }
666  return ARM::AK_INVALID;
667 }
668 
670  for (const auto A : ARCHExtNames) {
671  if (ArchExt == A.getName())
672  return A.ID;
673  }
674  return ARM::AEK_INVALID;
675 }
676 
678  for (const auto C : CPUNames) {
679  if (CPU == C.getName())
680  return C.ArchID;
681  }
682  return ARM::AK_INVALID;
683 }
684 
685 // ARM, Thumb, AArch64
687  return StringSwitch<unsigned>(Arch)
688  .StartsWith("aarch64", ARM::IK_AARCH64)
689  .StartsWith("arm64", ARM::IK_AARCH64)
690  .StartsWith("thumb", ARM::IK_THUMB)
691  .StartsWith("arm", ARM::IK_ARM)
693 }
694 
695 // Little/Big endian
697  if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
698  Arch.startswith("aarch64_be"))
699  return ARM::EK_BIG;
700 
701  if (Arch.startswith("arm") || Arch.startswith("thumb")) {
702  if (Arch.endswith("eb"))
703  return ARM::EK_BIG;
704  else
705  return ARM::EK_LITTLE;
706  }
707 
708  if (Arch.startswith("aarch64"))
709  return ARM::EK_LITTLE;
710 
711  return ARM::EK_INVALID;
712 }
713 
714 // Profile A/R/M
716  Arch = getCanonicalArchName(Arch);
717  switch (parseArch(Arch)) {
718  case ARM::AK_ARMV6M:
719  case ARM::AK_ARMV7M:
720  case ARM::AK_ARMV7EM:
721  case ARM::AK_ARMV8MMainline:
722  case ARM::AK_ARMV8MBaseline:
723  return ARM::PK_M;
724  case ARM::AK_ARMV7R:
725  case ARM::AK_ARMV8R:
726  return ARM::PK_R;
727  case ARM::AK_ARMV7A:
728  case ARM::AK_ARMV7K:
729  case ARM::AK_ARMV8A:
730  case ARM::AK_ARMV8_1A:
731  case ARM::AK_ARMV8_2A:
732  return ARM::PK_A;
733  }
734  return ARM::PK_INVALID;
735 }
736 
737 // Version number (ex. v7 = 7).
739  Arch = getCanonicalArchName(Arch);
740  switch (parseArch(Arch)) {
741  case ARM::AK_ARMV2:
742  case ARM::AK_ARMV2A:
743  return 2;
744  case ARM::AK_ARMV3:
745  case ARM::AK_ARMV3M:
746  return 3;
747  case ARM::AK_ARMV4:
748  case ARM::AK_ARMV4T:
749  return 4;
750  case ARM::AK_ARMV5T:
751  case ARM::AK_ARMV5TE:
752  case ARM::AK_IWMMXT:
753  case ARM::AK_IWMMXT2:
754  case ARM::AK_XSCALE:
755  case ARM::AK_ARMV5TEJ:
756  return 5;
757  case ARM::AK_ARMV6:
758  case ARM::AK_ARMV6K:
759  case ARM::AK_ARMV6T2:
760  case ARM::AK_ARMV6KZ:
761  case ARM::AK_ARMV6M:
762  return 6;
763  case ARM::AK_ARMV7A:
764  case ARM::AK_ARMV7R:
765  case ARM::AK_ARMV7M:
766  case ARM::AK_ARMV7S:
767  case ARM::AK_ARMV7EM:
768  case ARM::AK_ARMV7K:
769  return 7;
770  case ARM::AK_ARMV8A:
771  case ARM::AK_ARMV8_1A:
772  case ARM::AK_ARMV8_2A:
773  case ARM::AK_ARMV8R:
774  case ARM::AK_ARMV8MBaseline:
775  case ARM::AK_ARMV8MMainline:
776  return 8;
777  }
778  return 0;
779 }
780 
782  return ARM::getCanonicalArchName(Arch);
783 }
784 
785 unsigned llvm::AArch64::parseFPU(StringRef FPU) {
786  return ARM::parseFPU(FPU);
787 }
788 
789 // Allows partial match, ex. "v8a" matches "armv8a".
790 unsigned llvm::AArch64::parseArch(StringRef Arch) {
791  Arch = getCanonicalArchName(Arch);
792  if (checkArchVersion(Arch) < 8)
793  return static_cast<unsigned>(AArch64::ArchKind::AK_INVALID);
794 
795  StringRef Syn = getArchSynonym(Arch);
796  for (const auto A : AArch64ARCHNames) {
797  if (A.getName().endswith(Syn))
798  return static_cast<unsigned>(A.ID);
799  }
800  return static_cast<unsigned>(AArch64::ArchKind::AK_INVALID);
801 }
802 
803 unsigned llvm::AArch64::parseArchExt(StringRef ArchExt) {
804  for (const auto A : AArch64ARCHExtNames) {
805  if (ArchExt == A.getName())
806  return A.ID;
807  }
808  return AArch64::AEK_INVALID;
809 }
810 
812  for (const auto C : AArch64CPUNames) {
813  if (CPU == C.getName())
814  return static_cast<unsigned>(C.ArchID);
815  }
816  return static_cast<unsigned>(AArch64::ArchKind::AK_INVALID);
817 }
818 
819 // ARM, Thumb, AArch64
820 unsigned llvm::AArch64::parseArchISA(StringRef Arch) {
821  return ARM::parseArchISA(Arch);
822 }
823 
824 // Little/Big endian
826  return ARM::parseArchEndian(Arch);
827 }
828 
829 // Profile A/R/M
831  return ARM::parseArchProfile(Arch);
832 }
833 
834 // Version number (ex. v8 = 8).
836  return ARM::parseArchVersion(Arch);
837 }
unsigned parseArchEndian(StringRef Arch)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:276
unsigned getFPURestriction(unsigned FPUKind)
unsigned parseCPUArch(StringRef CPU)
unsigned checkArchVersion(StringRef Arch)
unsigned getFPUNeonSupportLevel(unsigned FPUKind)
StringRef getArchExtFeature(StringRef ArchExt)
StringRef getDefaultCPU(StringRef Arch)
unsigned parseArchISA(StringRef Arch)
unsigned parseFPU(StringRef FPU)
static StringRef getHWDivSynonym(StringRef HWDiv)
unsigned parseArchProfile(StringRef Arch)
StringRef getArchExtName(unsigned ArchExtKind)
StringRef getFPUName(unsigned FPUKind)
unsigned getArchAttr(unsigned ArchKind)
bool getHWDivFeatures(unsigned HWDivKind, std::vector< StringRef > &Features)
StringRef getArchName(unsigned ArchKind)
StringRef getArchName(unsigned ArchKind)
unsigned parseArchExt(StringRef ArchExt)
StringRef getArchExtName(unsigned ArchExtKind)
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
StringRef getArchExtFeature(StringRef ArchExt)
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
Definition: StringSwitch.h:244
static StringRef getName(Value *V)
bool getExtensionFeatures(unsigned Extensions, std::vector< StringRef > &Features)
unsigned getFPUNeonSupportLevel(unsigned FPUKind)
unsigned parseCPUArch(StringRef CPU)
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:74
static StringRef getArchSynonym(StringRef Arch)
#define F(x, y, z)
Definition: MD5.cpp:51
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:264
unsigned parseArchISA(StringRef Arch)
StringRef getCPUAttr(unsigned ArchKind)
bool getArchFeatures(unsigned ArchKind, std::vector< StringRef > &Features)
uint64_t * Cases
unsigned getDefaultFPU(StringRef CPU, unsigned ArchKind)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
Only single-precision instructions, with 16 D registers.
Definition: TargetParser.h:61
unsigned getFPUVersion(unsigned FPUKind)
Only 16 D registers.
Definition: TargetParser.h:60
unsigned parseArchVersion(StringRef Arch)
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
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:295
StringRef getCanonicalArchName(StringRef Arch)
unsigned parseArchEndian(StringRef Arch)
static const struct @305 Extensions[]
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:587
unsigned getFPUVersion(unsigned FPUKind)
bool getFPUFeatures(unsigned FPUKind, std::vector< StringRef > &Features)
static StringRef getFPUSynonym(StringRef FPU)
bool getExtensionFeatures(unsigned Extensions, std::vector< StringRef > &Features)
bool getFPUFeatures(unsigned FPUKind, std::vector< StringRef > &Features)
unsigned parseArch(StringRef Arch)
#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)
StringRef getHWDivName(unsigned HWDivKind)
Neon with Crypto.
Definition: TargetParser.h:54
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const T &Value)
Definition: StringSwitch.h:107
StringRef getCPUAttr(unsigned ArchKind)
unsigned getArchAttr(unsigned ArchKind)
StringRef getSubArch(unsigned ArchKind)
static const size_t npos
Definition: StringRef.h:51
unsigned parseArchProfile(StringRef Arch)
No restriction.
Definition: TargetParser.h:59
StringRef getSubArch(unsigned ArchKind)
#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)
unsigned parseArchExt(StringRef ArchExt)
unsigned getDefaultExtensions(StringRef CPU, unsigned ArchKind)
unsigned parseArch(StringRef Arch)
unsigned parseFPU(StringRef FPU)
Lightweight error class with error context and mandatory checking.
const FeatureBitset Features
unsigned parseHWDiv(StringRef HWDiv)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
StringRef getCanonicalArchName(StringRef Arch)
unsigned getDefaultFPU(StringRef CPU, unsigned ArchKind)
unsigned getDefaultExtensions(StringRef CPU, unsigned ArchKind)
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & StartsWith(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:96
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
StringRef getDefaultCPU(StringRef Arch)
StringRef getFPUName(unsigned FPUKind)
unsigned getFPURestriction(unsigned FPUKind)
unsigned parseArchVersion(StringRef Arch)