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