LLVM  3.7.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 <cctype>
20 
21 using namespace llvm;
22 
23 namespace {
24 
25 // List of canonical FPU names (use getFPUSynonym) and which architectural
26 // features they correspond to (use getFPUFeatures).
27 // FIXME: TableGen this.
28 // The entries must appear in the order listed in ARM::FPUKind for correct indexing
29 struct {
30  const char * Name;
33  ARM::NeonSupportLevel NeonSupport;
34  ARM::FPURestriction Restriction;
35 } FPUNames[] = {
56  { "crypto-neon-fp-armv8",
59 };
60 
61 // List of canonical arch names (use getArchSynonym).
62 // This table also provides the build attribute fields for CPU arch
63 // and Arch ID, according to the Addenda to the ARM ABI, chapters
64 // 2.4 and 2.3.5.2 respectively.
65 // FIXME: SubArch values were simplified to fit into the expectations
66 // of the triples and are not conforming with their official names.
67 // Check to see if the expectation should be changed.
68 // FIXME: TableGen this.
69 struct {
70  const char *Name;
72  const char *CPUAttr; // CPU class in build attributes.
73  const char *SubArch; // Sub-Arch name.
74  ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
75 } ARCHNames[] = {
76  { "invalid", ARM::AK_INVALID, nullptr, nullptr, ARMBuildAttrs::CPUArch::Pre_v4 },
77  { "armv2", ARM::AK_ARMV2, "2", "v2", ARMBuildAttrs::CPUArch::Pre_v4 },
78  { "armv2a", ARM::AK_ARMV2A, "2A", "v2a", ARMBuildAttrs::CPUArch::Pre_v4 },
79  { "armv3", ARM::AK_ARMV3, "3", "v3", ARMBuildAttrs::CPUArch::Pre_v4 },
80  { "armv3m", ARM::AK_ARMV3M, "3M", "v3m", ARMBuildAttrs::CPUArch::Pre_v4 },
81  { "armv4", ARM::AK_ARMV4, "4", "v4", ARMBuildAttrs::CPUArch::v4 },
82  { "armv4t", ARM::AK_ARMV4T, "4T", "v4t", ARMBuildAttrs::CPUArch::v4T },
83  { "armv5t", ARM::AK_ARMV5T, "5T", "v5", ARMBuildAttrs::CPUArch::v5T },
84  { "armv5te", ARM::AK_ARMV5TE, "5TE", "v5e", ARMBuildAttrs::CPUArch::v5TE },
85  { "armv5tej", ARM::AK_ARMV5TEJ, "5TEJ", "v5e", ARMBuildAttrs::CPUArch::v5TEJ },
86  { "armv6", ARM::AK_ARMV6, "6", "v6", ARMBuildAttrs::CPUArch::v6 },
87  { "armv6k", ARM::AK_ARMV6K, "6K", "v6k", ARMBuildAttrs::CPUArch::v6K },
88  { "armv6t2", ARM::AK_ARMV6T2, "6T2", "v6t2", ARMBuildAttrs::CPUArch::v6T2 },
89  { "armv6z", ARM::AK_ARMV6Z, "6Z", "v6z", ARMBuildAttrs::CPUArch::v6KZ },
90  { "armv6zk", ARM::AK_ARMV6ZK, "6ZK", "v6zk", ARMBuildAttrs::CPUArch::v6KZ },
91  { "armv6-m", ARM::AK_ARMV6M, "6-M", "v6m", ARMBuildAttrs::CPUArch::v6_M },
92  { "armv6s-m", ARM::AK_ARMV6SM, "6S-M", "v6sm", ARMBuildAttrs::CPUArch::v6S_M },
93  { "armv7-a", ARM::AK_ARMV7A, "7-A", "v7", ARMBuildAttrs::CPUArch::v7 },
94  { "armv7-r", ARM::AK_ARMV7R, "7-R", "v7r", ARMBuildAttrs::CPUArch::v7 },
95  { "armv7-m", ARM::AK_ARMV7M, "7-M", "v7m", ARMBuildAttrs::CPUArch::v7 },
96  { "armv7e-m", ARM::AK_ARMV7EM, "7E-M", "v7em", ARMBuildAttrs::CPUArch::v7E_M },
97  { "armv8-a", ARM::AK_ARMV8A, "8-A", "v8", ARMBuildAttrs::CPUArch::v8 },
98  { "armv8.1-a", ARM::AK_ARMV8_1A, "8.1-A", "v8.1a", ARMBuildAttrs::CPUArch::v8 },
99  // Non-standard Arch names.
100  { "iwmmxt", ARM::AK_IWMMXT, "iwmmxt", "", ARMBuildAttrs::CPUArch::v5TE },
101  { "iwmmxt2", ARM::AK_IWMMXT2, "iwmmxt2", "", ARMBuildAttrs::CPUArch::v5TE },
102  { "xscale", ARM::AK_XSCALE, "xscale", "", ARMBuildAttrs::CPUArch::v5TE },
103  { "armv5", ARM::AK_ARMV5, "5T", "v5", ARMBuildAttrs::CPUArch::v5T },
104  { "armv5e", ARM::AK_ARMV5E, "5TE", "v5e", ARMBuildAttrs::CPUArch::v5TE },
105  { "armv6j", ARM::AK_ARMV6J, "6J", "v6", ARMBuildAttrs::CPUArch::v6 },
106  { "armv6hl", ARM::AK_ARMV6HL, "6-M", "v6hl", ARMBuildAttrs::CPUArch::v6_M },
107  { "armv7", ARM::AK_ARMV7, "7", "v7", ARMBuildAttrs::CPUArch::v7 },
108  { "armv7l", ARM::AK_ARMV7L, "7-L", "v7l", ARMBuildAttrs::CPUArch::v7 },
109  { "armv7hl", ARM::AK_ARMV7HL, "7-L", "v7hl", ARMBuildAttrs::CPUArch::v7 },
110  { "armv7s", ARM::AK_ARMV7S, "7-S", "v7s", ARMBuildAttrs::CPUArch::v7 }
111 };
112 // List of Arch Extension names.
113 // FIXME: TableGen this.
114 struct {
115  const char *Name;
117 } ARCHExtNames[] = {
118  { "invalid", ARM::AEK_INVALID },
119  { "crc", ARM::AEK_CRC },
120  { "crypto", ARM::AEK_CRYPTO },
121  { "fp", ARM::AEK_FP },
122  { "idiv", ARM::AEK_HWDIV },
123  { "mp", ARM::AEK_MP },
124  { "simd", ARM::AEK_SIMD },
125  { "sec", ARM::AEK_SEC },
126  { "virt", ARM::AEK_VIRT },
127  { "os", ARM::AEK_OS },
128  { "iwmmxt", ARM::AEK_IWMMXT },
129  { "iwmmxt2", ARM::AEK_IWMMXT2 },
130  { "maverick", ARM::AEK_MAVERICK },
131  { "xscale", ARM::AEK_XSCALE }
132 };
133 // List of CPU names and their arches.
134 // The same CPU can have multiple arches and can be default on multiple arches.
135 // When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
136 // When this becomes table-generated, we'd probably need two tables.
137 // FIXME: TableGen this.
138 struct {
139  const char *Name;
140  ARM::ArchKind ArchID;
141  bool Default;
142 } CPUNames[] = {
143  { "arm2", ARM::AK_ARMV2, true },
144  { "arm3", ARM::AK_ARMV2A, true },
145  { "arm6", ARM::AK_ARMV3, true },
146  { "arm7m", ARM::AK_ARMV3M, true },
147  { "arm8", ARM::AK_ARMV4, false },
148  { "arm810", ARM::AK_ARMV4, false },
149  { "strongarm", ARM::AK_ARMV4, true },
150  { "strongarm110", ARM::AK_ARMV4, false },
151  { "strongarm1100", ARM::AK_ARMV4, false },
152  { "strongarm1110", ARM::AK_ARMV4, false },
153  { "arm7tdmi", ARM::AK_ARMV4T, true },
154  { "arm7tdmi-s", ARM::AK_ARMV4T, false },
155  { "arm710t", ARM::AK_ARMV4T, false },
156  { "arm720t", ARM::AK_ARMV4T, false },
157  { "arm9", ARM::AK_ARMV4T, false },
158  { "arm9tdmi", ARM::AK_ARMV4T, false },
159  { "arm920", ARM::AK_ARMV4T, false },
160  { "arm920t", ARM::AK_ARMV4T, false },
161  { "arm922t", ARM::AK_ARMV4T, false },
162  { "arm9312", ARM::AK_ARMV4T, false },
163  { "arm940t", ARM::AK_ARMV4T, false },
164  { "ep9312", ARM::AK_ARMV4T, false },
165  { "arm10tdmi", ARM::AK_ARMV5T, true },
166  { "arm1020t", ARM::AK_ARMV5T, false },
167  { "arm9e", ARM::AK_ARMV5TE, false },
168  { "arm946e-s", ARM::AK_ARMV5TE, false },
169  { "arm966e-s", ARM::AK_ARMV5TE, false },
170  { "arm968e-s", ARM::AK_ARMV5TE, false },
171  { "arm10e", ARM::AK_ARMV5TE, false },
172  { "arm1020e", ARM::AK_ARMV5TE, false },
173  { "arm1022e", ARM::AK_ARMV5TE, true },
174  { "iwmmxt", ARM::AK_ARMV5TE, false },
175  { "xscale", ARM::AK_ARMV5TE, false },
176  { "arm926ej-s", ARM::AK_ARMV5TEJ, true },
177  { "arm1136jf-s", ARM::AK_ARMV6, true },
178  { "arm1176j-s", ARM::AK_ARMV6K, false },
179  { "arm1176jz-s", ARM::AK_ARMV6K, false },
180  { "mpcore", ARM::AK_ARMV6K, false },
181  { "mpcorenovfp", ARM::AK_ARMV6K, false },
182  { "arm1176jzf-s", ARM::AK_ARMV6K, true },
183  { "arm1176jzf-s", ARM::AK_ARMV6Z, true },
184  { "arm1176jzf-s", ARM::AK_ARMV6ZK, true },
185  { "arm1156t2-s", ARM::AK_ARMV6T2, true },
186  { "arm1156t2f-s", ARM::AK_ARMV6T2, false },
187  { "cortex-m0", ARM::AK_ARMV6M, true },
188  { "cortex-m0plus", ARM::AK_ARMV6M, false },
189  { "cortex-m1", ARM::AK_ARMV6M, false },
190  { "sc000", ARM::AK_ARMV6M, false },
191  { "cortex-a5", ARM::AK_ARMV7A, false },
192  { "cortex-a7", ARM::AK_ARMV7A, false },
193  { "cortex-a8", ARM::AK_ARMV7A, true },
194  { "cortex-a9", ARM::AK_ARMV7A, false },
195  { "cortex-a12", ARM::AK_ARMV7A, false },
196  { "cortex-a15", ARM::AK_ARMV7A, false },
197  { "cortex-a17", ARM::AK_ARMV7A, false },
198  { "krait", ARM::AK_ARMV7A, false },
199  { "cortex-r4", ARM::AK_ARMV7R, true },
200  { "cortex-r4f", ARM::AK_ARMV7R, false },
201  { "cortex-r5", ARM::AK_ARMV7R, false },
202  { "cortex-r7", ARM::AK_ARMV7R, false },
203  { "sc300", ARM::AK_ARMV7M, false },
204  { "cortex-m3", ARM::AK_ARMV7M, true },
205  { "cortex-m4", ARM::AK_ARMV7EM, true },
206  { "cortex-m7", ARM::AK_ARMV7EM, false },
207  { "cortex-a53", ARM::AK_ARMV8A, true },
208  { "cortex-a57", ARM::AK_ARMV8A, false },
209  { "cortex-a72", ARM::AK_ARMV8A, false },
210  { "cyclone", ARM::AK_ARMV8A, false },
211  { "generic", ARM::AK_ARMV8_1A, true },
212  // Non-standard Arch names.
213  { "iwmmxt", ARM::AK_IWMMXT, true },
214  { "xscale", ARM::AK_XSCALE, true },
215  { "arm10tdmi", ARM::AK_ARMV5, true },
216  { "arm1022e", ARM::AK_ARMV5E, true },
217  { "arm1136j-s", ARM::AK_ARMV6J, true },
218  { "arm1136jz-s", ARM::AK_ARMV6J, false },
219  { "cortex-m0", ARM::AK_ARMV6SM, true },
220  { "arm1176jzf-s", ARM::AK_ARMV6HL, true },
221  { "cortex-a8", ARM::AK_ARMV7, true },
222  { "cortex-a8", ARM::AK_ARMV7L, true },
223  { "cortex-a8", ARM::AK_ARMV7HL, true },
224  { "cortex-m4", ARM::AK_ARMV7EM, true },
225  { "swift", ARM::AK_ARMV7S, true },
226  // Invalid CPU
227  { "invalid", ARM::AK_INVALID, true }
228 };
229 
230 } // namespace
231 
232 // ======================================================= //
233 // Information by ID
234 // ======================================================= //
235 
236 const char *ARMTargetParser::getFPUName(unsigned FPUKind) {
237  if (FPUKind >= ARM::FK_LAST)
238  return nullptr;
239  return FPUNames[FPUKind].Name;
240 }
241 
243  if (FPUKind >= ARM::FK_LAST)
244  return 0;
245  return FPUNames[FPUKind].FPUVersion;
246 }
247 
249  if (FPUKind >= ARM::FK_LAST)
250  return 0;
251  return FPUNames[FPUKind].NeonSupport;
252 }
253 
255  if (FPUKind >= ARM::FK_LAST)
256  return 0;
257  return FPUNames[FPUKind].Restriction;
258 }
259 
261  std::vector<const char *> &Features) {
262 
263  if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
264  return false;
265 
266  // fp-only-sp and d16 subtarget features are independent of each other, so we
267  // must enable/disable both.
268  switch (FPUNames[FPUKind].Restriction) {
269  case ARM::FR_SP_D16:
270  Features.push_back("+fp-only-sp");
271  Features.push_back("+d16");
272  break;
273  case ARM::FR_D16:
274  Features.push_back("-fp-only-sp");
275  Features.push_back("+d16");
276  break;
277  case ARM::FR_None:
278  Features.push_back("-fp-only-sp");
279  Features.push_back("-d16");
280  break;
281  }
282 
283  // FPU version subtarget features are inclusive of lower-numbered ones, so
284  // enable the one corresponding to this version and disable all that are
285  // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
286  // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
287  switch (FPUNames[FPUKind].FPUVersion) {
288  case ARM::FV_VFPV5:
289  Features.push_back("+fp-armv8");
290  break;
291  case ARM::FV_VFPV4:
292  Features.push_back("+vfp4");
293  Features.push_back("-fp-armv8");
294  break;
295  case ARM::FV_VFPV3_FP16:
296  Features.push_back("+vfp3");
297  Features.push_back("+fp16");
298  Features.push_back("-vfp4");
299  Features.push_back("-fp-armv8");
300  break;
301  case ARM::FV_VFPV3:
302  Features.push_back("+vfp3");
303  Features.push_back("-fp16");
304  Features.push_back("-vfp4");
305  Features.push_back("-fp-armv8");
306  break;
307  case ARM::FV_VFPV2:
308  Features.push_back("+vfp2");
309  Features.push_back("-vfp3");
310  Features.push_back("-fp16");
311  Features.push_back("-vfp4");
312  Features.push_back("-fp-armv8");
313  break;
314  case ARM::FV_NONE:
315  Features.push_back("-vfp2");
316  Features.push_back("-vfp3");
317  Features.push_back("-fp16");
318  Features.push_back("-vfp4");
319  Features.push_back("-fp-armv8");
320  break;
321  }
322 
323  // crypto includes neon, so we handle this similarly to FPU version.
324  switch (FPUNames[FPUKind].NeonSupport) {
325  case ARM::NS_Crypto:
326  Features.push_back("+crypto");
327  break;
328  case ARM::NS_Neon:
329  Features.push_back("+neon");
330  Features.push_back("-crypto");
331  break;
332  case ARM::NS_None:
333  Features.push_back("-neon");
334  Features.push_back("-crypto");
335  break;
336  }
337 
338  return true;
339 }
340 
341 const char *ARMTargetParser::getArchName(unsigned ArchKind) {
342  if (ArchKind >= ARM::AK_LAST)
343  return nullptr;
344  return ARCHNames[ArchKind].Name;
345 }
346 
347 const char *ARMTargetParser::getCPUAttr(unsigned ArchKind) {
348  if (ArchKind >= ARM::AK_LAST)
349  return nullptr;
350  return ARCHNames[ArchKind].CPUAttr;
351 }
352 
353 const char *ARMTargetParser::getSubArch(unsigned ArchKind) {
354  if (ArchKind >= ARM::AK_LAST)
355  return nullptr;
356  return ARCHNames[ArchKind].SubArch;
357 }
358 
360  if (ArchKind >= ARM::AK_LAST)
362  return ARCHNames[ArchKind].ArchAttr;
363 }
364 
366  if (ArchExtKind >= ARM::AEK_LAST)
367  return nullptr;
368  return ARCHExtNames[ArchExtKind].Name;
369 }
370 
372  unsigned AK = parseArch(Arch);
373  if (AK == ARM::AK_INVALID)
374  return nullptr;
375 
376  // Look for multiple AKs to find the default for pair AK+Name.
377  for (const auto CPU : CPUNames) {
378  if (CPU.ArchID == AK && CPU.Default)
379  return CPU.Name;
380  }
381  return nullptr;
382 }
383 
384 // ======================================================= //
385 // Parsers
386 // ======================================================= //
387 
388 StringRef ARMTargetParser::getFPUSynonym(StringRef FPU) {
389  return StringSwitch<StringRef>(FPU)
390  .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
391  .Case("vfp2", "vfpv2")
392  .Case("vfp3", "vfpv3")
393  .Case("vfp4", "vfpv4")
394  .Case("vfp3-d16", "vfpv3-d16")
395  .Case("vfp4-d16", "vfpv4-d16")
396  .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
397  .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
398  .Case("fp5-sp-d16", "fpv5-sp-d16")
399  .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
400  // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
401  .Case("neon-vfpv3", "neon")
402  .Default(FPU);
403 }
404 
405 StringRef ARMTargetParser::getArchSynonym(StringRef Arch) {
406  return StringSwitch<StringRef>(Arch)
407  .Case("v6sm", "v6s-m")
408  .Case("v6m", "v6-m")
409  .Case("v7a", "v7-a")
410  .Case("v7r", "v7-r")
411  .Case("v7m", "v7-m")
412  .Case("v7em", "v7e-m")
413  .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
414  .Case("v8.1a", "v8.1-a")
415  .Default(Arch);
416 }
417 
418 // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
419 // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
420 // "v.+", if the latter, return unmodified string, minus 'eb'.
421 // If invalid, return empty string.
423  size_t offset = StringRef::npos;
424  StringRef A = Arch;
425  StringRef Error = "";
426 
427  // Begins with "arm" / "thumb", move past it.
428  if (A.startswith("arm64"))
429  offset = 5;
430  else if (A.startswith("arm"))
431  offset = 3;
432  else if (A.startswith("thumb"))
433  offset = 5;
434  else if (A.startswith("aarch64")) {
435  offset = 7;
436  // AArch64 uses "_be", not "eb" suffix.
437  if (A.find("eb") != StringRef::npos)
438  return Error;
439  if (A.substr(offset,3) == "_be")
440  offset += 3;
441  }
442 
443  // Ex. "armebv7", move past the "eb".
444  if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
445  offset += 2;
446  // Or, if it ends with eb ("armv7eb"), chop it off.
447  else if (A.endswith("eb"))
448  A = A.substr(0, A.size() - 2);
449  // Trim the head
450  if (offset != StringRef::npos)
451  A = A.substr(offset);
452 
453  // Empty string means offset reached the end, which means it's valid.
454  if (A.empty())
455  return Arch;
456 
457  // Only match non-marketing names
458  if (offset != StringRef::npos) {
459  // Must start with 'vN'.
460  if (A[0] != 'v' || !std::isdigit(A[1]))
461  return Error;
462  // Can't have an extra 'eb'.
463  if (A.find("eb") != StringRef::npos)
464  return Error;
465  }
466 
467  // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
468  return A;
469 }
470 
472  StringRef Syn = getFPUSynonym(FPU);
473  for (const auto F : FPUNames) {
474  if (Syn == F.Name)
475  return F.ID;
476  }
477  return ARM::FK_INVALID;
478 }
479 
480 // Allows partial match, ex. "v7a" matches "armv7a".
482  Arch = getCanonicalArchName(Arch);
483  StringRef Syn = getArchSynonym(Arch);
484  for (const auto A : ARCHNames) {
485  if (StringRef(A.Name).endswith(Syn))
486  return A.ID;
487  }
488  return ARM::AK_INVALID;
489 }
490 
492  for (const auto A : ARCHExtNames) {
493  if (ArchExt == A.Name)
494  return A.ID;
495  }
496  return ARM::AEK_INVALID;
497 }
498 
500  for (const auto C : CPUNames) {
501  if (CPU == C.Name)
502  return C.ArchID;
503  }
504  return ARM::AK_INVALID;
505 }
506 
507 // ARM, Thumb, AArch64
509  return StringSwitch<unsigned>(Arch)
510  .StartsWith("aarch64", ARM::IK_AARCH64)
511  .StartsWith("arm64", ARM::IK_AARCH64)
512  .StartsWith("thumb", ARM::IK_THUMB)
513  .StartsWith("arm", ARM::IK_ARM)
515 }
516 
517 // Little/Big endian
519  if (Arch.startswith("armeb") ||
520  Arch.startswith("thumbeb") ||
521  Arch.startswith("aarch64_be"))
522  return ARM::EK_BIG;
523 
524  if (Arch.startswith("arm") || Arch.startswith("thumb")) {
525  if (Arch.endswith("eb"))
526  return ARM::EK_BIG;
527  else
528  return ARM::EK_LITTLE;
529  }
530 
531  if (Arch.startswith("aarch64"))
532  return ARM::EK_LITTLE;
533 
534  return ARM::EK_INVALID;
535 }
536 
537 // Profile A/R/M
539  Arch = getCanonicalArchName(Arch);
540  switch(parseArch(Arch)) {
541  case ARM::AK_ARMV6M:
542  case ARM::AK_ARMV7M:
543  case ARM::AK_ARMV6SM:
544  case ARM::AK_ARMV7EM:
545  return ARM::PK_M;
546  case ARM::AK_ARMV7R:
547  return ARM::PK_R;
548  case ARM::AK_ARMV7:
549  case ARM::AK_ARMV7A:
550  case ARM::AK_ARMV8A:
551  case ARM::AK_ARMV8_1A:
552  return ARM::PK_A;
553  }
554  return ARM::PK_INVALID;
555 }
556 
557 // Version number (ex. v7 = 7).
559  Arch = getCanonicalArchName(Arch);
560  switch(parseArch(Arch)) {
561  case ARM::AK_ARMV2:
562  case ARM::AK_ARMV2A:
563  return 2;
564  case ARM::AK_ARMV3:
565  case ARM::AK_ARMV3M:
566  return 3;
567  case ARM::AK_ARMV4:
568  case ARM::AK_ARMV4T:
569  return 4;
570  case ARM::AK_ARMV5:
571  case ARM::AK_ARMV5T:
572  case ARM::AK_ARMV5TE:
573  case ARM::AK_IWMMXT:
574  case ARM::AK_IWMMXT2:
575  case ARM::AK_XSCALE:
576  case ARM::AK_ARMV5E:
577  case ARM::AK_ARMV5TEJ:
578  return 5;
579  case ARM::AK_ARMV6:
580  case ARM::AK_ARMV6J:
581  case ARM::AK_ARMV6K:
582  case ARM::AK_ARMV6T2:
583  case ARM::AK_ARMV6Z:
584  case ARM::AK_ARMV6ZK:
585  case ARM::AK_ARMV6M:
586  case ARM::AK_ARMV6SM:
587  case ARM::AK_ARMV6HL:
588  return 6;
589  case ARM::AK_ARMV7:
590  case ARM::AK_ARMV7A:
591  case ARM::AK_ARMV7R:
592  case ARM::AK_ARMV7M:
593  case ARM::AK_ARMV7L:
594  case ARM::AK_ARMV7HL:
595  case ARM::AK_ARMV7S:
596  case ARM::AK_ARMV7EM:
597  return 7;
598  case ARM::AK_ARMV8A:
599  case ARM::AK_ARMV8_1A:
600  return 8;
601  }
602  return 0;
603 }
static unsigned getFPUVersion(unsigned FPUKind)
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
static unsigned parseCPUArch(StringRef CPU)
static unsigned parseArch(StringRef Arch)
static unsigned parseArchExt(StringRef ArchExt)
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:240
bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:224
static const char * getSubArch(unsigned ArchKind)
const FeatureBitset Features
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:405
F(f)
StringSwitch & Case(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:55
static unsigned parseFPU(StringRef FPU)
static bool getFPUFeatures(unsigned FPUKind, std::vector< const char * > &Features)
Only single-precision instructions, with 16 D registers.
Definition: TargetParser.h:80
Only 16 D registers.
Definition: TargetParser.h:79
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
static const char * getDefaultCPU(StringRef Arch)
static unsigned getArchAttr(unsigned ArchKind)
static unsigned parseArchVersion(StringRef Arch)
static const char * getCPUAttr(unsigned ArchKind)
static unsigned getFPUNeonSupportLevel(unsigned FPUKind)
StringSwitch & StartsWith(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:75
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:215
static unsigned parseArchEndian(StringRef Arch)
static const char * getFPUName(unsigned FPUKind)
Neon with Crypto.
Definition: TargetParser.h:73
R Default(const T &Value) const
Definition: StringSwitch.h:111
static const char * getArchExtName(unsigned ArchExtKind)
static const size_t npos
Definition: StringRef.h:44
No restriction.
Definition: TargetParser.h:78
static unsigned parseArchProfile(StringRef Arch)
static unsigned parseArchISA(StringRef Arch)
static const char * getArchName(unsigned ArchKind)
static unsigned getFPURestriction(unsigned FPUKind)
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const T &Value)
Definition: StringSwitch.h:85
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
static StringRef getCanonicalArchName(StringRef Arch)
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110