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