blob: 3280035dca9457210b3c21c814491a50d5d91f6b [file] [log] [blame]
Renato Golinf5f373f2015-05-08 21:04:27 +00001//===-- 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"
Renato Golinebdd12c2015-05-22 20:43:30 +000019#include <cctype>
Renato Golinf5f373f2015-05-08 21:04:27 +000020
21using namespace llvm;
Chandler Carruth799e8802015-08-30 05:27:31 +000022using namespace ARM;
Renato Golinf5f373f2015-05-08 21:04:27 +000023
24namespace {
25
John Brawnd03d2292015-06-05 13:29:24 +000026// List of canonical FPU names (use getFPUSynonym) and which architectural
27// features they correspond to (use getFPUFeatures).
Renato Golinf5f373f2015-05-08 21:04:27 +000028// FIXME: TableGen this.
Javed Absard5526302015-06-29 09:32:29 +000029// The entries must appear in the order listed in ARM::FPUKind for correct indexing
Renato Golinf5f373f2015-05-08 21:04:27 +000030struct {
Chandler Carruth3309ef62015-08-30 07:51:04 +000031 const char *NameCStr;
32 size_t NameLength;
Renato Golinf5f373f2015-05-08 21:04:27 +000033 ARM::FPUKind ID;
Javed Absard5526302015-06-29 09:32:29 +000034 ARM::FPUVersion FPUVersion;
John Brawnd03d2292015-06-05 13:29:24 +000035 ARM::NeonSupportLevel NeonSupport;
36 ARM::FPURestriction Restriction;
Chandler Carruth3309ef62015-08-30 07:51:04 +000037
38 StringRef getName() const { return StringRef(NameCStr, NameLength); }
Renato Golinf5f373f2015-05-08 21:04:27 +000039} FPUNames[] = {
Chandler Carruth799e8802015-08-30 05:27:31 +000040#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
Chandler Carruth3309ef62015-08-30 07:51:04 +000041 { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION },
Chandler Carruth799e8802015-08-30 05:27:31 +000042#include "llvm/Support/ARMTargetParser.def"
Renato Golinf5f373f2015-05-08 21:04:27 +000043};
John Brawnd03d2292015-06-05 13:29:24 +000044
Renato Golinf7c0d5f2015-05-27 18:15:37 +000045// 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.
Renato Golin42dad642015-05-28 15:05:18 +000049// 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.
Renato Golinf5f373f2015-05-08 21:04:27 +000052// FIXME: TableGen this.
53struct {
Chandler Carruth3309ef62015-08-30 07:51:04 +000054 const char *NameCStr;
55 size_t NameLength;
Renato Golinf5f373f2015-05-08 21:04:27 +000056 ARM::ArchKind ID;
Chandler Carruth3309ef62015-08-30 07:51:04 +000057 const char *CPUAttrCStr;
58 size_t CPUAttrLength;
59 const char *SubArchCStr;
60 size_t SubArchLength;
Renato Golinf7c0d5f2015-05-27 18:15:37 +000061 ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
Chandler Carruth3309ef62015-08-30 07:51:04 +000062
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); }
Renato Golinf5f373f2015-05-08 21:04:27 +000070} ARCHNames[] = {
Chandler Carruth3309ef62015-08-30 07:51:04 +000071#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},
Chandler Carruth799e8802015-08-30 05:27:31 +000074#include "llvm/Support/ARMTargetParser.def"
Renato Golinf5f373f2015-05-08 21:04:27 +000075};
Chandler Carruth3309ef62015-08-30 07:51:04 +000076
Renato Goline1326ca2015-05-28 08:59:03 +000077// List of Arch Extension names.
Renato Golinf5f373f2015-05-08 21:04:27 +000078// FIXME: TableGen this.
79struct {
Chandler Carruth3309ef62015-08-30 07:51:04 +000080 const char *NameCStr;
81 size_t NameLength;
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +000082 unsigned ID;
Chandler Carruth3309ef62015-08-30 07:51:04 +000083
84 StringRef getName() const { return StringRef(NameCStr, NameLength); }
Renato Golinf5f373f2015-05-08 21:04:27 +000085} ARCHExtNames[] = {
Chandler Carruth3309ef62015-08-30 07:51:04 +000086#define ARM_ARCH_EXT_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
Chandler Carruth799e8802015-08-30 05:27:31 +000087#include "llvm/Support/ARMTargetParser.def"
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +000088};
Chandler Carruth3309ef62015-08-30 07:51:04 +000089
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +000090// List of HWDiv names (use getHWDivSynonym) and which architectural
91// features they correspond to (use getHWDivFeatures).
92// FIXME: TableGen this.
93struct {
Chandler Carruth3309ef62015-08-30 07:51:04 +000094 const char *NameCStr;
95 size_t NameLength;
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +000096 unsigned ID;
Chandler Carruth3309ef62015-08-30 07:51:04 +000097
98 StringRef getName() const { return StringRef(NameCStr, NameLength); }
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +000099} HWDivNames[] = {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000100#define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
Chandler Carruth799e8802015-08-30 05:27:31 +0000101#include "llvm/Support/ARMTargetParser.def"
Renato Golinf5f373f2015-05-08 21:04:27 +0000102};
Chandler Carruth3309ef62015-08-30 07:51:04 +0000103
Renato Goline8048f02015-05-20 15:05:07 +0000104// 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.
Renato Golin7374fcd2015-05-28 12:10:37 +0000107// When this becomes table-generated, we'd probably need two tables.
Renato Goline8048f02015-05-20 15:05:07 +0000108// FIXME: TableGen this.
109struct {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000110 const char *NameCStr;
111 size_t NameLength;
Renato Goline8048f02015-05-20 15:05:07 +0000112 ARM::ArchKind ArchID;
Alexandros Lamprineasfcd93d52015-07-15 10:46:21 +0000113 ARM::FPUKind DefaultFPU;
114 bool Default; // is $Name the default CPU for $ArchID ?
Chandler Carruth3309ef62015-08-30 07:51:04 +0000115
116 StringRef getName() const { return StringRef(NameCStr, NameLength); }
Renato Goline8048f02015-05-20 15:05:07 +0000117} CPUNames[] = {
Chandler Carruth799e8802015-08-30 05:27:31 +0000118#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT) \
Chandler Carruth3309ef62015-08-30 07:51:04 +0000119 { NAME, sizeof(NAME) - 1, ID, DEFAULT_FPU, IS_DEFAULT },
Chandler Carruth799e8802015-08-30 05:27:31 +0000120#include "llvm/Support/ARMTargetParser.def"
Renato Goline8048f02015-05-20 15:05:07 +0000121};
Renato Golinf5f373f2015-05-08 21:04:27 +0000122
123} // namespace
124
Renato Golinf5f373f2015-05-08 21:04:27 +0000125// ======================================================= //
126// Information by ID
127// ======================================================= //
128
Chandler Carruth3309ef62015-08-30 07:51:04 +0000129StringRef llvm::ARM::getFPUName(unsigned FPUKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000130 if (FPUKind >= ARM::FK_LAST)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000131 return StringRef();
132 return FPUNames[FPUKind].getName();
Renato Golinf5f373f2015-05-08 21:04:27 +0000133}
134
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000135unsigned llvm::ARM::getFPUVersion(unsigned FPUKind) {
John Brawnd03d2292015-06-05 13:29:24 +0000136 if (FPUKind >= ARM::FK_LAST)
137 return 0;
138 return FPUNames[FPUKind].FPUVersion;
139}
140
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000141unsigned llvm::ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
John Brawnd03d2292015-06-05 13:29:24 +0000142 if (FPUKind >= ARM::FK_LAST)
143 return 0;
144 return FPUNames[FPUKind].NeonSupport;
145}
146
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000147unsigned llvm::ARM::getFPURestriction(unsigned FPUKind) {
John Brawnd03d2292015-06-05 13:29:24 +0000148 if (FPUKind >= ARM::FK_LAST)
149 return 0;
150 return FPUNames[FPUKind].Restriction;
151}
152
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000153unsigned llvm::ARM::getDefaultFPU(StringRef CPU) {
Alexandros Lamprineasfcd93d52015-07-15 10:46:21 +0000154 for (const auto C : CPUNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000155 if (CPU == C.getName())
Alexandros Lamprineasfcd93d52015-07-15 10:46:21 +0000156 return C.DefaultFPU;
157 }
158 return ARM::FK_INVALID;
159}
160
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000161bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000162 std::vector<const char *> &Features) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000163
164 if (HWDivKind == ARM::AEK_INVALID)
165 return false;
166
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000167 if (HWDivKind & ARM::AEK_HWDIVARM)
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000168 Features.push_back("+hwdiv-arm");
169 else
170 Features.push_back("-hwdiv-arm");
171
172 if (HWDivKind & ARM::AEK_HWDIV)
173 Features.push_back("+hwdiv");
174 else
175 Features.push_back("-hwdiv");
176
177 return true;
178}
179
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000180bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000181 std::vector<const char *> &Features) {
John Brawnd03d2292015-06-05 13:29:24 +0000182
183 if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
184 return false;
185
186 // fp-only-sp and d16 subtarget features are independent of each other, so we
187 // must enable/disable both.
188 switch (FPUNames[FPUKind].Restriction) {
189 case ARM::FR_SP_D16:
190 Features.push_back("+fp-only-sp");
191 Features.push_back("+d16");
192 break;
193 case ARM::FR_D16:
194 Features.push_back("-fp-only-sp");
195 Features.push_back("+d16");
196 break;
197 case ARM::FR_None:
198 Features.push_back("-fp-only-sp");
199 Features.push_back("-d16");
200 break;
201 }
202
203 // FPU version subtarget features are inclusive of lower-numbered ones, so
204 // enable the one corresponding to this version and disable all that are
John Brawnd9e39d52015-06-12 09:38:51 +0000205 // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
206 // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
John Brawnd03d2292015-06-05 13:29:24 +0000207 switch (FPUNames[FPUKind].FPUVersion) {
Javed Absard5526302015-06-29 09:32:29 +0000208 case ARM::FV_VFPV5:
John Brawnd03d2292015-06-05 13:29:24 +0000209 Features.push_back("+fp-armv8");
210 break;
Javed Absard5526302015-06-29 09:32:29 +0000211 case ARM::FV_VFPV4:
John Brawnd03d2292015-06-05 13:29:24 +0000212 Features.push_back("+vfp4");
213 Features.push_back("-fp-armv8");
214 break;
Javed Absard5526302015-06-29 09:32:29 +0000215 case ARM::FV_VFPV3_FP16:
216 Features.push_back("+vfp3");
217 Features.push_back("+fp16");
218 Features.push_back("-vfp4");
219 Features.push_back("-fp-armv8");
220 break;
221 case ARM::FV_VFPV3:
John Brawnd03d2292015-06-05 13:29:24 +0000222 Features.push_back("+vfp3");
John Brawnd9e39d52015-06-12 09:38:51 +0000223 Features.push_back("-fp16");
John Brawnd03d2292015-06-05 13:29:24 +0000224 Features.push_back("-vfp4");
225 Features.push_back("-fp-armv8");
226 break;
Javed Absard5526302015-06-29 09:32:29 +0000227 case ARM::FV_VFPV2:
John Brawnd03d2292015-06-05 13:29:24 +0000228 Features.push_back("+vfp2");
229 Features.push_back("-vfp3");
John Brawnd9e39d52015-06-12 09:38:51 +0000230 Features.push_back("-fp16");
John Brawnd03d2292015-06-05 13:29:24 +0000231 Features.push_back("-vfp4");
232 Features.push_back("-fp-armv8");
233 break;
Javed Absard5526302015-06-29 09:32:29 +0000234 case ARM::FV_NONE:
John Brawnd03d2292015-06-05 13:29:24 +0000235 Features.push_back("-vfp2");
236 Features.push_back("-vfp3");
John Brawnd9e39d52015-06-12 09:38:51 +0000237 Features.push_back("-fp16");
John Brawnd03d2292015-06-05 13:29:24 +0000238 Features.push_back("-vfp4");
239 Features.push_back("-fp-armv8");
240 break;
241 }
242
243 // crypto includes neon, so we handle this similarly to FPU version.
244 switch (FPUNames[FPUKind].NeonSupport) {
245 case ARM::NS_Crypto:
246 Features.push_back("+crypto");
247 break;
248 case ARM::NS_Neon:
249 Features.push_back("+neon");
250 Features.push_back("-crypto");
251 break;
252 case ARM::NS_None:
253 Features.push_back("-neon");
254 Features.push_back("-crypto");
255 break;
256 }
257
258 return true;
259}
260
Chandler Carruth3309ef62015-08-30 07:51:04 +0000261StringRef llvm::ARM::getArchName(unsigned ArchKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000262 if (ArchKind >= ARM::AK_LAST)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000263 return StringRef();
264 return ARCHNames[ArchKind].getName();
Renato Golinf5f373f2015-05-08 21:04:27 +0000265}
266
Chandler Carruth3309ef62015-08-30 07:51:04 +0000267StringRef llvm::ARM::getCPUAttr(unsigned ArchKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000268 if (ArchKind >= ARM::AK_LAST)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000269 return StringRef();
270 return ARCHNames[ArchKind].getCPUAttr();
Renato Golinf5f373f2015-05-08 21:04:27 +0000271}
272
Chandler Carruth3309ef62015-08-30 07:51:04 +0000273StringRef llvm::ARM::getSubArch(unsigned ArchKind) {
Renato Golin42dad642015-05-28 15:05:18 +0000274 if (ArchKind >= ARM::AK_LAST)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000275 return StringRef();
276 return ARCHNames[ArchKind].getSubArch();
Renato Golin42dad642015-05-28 15:05:18 +0000277}
278
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000279unsigned llvm::ARM::getArchAttr(unsigned ArchKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000280 if (ArchKind >= ARM::AK_LAST)
281 return ARMBuildAttrs::CPUArch::Pre_v4;
Renato Golinf7c0d5f2015-05-27 18:15:37 +0000282 return ARCHNames[ArchKind].ArchAttr;
Renato Golinf5f373f2015-05-08 21:04:27 +0000283}
284
Chandler Carruth3309ef62015-08-30 07:51:04 +0000285StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000286 for (const auto AE : ARCHExtNames) {
287 if (ArchExtKind == AE.ID)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000288 return AE.getName();
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000289 }
Chandler Carruth3309ef62015-08-30 07:51:04 +0000290 return StringRef();
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000291}
292
Chandler Carruth3309ef62015-08-30 07:51:04 +0000293StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000294 for (const auto D : HWDivNames) {
295 if (HWDivKind == D.ID)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000296 return D.getName();
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000297 }
Chandler Carruth3309ef62015-08-30 07:51:04 +0000298 return StringRef();
Renato Goline8048f02015-05-20 15:05:07 +0000299}
300
Chandler Carruth3309ef62015-08-30 07:51:04 +0000301StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
Renato Goline8048f02015-05-20 15:05:07 +0000302 unsigned AK = parseArch(Arch);
303 if (AK == ARM::AK_INVALID)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000304 return StringRef();
Renato Goline8048f02015-05-20 15:05:07 +0000305
306 // Look for multiple AKs to find the default for pair AK+Name.
307 for (const auto CPU : CPUNames) {
308 if (CPU.ArchID == AK && CPU.Default)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000309 return CPU.getName();
Renato Goline8048f02015-05-20 15:05:07 +0000310 }
Chandler Carruth3309ef62015-08-30 07:51:04 +0000311 return StringRef();
Renato Golinf5f373f2015-05-08 21:04:27 +0000312}
313
314// ======================================================= //
315// Parsers
316// ======================================================= //
317
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000318static StringRef getHWDivSynonym(StringRef HWDiv) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000319 return StringSwitch<StringRef>(HWDiv)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000320 .Case("thumb,arm", "arm,thumb")
321 .Default(HWDiv);
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000322}
323
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000324static StringRef getFPUSynonym(StringRef FPU) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000325 return StringSwitch<StringRef>(FPU)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000326 .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
327 .Case("vfp2", "vfpv2")
328 .Case("vfp3", "vfpv3")
329 .Case("vfp4", "vfpv4")
330 .Case("vfp3-d16", "vfpv3-d16")
331 .Case("vfp4-d16", "vfpv4-d16")
332 .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
333 .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
334 .Case("fp5-sp-d16", "fpv5-sp-d16")
335 .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
336 // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
337 .Case("neon-vfpv3", "neon")
338 .Default(FPU);
Renato Golinf5f373f2015-05-08 21:04:27 +0000339}
340
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000341static StringRef getArchSynonym(StringRef Arch) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000342 return StringSwitch<StringRef>(Arch)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000343 .Case("v6sm", "v6s-m")
344 .Case("v6m", "v6-m")
345 .Case("v7a", "v7-a")
346 .Case("v7r", "v7-r")
347 .Case("v7m", "v7-m")
348 .Case("v7em", "v7e-m")
349 .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
350 .Case("v8.1a", "v8.1-a")
351 .Default(Arch);
Renato Golinf5f373f2015-05-08 21:04:27 +0000352}
353
Renato Goline8048f02015-05-20 15:05:07 +0000354// MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
355// (iwmmxt|xscale)(eb)? is also permitted. If the former, return
Renato Golinebdd12c2015-05-22 20:43:30 +0000356// "v.+", if the latter, return unmodified string, minus 'eb'.
357// If invalid, return empty string.
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000358StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
Renato Goline8048f02015-05-20 15:05:07 +0000359 size_t offset = StringRef::npos;
360 StringRef A = Arch;
Renato Golinb6b9e052015-05-21 13:52:20 +0000361 StringRef Error = "";
Renato Goline8048f02015-05-20 15:05:07 +0000362
363 // Begins with "arm" / "thumb", move past it.
Renato Golinebdd12c2015-05-22 20:43:30 +0000364 if (A.startswith("arm64"))
365 offset = 5;
366 else if (A.startswith("arm"))
Renato Goline8048f02015-05-20 15:05:07 +0000367 offset = 3;
368 else if (A.startswith("thumb"))
369 offset = 5;
Renato Golinb6b9e052015-05-21 13:52:20 +0000370 else if (A.startswith("aarch64")) {
371 offset = 7;
372 // AArch64 uses "_be", not "eb" suffix.
373 if (A.find("eb") != StringRef::npos)
374 return Error;
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000375 if (A.substr(offset, 3) == "_be")
Renato Golinb6b9e052015-05-21 13:52:20 +0000376 offset += 3;
377 }
378
Renato Goline8048f02015-05-20 15:05:07 +0000379 // Ex. "armebv7", move past the "eb".
380 if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
381 offset += 2;
382 // Or, if it ends with eb ("armv7eb"), chop it off.
383 else if (A.endswith("eb"))
384 A = A.substr(0, A.size() - 2);
Renato Golinebdd12c2015-05-22 20:43:30 +0000385 // Trim the head
386 if (offset != StringRef::npos)
Renato Goline8048f02015-05-20 15:05:07 +0000387 A = A.substr(offset);
388
Renato Golinebdd12c2015-05-22 20:43:30 +0000389 // Empty string means offset reached the end, which means it's valid.
Renato Goline8048f02015-05-20 15:05:07 +0000390 if (A.empty())
391 return Arch;
392
Renato Golinebdd12c2015-05-22 20:43:30 +0000393 // Only match non-marketing names
394 if (offset != StringRef::npos) {
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000395 // Must start with 'vN'.
Renato Golinebdd12c2015-05-22 20:43:30 +0000396 if (A[0] != 'v' || !std::isdigit(A[1]))
397 return Error;
398 // Can't have an extra 'eb'.
399 if (A.find("eb") != StringRef::npos)
400 return Error;
401 }
Renato Goline8048f02015-05-20 15:05:07 +0000402
Renato Golinebdd12c2015-05-22 20:43:30 +0000403 // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
Renato Goline8048f02015-05-20 15:05:07 +0000404 return A;
405}
406
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000407unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000408 StringRef Syn = getHWDivSynonym(HWDiv);
409 for (const auto D : HWDivNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000410 if (Syn == D.getName())
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000411 return D.ID;
412 }
413 return ARM::AEK_INVALID;
414}
415
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000416unsigned llvm::ARM::parseFPU(StringRef FPU) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000417 StringRef Syn = getFPUSynonym(FPU);
418 for (const auto F : FPUNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000419 if (Syn == F.getName())
Renato Golinf5f373f2015-05-08 21:04:27 +0000420 return F.ID;
421 }
Renato Golin35de35d2015-05-12 10:33:58 +0000422 return ARM::FK_INVALID;
Renato Golinf5f373f2015-05-08 21:04:27 +0000423}
424
Renato Goline8048f02015-05-20 15:05:07 +0000425// Allows partial match, ex. "v7a" matches "armv7a".
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000426unsigned llvm::ARM::parseArch(StringRef Arch) {
Artyom Skrobov85aebc82015-06-04 21:26:58 +0000427 Arch = getCanonicalArchName(Arch);
Renato Golinf5f373f2015-05-08 21:04:27 +0000428 StringRef Syn = getArchSynonym(Arch);
429 for (const auto A : ARCHNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000430 if (A.getName().endswith(Syn))
Renato Golinf5f373f2015-05-08 21:04:27 +0000431 return A.ID;
432 }
Renato Golin35de35d2015-05-12 10:33:58 +0000433 return ARM::AK_INVALID;
Renato Golinf5f373f2015-05-08 21:04:27 +0000434}
435
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000436unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000437 for (const auto A : ARCHExtNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000438 if (ArchExt == A.getName())
Renato Golinf5f373f2015-05-08 21:04:27 +0000439 return A.ID;
440 }
Renato Golin35de35d2015-05-12 10:33:58 +0000441 return ARM::AEK_INVALID;
Renato Golinf5f373f2015-05-08 21:04:27 +0000442}
443
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000444unsigned llvm::ARM::parseCPUArch(StringRef CPU) {
Renato Goline8048f02015-05-20 15:05:07 +0000445 for (const auto C : CPUNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000446 if (CPU == C.getName())
Renato Goline8048f02015-05-20 15:05:07 +0000447 return C.ArchID;
448 }
449 return ARM::AK_INVALID;
450}
451
Renato Golinb6b9e052015-05-21 13:52:20 +0000452// ARM, Thumb, AArch64
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000453unsigned llvm::ARM::parseArchISA(StringRef Arch) {
Renato Golinb6b9e052015-05-21 13:52:20 +0000454 return StringSwitch<unsigned>(Arch)
455 .StartsWith("aarch64", ARM::IK_AARCH64)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000456 .StartsWith("arm64", ARM::IK_AARCH64)
457 .StartsWith("thumb", ARM::IK_THUMB)
458 .StartsWith("arm", ARM::IK_ARM)
Renato Golinb6b9e052015-05-21 13:52:20 +0000459 .Default(ARM::EK_INVALID);
460}
461
462// Little/Big endian
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000463unsigned llvm::ARM::parseArchEndian(StringRef Arch) {
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000464 if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
Renato Golinb6b9e052015-05-21 13:52:20 +0000465 Arch.startswith("aarch64_be"))
466 return ARM::EK_BIG;
467
468 if (Arch.startswith("arm") || Arch.startswith("thumb")) {
469 if (Arch.endswith("eb"))
470 return ARM::EK_BIG;
471 else
472 return ARM::EK_LITTLE;
473 }
474
475 if (Arch.startswith("aarch64"))
476 return ARM::EK_LITTLE;
477
478 return ARM::EK_INVALID;
479}
480
Renato Golinfadc2102015-05-22 18:17:55 +0000481// Profile A/R/M
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000482unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
Renato Golinfadc2102015-05-22 18:17:55 +0000483 Arch = getCanonicalArchName(Arch);
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000484 switch (parseArch(Arch)) {
Renato Golinfadc2102015-05-22 18:17:55 +0000485 case ARM::AK_ARMV6M:
486 case ARM::AK_ARMV7M:
487 case ARM::AK_ARMV6SM:
488 case ARM::AK_ARMV7EM:
489 return ARM::PK_M;
490 case ARM::AK_ARMV7R:
491 return ARM::PK_R;
492 case ARM::AK_ARMV7:
493 case ARM::AK_ARMV7A:
Alexandros Lamprineas0e20b8d2015-07-16 14:54:41 +0000494 case ARM::AK_ARMV7L:
Renato Golinfadc2102015-05-22 18:17:55 +0000495 case ARM::AK_ARMV8A:
496 case ARM::AK_ARMV8_1A:
497 return ARM::PK_A;
498 }
499 return ARM::PK_INVALID;
500}
501
Renato Golinebdd12c2015-05-22 20:43:30 +0000502// Version number (ex. v7 = 7).
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000503unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
Renato Golinfadc2102015-05-22 18:17:55 +0000504 Arch = getCanonicalArchName(Arch);
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000505 switch (parseArch(Arch)) {
Renato Golinfadc2102015-05-22 18:17:55 +0000506 case ARM::AK_ARMV2:
507 case ARM::AK_ARMV2A:
508 return 2;
509 case ARM::AK_ARMV3:
510 case ARM::AK_ARMV3M:
511 return 3;
512 case ARM::AK_ARMV4:
513 case ARM::AK_ARMV4T:
514 return 4;
515 case ARM::AK_ARMV5:
516 case ARM::AK_ARMV5T:
517 case ARM::AK_ARMV5TE:
518 case ARM::AK_IWMMXT:
519 case ARM::AK_IWMMXT2:
520 case ARM::AK_XSCALE:
521 case ARM::AK_ARMV5E:
522 case ARM::AK_ARMV5TEJ:
523 return 5;
524 case ARM::AK_ARMV6:
525 case ARM::AK_ARMV6J:
526 case ARM::AK_ARMV6K:
527 case ARM::AK_ARMV6T2:
528 case ARM::AK_ARMV6Z:
529 case ARM::AK_ARMV6ZK:
530 case ARM::AK_ARMV6M:
531 case ARM::AK_ARMV6SM:
532 case ARM::AK_ARMV6HL:
533 return 6;
534 case ARM::AK_ARMV7:
535 case ARM::AK_ARMV7A:
536 case ARM::AK_ARMV7R:
537 case ARM::AK_ARMV7M:
538 case ARM::AK_ARMV7L:
539 case ARM::AK_ARMV7HL:
540 case ARM::AK_ARMV7S:
541 case ARM::AK_ARMV7EM:
Vedant Kumar366dd9fd2015-08-21 21:52:48 +0000542 case ARM::AK_ARMV7K:
Renato Golinfadc2102015-05-22 18:17:55 +0000543 return 7;
544 case ARM::AK_ARMV8A:
545 case ARM::AK_ARMV8_1A:
546 return 8;
547 }
548 return 0;
549}