4f5d9acba51973d0da7b34ef900d38e66d3a49f2
[oota-llvm.git] / lib / Support / TargetParser.cpp
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
15 #include "llvm/Support/ARMBuildAttributes.h"
16 #include "llvm/Support/TargetParser.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include <cctype>
20
21 using namespace llvm;
22 using namespace ARM;
23
24 namespace {
25
26 // List of canonical FPU names (use getFPUSynonym) and which architectural
27 // features they correspond to (use getFPUFeatures).
28 // FIXME: TableGen this.
29 // The entries must appear in the order listed in ARM::FPUKind for correct indexing
30 struct {
31   const char *NameCStr;
32   size_t NameLength;
33   ARM::FPUKind ID;
34   ARM::FPUVersion FPUVersion;
35   ARM::NeonSupportLevel NeonSupport;
36   ARM::FPURestriction Restriction;
37
38   StringRef getName() const { return StringRef(NameCStr, NameLength); }
39 } FPUNames[] = {
40 #define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
41   { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION },
42 #include "llvm/Support/ARMTargetParser.def"
43 };
44
45 // List of canonical arch names (use getArchSynonym).
46 // This table also provides the build attribute fields for CPU arch
47 // and Arch ID, according to the Addenda to the ARM ABI, chapters
48 // 2.4 and 2.3.5.2 respectively.
49 // FIXME: SubArch values were simplified to fit into the expectations
50 // of the triples and are not conforming with their official names.
51 // Check to see if the expectation should be changed.
52 // FIXME: TableGen this.
53 struct {
54   const char *NameCStr;
55   size_t NameLength;
56   ARM::ArchKind ID;
57   const char *CPUAttrCStr;
58   size_t CPUAttrLength;
59   const char *SubArchCStr;
60   size_t SubArchLength;
61   ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
62
63   StringRef getName() const { return StringRef(NameCStr, NameLength); }
64
65   // CPU class in build attributes.
66   StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
67
68   // Sub-Arch name.
69   StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
70 } ARCHNames[] = {
71 #define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR)                      \
72   {NAME, sizeof(NAME) - 1, ID, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH,       \
73    sizeof(SUB_ARCH) - 1, ARCH_ATTR},
74 #include "llvm/Support/ARMTargetParser.def"
75 };
76
77 // List of Arch Extension names.
78 // FIXME: TableGen this.
79 struct {
80   const char *NameCStr;
81   size_t NameLength;
82   unsigned ID;
83
84   StringRef getName() const { return StringRef(NameCStr, NameLength); }
85 } ARCHExtNames[] = {
86 #define ARM_ARCH_EXT_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
87 #include "llvm/Support/ARMTargetParser.def"
88 };
89
90 // List of HWDiv names (use getHWDivSynonym) and which architectural
91 // features they correspond to (use getHWDivFeatures).
92 // FIXME: TableGen this.
93 struct {
94   const char *NameCStr;
95   size_t NameLength;
96   unsigned ID;
97
98   StringRef getName() const { return StringRef(NameCStr, NameLength); }
99 } HWDivNames[] = {
100 #define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
101 #include "llvm/Support/ARMTargetParser.def"
102 };
103
104 // List of CPU names and their arches.
105 // The same CPU can have multiple arches and can be default on multiple arches.
106 // When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
107 // When this becomes table-generated, we'd probably need two tables.
108 // FIXME: TableGen this.
109 struct {
110   const char *NameCStr;
111   size_t NameLength;
112   ARM::ArchKind ArchID;
113   bool Default; // is $Name the default CPU for $ArchID ?
114
115   StringRef getName() const { return StringRef(NameCStr, NameLength); }
116 } CPUNames[] = {
117 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT) \
118   { NAME, sizeof(NAME) - 1, ID, IS_DEFAULT },
119 #include "llvm/Support/ARMTargetParser.def"
120 };
121
122 } // namespace
123
124 // ======================================================= //
125 // Information by ID
126 // ======================================================= //
127
128 StringRef llvm::ARM::getFPUName(unsigned FPUKind) {
129   if (FPUKind >= ARM::FK_LAST)
130     return StringRef();
131   return FPUNames[FPUKind].getName();
132 }
133
134 unsigned llvm::ARM::getFPUVersion(unsigned FPUKind) {
135   if (FPUKind >= ARM::FK_LAST)
136     return 0;
137   return FPUNames[FPUKind].FPUVersion;
138 }
139
140 unsigned llvm::ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
141   if (FPUKind >= ARM::FK_LAST)
142     return 0;
143   return FPUNames[FPUKind].NeonSupport;
144 }
145
146 unsigned llvm::ARM::getFPURestriction(unsigned FPUKind) {
147   if (FPUKind >= ARM::FK_LAST)
148     return 0;
149   return FPUNames[FPUKind].Restriction;
150 }
151
152 unsigned llvm::ARM::getDefaultFPU(StringRef CPU) {
153   return StringSwitch<unsigned>(CPU)
154 #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT) \
155     .Case(NAME, DEFAULT_FPU)
156 #include "llvm/Support/ARMTargetParser.def"
157     .Default(ARM::FK_INVALID);
158 }
159
160 bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
161                                  std::vector<const char *> &Features) {
162
163   if (HWDivKind == ARM::AEK_INVALID)
164     return false;
165
166   if (HWDivKind & ARM::AEK_HWDIVARM)
167     Features.push_back("+hwdiv-arm");
168   else
169     Features.push_back("-hwdiv-arm");
170
171   if (HWDivKind & ARM::AEK_HWDIV)
172     Features.push_back("+hwdiv");
173   else
174     Features.push_back("-hwdiv");
175
176   return true;
177 }
178
179 bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
180                                std::vector<const char *> &Features) {
181
182   if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
183     return false;
184
185   // fp-only-sp and d16 subtarget features are independent of each other, so we
186   // must enable/disable both.
187   switch (FPUNames[FPUKind].Restriction) {
188   case ARM::FR_SP_D16:
189     Features.push_back("+fp-only-sp");
190     Features.push_back("+d16");
191     break;
192   case ARM::FR_D16:
193     Features.push_back("-fp-only-sp");
194     Features.push_back("+d16");
195     break;
196   case ARM::FR_None:
197     Features.push_back("-fp-only-sp");
198     Features.push_back("-d16");
199     break;
200   }
201
202   // FPU version subtarget features are inclusive of lower-numbered ones, so
203   // enable the one corresponding to this version and disable all that are
204   // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
205   // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
206   switch (FPUNames[FPUKind].FPUVersion) {
207   case ARM::FV_VFPV5:
208     Features.push_back("+fp-armv8");
209     break;
210   case ARM::FV_VFPV4:
211     Features.push_back("+vfp4");
212     Features.push_back("-fp-armv8");
213     break;
214   case ARM::FV_VFPV3_FP16:
215     Features.push_back("+vfp3");
216     Features.push_back("+fp16");
217     Features.push_back("-vfp4");
218     Features.push_back("-fp-armv8");
219     break;
220   case ARM::FV_VFPV3:
221     Features.push_back("+vfp3");
222     Features.push_back("-fp16");
223     Features.push_back("-vfp4");
224     Features.push_back("-fp-armv8");
225     break;
226   case ARM::FV_VFPV2:
227     Features.push_back("+vfp2");
228     Features.push_back("-vfp3");
229     Features.push_back("-fp16");
230     Features.push_back("-vfp4");
231     Features.push_back("-fp-armv8");
232     break;
233   case ARM::FV_NONE:
234     Features.push_back("-vfp2");
235     Features.push_back("-vfp3");
236     Features.push_back("-fp16");
237     Features.push_back("-vfp4");
238     Features.push_back("-fp-armv8");
239     break;
240   }
241
242   // crypto includes neon, so we handle this similarly to FPU version.
243   switch (FPUNames[FPUKind].NeonSupport) {
244   case ARM::NS_Crypto:
245     Features.push_back("+crypto");
246     break;
247   case ARM::NS_Neon:
248     Features.push_back("+neon");
249     Features.push_back("-crypto");
250     break;
251   case ARM::NS_None:
252     Features.push_back("-neon");
253     Features.push_back("-crypto");
254     break;
255   }
256
257   return true;
258 }
259
260 StringRef llvm::ARM::getArchName(unsigned ArchKind) {
261   if (ArchKind >= ARM::AK_LAST)
262     return StringRef();
263   return ARCHNames[ArchKind].getName();
264 }
265
266 StringRef llvm::ARM::getCPUAttr(unsigned ArchKind) {
267   if (ArchKind >= ARM::AK_LAST)
268     return StringRef();
269   return ARCHNames[ArchKind].getCPUAttr();
270 }
271
272 StringRef llvm::ARM::getSubArch(unsigned ArchKind) {
273   if (ArchKind >= ARM::AK_LAST)
274     return StringRef();
275   return ARCHNames[ArchKind].getSubArch();
276 }
277
278 unsigned llvm::ARM::getArchAttr(unsigned ArchKind) {
279   if (ArchKind >= ARM::AK_LAST)
280     return ARMBuildAttrs::CPUArch::Pre_v4;
281   return ARCHNames[ArchKind].ArchAttr;
282 }
283
284 StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
285   for (const auto AE : ARCHExtNames) {
286     if (ArchExtKind == AE.ID)
287       return AE.getName();
288   }
289   return StringRef();
290 }
291
292 StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
293   for (const auto D : HWDivNames) {
294     if (HWDivKind == D.ID)
295       return D.getName();
296   }
297   return StringRef();
298 }
299
300 StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
301   unsigned AK = parseArch(Arch);
302   if (AK == ARM::AK_INVALID)
303     return StringRef();
304
305   // Look for multiple AKs to find the default for pair AK+Name.
306   for (const auto CPU : CPUNames) {
307     if (CPU.ArchID == AK && CPU.Default)
308       return CPU.getName();
309   }
310   return StringRef();
311 }
312
313 // ======================================================= //
314 // Parsers
315 // ======================================================= //
316
317 static StringRef getHWDivSynonym(StringRef HWDiv) {
318   return StringSwitch<StringRef>(HWDiv)
319       .Case("thumb,arm", "arm,thumb")
320       .Default(HWDiv);
321 }
322
323 static StringRef getFPUSynonym(StringRef FPU) {
324   return StringSwitch<StringRef>(FPU)
325       .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
326       .Case("vfp2", "vfpv2")
327       .Case("vfp3", "vfpv3")
328       .Case("vfp4", "vfpv4")
329       .Case("vfp3-d16", "vfpv3-d16")
330       .Case("vfp4-d16", "vfpv4-d16")
331       .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
332       .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
333       .Case("fp5-sp-d16", "fpv5-sp-d16")
334       .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
335       // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
336       .Case("neon-vfpv3", "neon")
337       .Default(FPU);
338 }
339
340 static StringRef getArchSynonym(StringRef Arch) {
341   return StringSwitch<StringRef>(Arch)
342       .Case("v6sm", "v6s-m")
343       .Case("v6m", "v6-m")
344       .Case("v7a", "v7-a")
345       .Case("v7r", "v7-r")
346       .Case("v7m", "v7-m")
347       .Case("v7em", "v7e-m")
348       .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
349       .Case("v8.1a", "v8.1-a")
350       .Default(Arch);
351 }
352
353 // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
354 // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
355 // "v.+", if the latter, return unmodified string, minus 'eb'.
356 // If invalid, return empty string.
357 StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
358   size_t offset = StringRef::npos;
359   StringRef A = Arch;
360   StringRef Error = "";
361
362   // Begins with "arm" / "thumb", move past it.
363   if (A.startswith("arm64"))
364     offset = 5;
365   else if (A.startswith("arm"))
366     offset = 3;
367   else if (A.startswith("thumb"))
368     offset = 5;
369   else if (A.startswith("aarch64")) {
370     offset = 7;
371     // AArch64 uses "_be", not "eb" suffix.
372     if (A.find("eb") != StringRef::npos)
373       return Error;
374     if (A.substr(offset, 3) == "_be")
375       offset += 3;
376   }
377
378   // Ex. "armebv7", move past the "eb".
379   if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
380     offset += 2;
381   // Or, if it ends with eb ("armv7eb"), chop it off.
382   else if (A.endswith("eb"))
383     A = A.substr(0, A.size() - 2);
384   // Trim the head
385   if (offset != StringRef::npos)
386     A = A.substr(offset);
387
388   // Empty string means offset reached the end, which means it's valid.
389   if (A.empty())
390     return Arch;
391
392   // Only match non-marketing names
393   if (offset != StringRef::npos) {
394     // Must start with 'vN'.
395     if (A[0] != 'v' || !std::isdigit(A[1]))
396       return Error;
397     // Can't have an extra 'eb'.
398     if (A.find("eb") != StringRef::npos)
399       return Error;
400   }
401
402   // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
403   return A;
404 }
405
406 unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
407   StringRef Syn = getHWDivSynonym(HWDiv);
408   for (const auto D : HWDivNames) {
409     if (Syn == D.getName())
410       return D.ID;
411   }
412   return ARM::AEK_INVALID;
413 }
414
415 unsigned llvm::ARM::parseFPU(StringRef FPU) {
416   StringRef Syn = getFPUSynonym(FPU);
417   for (const auto F : FPUNames) {
418     if (Syn == F.getName())
419       return F.ID;
420   }
421   return ARM::FK_INVALID;
422 }
423
424 // Allows partial match, ex. "v7a" matches "armv7a".
425 unsigned llvm::ARM::parseArch(StringRef Arch) {
426   Arch = getCanonicalArchName(Arch);
427   StringRef Syn = getArchSynonym(Arch);
428   for (const auto A : ARCHNames) {
429     if (A.getName().endswith(Syn))
430       return A.ID;
431   }
432   return ARM::AK_INVALID;
433 }
434
435 unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
436   for (const auto A : ARCHExtNames) {
437     if (ArchExt == A.getName())
438       return A.ID;
439   }
440   return ARM::AEK_INVALID;
441 }
442
443 unsigned llvm::ARM::parseCPUArch(StringRef CPU) {
444   for (const auto C : CPUNames) {
445     if (CPU == C.getName())
446       return C.ArchID;
447   }
448   return ARM::AK_INVALID;
449 }
450
451 // ARM, Thumb, AArch64
452 unsigned llvm::ARM::parseArchISA(StringRef Arch) {
453   return StringSwitch<unsigned>(Arch)
454       .StartsWith("aarch64", ARM::IK_AARCH64)
455       .StartsWith("arm64", ARM::IK_AARCH64)
456       .StartsWith("thumb", ARM::IK_THUMB)
457       .StartsWith("arm", ARM::IK_ARM)
458       .Default(ARM::EK_INVALID);
459 }
460
461 // Little/Big endian
462 unsigned llvm::ARM::parseArchEndian(StringRef Arch) {
463   if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
464       Arch.startswith("aarch64_be"))
465     return ARM::EK_BIG;
466
467   if (Arch.startswith("arm") || Arch.startswith("thumb")) {
468     if (Arch.endswith("eb"))
469       return ARM::EK_BIG;
470     else
471       return ARM::EK_LITTLE;
472   }
473
474   if (Arch.startswith("aarch64"))
475     return ARM::EK_LITTLE;
476
477   return ARM::EK_INVALID;
478 }
479
480 // Profile A/R/M
481 unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
482   Arch = getCanonicalArchName(Arch);
483   switch (parseArch(Arch)) {
484   case ARM::AK_ARMV6M:
485   case ARM::AK_ARMV7M:
486   case ARM::AK_ARMV6SM:
487   case ARM::AK_ARMV7EM:
488     return ARM::PK_M;
489   case ARM::AK_ARMV7R:
490     return ARM::PK_R;
491   case ARM::AK_ARMV7:
492   case ARM::AK_ARMV7A:
493   case ARM::AK_ARMV7L:
494   case ARM::AK_ARMV8A:
495   case ARM::AK_ARMV8_1A:
496     return ARM::PK_A;
497   }
498   return ARM::PK_INVALID;
499 }
500
501 // Version number (ex. v7 = 7).
502 unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
503   Arch = getCanonicalArchName(Arch);
504   switch (parseArch(Arch)) {
505   case ARM::AK_ARMV2:
506   case ARM::AK_ARMV2A:
507     return 2;
508   case ARM::AK_ARMV3:
509   case ARM::AK_ARMV3M:
510     return 3;
511   case ARM::AK_ARMV4:
512   case ARM::AK_ARMV4T:
513     return 4;
514   case ARM::AK_ARMV5:
515   case ARM::AK_ARMV5T:
516   case ARM::AK_ARMV5TE:
517   case ARM::AK_IWMMXT:
518   case ARM::AK_IWMMXT2:
519   case ARM::AK_XSCALE:
520   case ARM::AK_ARMV5E:
521   case ARM::AK_ARMV5TEJ:
522     return 5;
523   case ARM::AK_ARMV6:
524   case ARM::AK_ARMV6J:
525   case ARM::AK_ARMV6K:
526   case ARM::AK_ARMV6T2:
527   case ARM::AK_ARMV6Z:
528   case ARM::AK_ARMV6ZK:
529   case ARM::AK_ARMV6M:
530   case ARM::AK_ARMV6SM:
531   case ARM::AK_ARMV6HL:
532     return 6;
533   case ARM::AK_ARMV7:
534   case ARM::AK_ARMV7A:
535   case ARM::AK_ARMV7R:
536   case ARM::AK_ARMV7M:
537   case ARM::AK_ARMV7L:
538   case ARM::AK_ARMV7HL:
539   case ARM::AK_ARMV7S:
540   case ARM::AK_ARMV7EM:
541   case ARM::AK_ARMV7K:
542     return 7;
543   case ARM::AK_ARMV8A:
544   case ARM::AK_ARMV8_1A:
545     return 8;
546   }
547   return 0;
548 }