blob: 53b713cb16b008a4fca8a33d1af62674f2819908 [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 {
31 const char * Name;
32 ARM::FPUKind ID;
Javed Absard5526302015-06-29 09:32:29 +000033 ARM::FPUVersion FPUVersion;
John Brawnd03d2292015-06-05 13:29:24 +000034 ARM::NeonSupportLevel NeonSupport;
35 ARM::FPURestriction Restriction;
Renato Golinf5f373f2015-05-08 21:04:27 +000036} FPUNames[] = {
Chandler Carruth799e8802015-08-30 05:27:31 +000037#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
38 { NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION },
39#include "llvm/Support/ARMTargetParser.def"
Renato Golinf5f373f2015-05-08 21:04:27 +000040};
John Brawnd03d2292015-06-05 13:29:24 +000041
Renato Golinf7c0d5f2015-05-27 18:15:37 +000042// 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.
Renato Golin42dad642015-05-28 15:05:18 +000046// 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.
Renato Golinf5f373f2015-05-08 21:04:27 +000049// FIXME: TableGen this.
50struct {
51 const char *Name;
52 ARM::ArchKind ID;
Renato Golinf7c0d5f2015-05-27 18:15:37 +000053 const char *CPUAttr; // CPU class in build attributes.
Renato Golin42dad642015-05-28 15:05:18 +000054 const char *SubArch; // Sub-Arch name.
Renato Golinf7c0d5f2015-05-27 18:15:37 +000055 ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
Renato Golinf5f373f2015-05-08 21:04:27 +000056} ARCHNames[] = {
Chandler Carruth799e8802015-08-30 05:27:31 +000057#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"
Renato Golinf5f373f2015-05-08 21:04:27 +000060};
Renato Goline1326ca2015-05-28 08:59:03 +000061// List of Arch Extension names.
Renato Golinf5f373f2015-05-08 21:04:27 +000062// FIXME: TableGen this.
63struct {
64 const char *Name;
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +000065 unsigned ID;
Renato Golinf5f373f2015-05-08 21:04:27 +000066} ARCHExtNames[] = {
Chandler Carruth799e8802015-08-30 05:27:31 +000067#define ARM_ARCH_EXT_NAME(NAME, ID) { NAME, ID },
68#include "llvm/Support/ARMTargetParser.def"
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +000069};
70// List of HWDiv names (use getHWDivSynonym) and which architectural
71// features they correspond to (use getHWDivFeatures).
72// FIXME: TableGen this.
73struct {
74 const char *Name;
75 unsigned ID;
76} HWDivNames[] = {
Chandler Carruth799e8802015-08-30 05:27:31 +000077#define ARM_HW_DIV_NAME(NAME, ID) { NAME, ID },
78#include "llvm/Support/ARMTargetParser.def"
Renato Golinf5f373f2015-05-08 21:04:27 +000079};
Renato Goline8048f02015-05-20 15:05:07 +000080// 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.
Renato Golin7374fcd2015-05-28 12:10:37 +000083// When this becomes table-generated, we'd probably need two tables.
Renato Goline8048f02015-05-20 15:05:07 +000084// FIXME: TableGen this.
85struct {
86 const char *Name;
87 ARM::ArchKind ArchID;
Alexandros Lamprineasfcd93d52015-07-15 10:46:21 +000088 ARM::FPUKind DefaultFPU;
89 bool Default; // is $Name the default CPU for $ArchID ?
Renato Goline8048f02015-05-20 15:05:07 +000090} CPUNames[] = {
Chandler Carruth799e8802015-08-30 05:27:31 +000091#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT) \
92 { NAME, ID, DEFAULT_FPU, IS_DEFAULT },
93#include "llvm/Support/ARMTargetParser.def"
Renato Goline8048f02015-05-20 15:05:07 +000094};
Renato Golinf5f373f2015-05-08 21:04:27 +000095
96} // namespace
97
Renato Golinf5f373f2015-05-08 21:04:27 +000098// ======================================================= //
99// Information by ID
100// ======================================================= //
101
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000102const char *llvm::ARM::getFPUName(unsigned FPUKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000103 if (FPUKind >= ARM::FK_LAST)
Renato Golinf5f373f2015-05-08 21:04:27 +0000104 return nullptr;
Renato Goline8048f02015-05-20 15:05:07 +0000105 return FPUNames[FPUKind].Name;
Renato Golinf5f373f2015-05-08 21:04:27 +0000106}
107
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000108unsigned llvm::ARM::getFPUVersion(unsigned FPUKind) {
John Brawnd03d2292015-06-05 13:29:24 +0000109 if (FPUKind >= ARM::FK_LAST)
110 return 0;
111 return FPUNames[FPUKind].FPUVersion;
112}
113
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000114unsigned llvm::ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
John Brawnd03d2292015-06-05 13:29:24 +0000115 if (FPUKind >= ARM::FK_LAST)
116 return 0;
117 return FPUNames[FPUKind].NeonSupport;
118}
119
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000120unsigned llvm::ARM::getFPURestriction(unsigned FPUKind) {
John Brawnd03d2292015-06-05 13:29:24 +0000121 if (FPUKind >= ARM::FK_LAST)
122 return 0;
123 return FPUNames[FPUKind].Restriction;
124}
125
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000126unsigned llvm::ARM::getDefaultFPU(StringRef CPU) {
Alexandros Lamprineasfcd93d52015-07-15 10:46:21 +0000127 for (const auto C : CPUNames) {
128 if (CPU == C.Name)
129 return C.DefaultFPU;
130 }
131 return ARM::FK_INVALID;
132}
133
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000134bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000135 std::vector<const char *> &Features) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000136
137 if (HWDivKind == ARM::AEK_INVALID)
138 return false;
139
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000140 if (HWDivKind & ARM::AEK_HWDIVARM)
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000141 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
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000153bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000154 std::vector<const char *> &Features) {
John Brawnd03d2292015-06-05 13:29:24 +0000155
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
John Brawnd9e39d52015-06-12 09:38:51 +0000178 // 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.
John Brawnd03d2292015-06-05 13:29:24 +0000180 switch (FPUNames[FPUKind].FPUVersion) {
Javed Absard5526302015-06-29 09:32:29 +0000181 case ARM::FV_VFPV5:
John Brawnd03d2292015-06-05 13:29:24 +0000182 Features.push_back("+fp-armv8");
183 break;
Javed Absard5526302015-06-29 09:32:29 +0000184 case ARM::FV_VFPV4:
John Brawnd03d2292015-06-05 13:29:24 +0000185 Features.push_back("+vfp4");
186 Features.push_back("-fp-armv8");
187 break;
Javed Absard5526302015-06-29 09:32:29 +0000188 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:
John Brawnd03d2292015-06-05 13:29:24 +0000195 Features.push_back("+vfp3");
John Brawnd9e39d52015-06-12 09:38:51 +0000196 Features.push_back("-fp16");
John Brawnd03d2292015-06-05 13:29:24 +0000197 Features.push_back("-vfp4");
198 Features.push_back("-fp-armv8");
199 break;
Javed Absard5526302015-06-29 09:32:29 +0000200 case ARM::FV_VFPV2:
John Brawnd03d2292015-06-05 13:29:24 +0000201 Features.push_back("+vfp2");
202 Features.push_back("-vfp3");
John Brawnd9e39d52015-06-12 09:38:51 +0000203 Features.push_back("-fp16");
John Brawnd03d2292015-06-05 13:29:24 +0000204 Features.push_back("-vfp4");
205 Features.push_back("-fp-armv8");
206 break;
Javed Absard5526302015-06-29 09:32:29 +0000207 case ARM::FV_NONE:
John Brawnd03d2292015-06-05 13:29:24 +0000208 Features.push_back("-vfp2");
209 Features.push_back("-vfp3");
John Brawnd9e39d52015-06-12 09:38:51 +0000210 Features.push_back("-fp16");
John Brawnd03d2292015-06-05 13:29:24 +0000211 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
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000234const char *llvm::ARM::getArchName(unsigned ArchKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000235 if (ArchKind >= ARM::AK_LAST)
Renato Golinf5f373f2015-05-08 21:04:27 +0000236 return nullptr;
Renato Goline8048f02015-05-20 15:05:07 +0000237 return ARCHNames[ArchKind].Name;
Renato Golinf5f373f2015-05-08 21:04:27 +0000238}
239
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000240const char *llvm::ARM::getCPUAttr(unsigned ArchKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000241 if (ArchKind >= ARM::AK_LAST)
Renato Golinf5f373f2015-05-08 21:04:27 +0000242 return nullptr;
Renato Golinf7c0d5f2015-05-27 18:15:37 +0000243 return ARCHNames[ArchKind].CPUAttr;
Renato Golinf5f373f2015-05-08 21:04:27 +0000244}
245
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000246const char *llvm::ARM::getSubArch(unsigned ArchKind) {
Renato Golin42dad642015-05-28 15:05:18 +0000247 if (ArchKind >= ARM::AK_LAST)
248 return nullptr;
249 return ARCHNames[ArchKind].SubArch;
250}
251
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000252unsigned llvm::ARM::getArchAttr(unsigned ArchKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000253 if (ArchKind >= ARM::AK_LAST)
254 return ARMBuildAttrs::CPUArch::Pre_v4;
Renato Golinf7c0d5f2015-05-27 18:15:37 +0000255 return ARCHNames[ArchKind].ArchAttr;
Renato Golinf5f373f2015-05-08 21:04:27 +0000256}
257
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000258const char *llvm::ARM::getArchExtName(unsigned ArchExtKind) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000259 for (const auto AE : ARCHExtNames) {
260 if (ArchExtKind == AE.ID)
261 return AE.Name;
262 }
263 return nullptr;
264}
265
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000266const char *llvm::ARM::getHWDivName(unsigned HWDivKind) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000267 for (const auto D : HWDivNames) {
268 if (HWDivKind == D.ID)
269 return D.Name;
270 }
271 return nullptr;
Renato Goline8048f02015-05-20 15:05:07 +0000272}
273
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000274const char *llvm::ARM::getDefaultCPU(StringRef Arch) {
Renato Goline8048f02015-05-20 15:05:07 +0000275 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;
Renato Golinf5f373f2015-05-08 21:04:27 +0000285}
286
287// ======================================================= //
288// Parsers
289// ======================================================= //
290
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000291static StringRef getHWDivSynonym(StringRef HWDiv) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000292 return StringSwitch<StringRef>(HWDiv)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000293 .Case("thumb,arm", "arm,thumb")
294 .Default(HWDiv);
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000295}
296
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000297static StringRef getFPUSynonym(StringRef FPU) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000298 return StringSwitch<StringRef>(FPU)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000299 .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);
Renato Golinf5f373f2015-05-08 21:04:27 +0000312}
313
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000314static StringRef getArchSynonym(StringRef Arch) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000315 return StringSwitch<StringRef>(Arch)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000316 .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);
Renato Golinf5f373f2015-05-08 21:04:27 +0000325}
326
Renato Goline8048f02015-05-20 15:05:07 +0000327// 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
Renato Golinebdd12c2015-05-22 20:43:30 +0000329// "v.+", if the latter, return unmodified string, minus 'eb'.
330// If invalid, return empty string.
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000331StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
Renato Goline8048f02015-05-20 15:05:07 +0000332 size_t offset = StringRef::npos;
333 StringRef A = Arch;
Renato Golinb6b9e052015-05-21 13:52:20 +0000334 StringRef Error = "";
Renato Goline8048f02015-05-20 15:05:07 +0000335
336 // Begins with "arm" / "thumb", move past it.
Renato Golinebdd12c2015-05-22 20:43:30 +0000337 if (A.startswith("arm64"))
338 offset = 5;
339 else if (A.startswith("arm"))
Renato Goline8048f02015-05-20 15:05:07 +0000340 offset = 3;
341 else if (A.startswith("thumb"))
342 offset = 5;
Renato Golinb6b9e052015-05-21 13:52:20 +0000343 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;
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000348 if (A.substr(offset, 3) == "_be")
Renato Golinb6b9e052015-05-21 13:52:20 +0000349 offset += 3;
350 }
351
Renato Goline8048f02015-05-20 15:05:07 +0000352 // 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);
Renato Golinebdd12c2015-05-22 20:43:30 +0000358 // Trim the head
359 if (offset != StringRef::npos)
Renato Goline8048f02015-05-20 15:05:07 +0000360 A = A.substr(offset);
361
Renato Golinebdd12c2015-05-22 20:43:30 +0000362 // Empty string means offset reached the end, which means it's valid.
Renato Goline8048f02015-05-20 15:05:07 +0000363 if (A.empty())
364 return Arch;
365
Renato Golinebdd12c2015-05-22 20:43:30 +0000366 // Only match non-marketing names
367 if (offset != StringRef::npos) {
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000368 // Must start with 'vN'.
Renato Golinebdd12c2015-05-22 20:43:30 +0000369 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 }
Renato Goline8048f02015-05-20 15:05:07 +0000375
Renato Golinebdd12c2015-05-22 20:43:30 +0000376 // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
Renato Goline8048f02015-05-20 15:05:07 +0000377 return A;
378}
379
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000380unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000381 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
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000389unsigned llvm::ARM::parseFPU(StringRef FPU) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000390 StringRef Syn = getFPUSynonym(FPU);
391 for (const auto F : FPUNames) {
392 if (Syn == F.Name)
393 return F.ID;
394 }
Renato Golin35de35d2015-05-12 10:33:58 +0000395 return ARM::FK_INVALID;
Renato Golinf5f373f2015-05-08 21:04:27 +0000396}
397
Renato Goline8048f02015-05-20 15:05:07 +0000398// Allows partial match, ex. "v7a" matches "armv7a".
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000399unsigned llvm::ARM::parseArch(StringRef Arch) {
Artyom Skrobov85aebc82015-06-04 21:26:58 +0000400 Arch = getCanonicalArchName(Arch);
Renato Golinf5f373f2015-05-08 21:04:27 +0000401 StringRef Syn = getArchSynonym(Arch);
402 for (const auto A : ARCHNames) {
Renato Goline8048f02015-05-20 15:05:07 +0000403 if (StringRef(A.Name).endswith(Syn))
Renato Golinf5f373f2015-05-08 21:04:27 +0000404 return A.ID;
405 }
Renato Golin35de35d2015-05-12 10:33:58 +0000406 return ARM::AK_INVALID;
Renato Golinf5f373f2015-05-08 21:04:27 +0000407}
408
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000409unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000410 for (const auto A : ARCHExtNames) {
411 if (ArchExt == A.Name)
412 return A.ID;
413 }
Renato Golin35de35d2015-05-12 10:33:58 +0000414 return ARM::AEK_INVALID;
Renato Golinf5f373f2015-05-08 21:04:27 +0000415}
416
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000417unsigned llvm::ARM::parseCPUArch(StringRef CPU) {
Renato Goline8048f02015-05-20 15:05:07 +0000418 for (const auto C : CPUNames) {
419 if (CPU == C.Name)
420 return C.ArchID;
421 }
422 return ARM::AK_INVALID;
423}
424
Renato Golinb6b9e052015-05-21 13:52:20 +0000425// ARM, Thumb, AArch64
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000426unsigned llvm::ARM::parseArchISA(StringRef Arch) {
Renato Golinb6b9e052015-05-21 13:52:20 +0000427 return StringSwitch<unsigned>(Arch)
428 .StartsWith("aarch64", ARM::IK_AARCH64)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000429 .StartsWith("arm64", ARM::IK_AARCH64)
430 .StartsWith("thumb", ARM::IK_THUMB)
431 .StartsWith("arm", ARM::IK_ARM)
Renato Golinb6b9e052015-05-21 13:52:20 +0000432 .Default(ARM::EK_INVALID);
433}
434
435// Little/Big endian
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000436unsigned llvm::ARM::parseArchEndian(StringRef Arch) {
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000437 if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
Renato Golinb6b9e052015-05-21 13:52:20 +0000438 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
Renato Golinfadc2102015-05-22 18:17:55 +0000454// Profile A/R/M
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000455unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
Renato Golinfadc2102015-05-22 18:17:55 +0000456 Arch = getCanonicalArchName(Arch);
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000457 switch (parseArch(Arch)) {
Renato Golinfadc2102015-05-22 18:17:55 +0000458 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:
Alexandros Lamprineas0e20b8d2015-07-16 14:54:41 +0000467 case ARM::AK_ARMV7L:
Renato Golinfadc2102015-05-22 18:17:55 +0000468 case ARM::AK_ARMV8A:
469 case ARM::AK_ARMV8_1A:
470 return ARM::PK_A;
471 }
472 return ARM::PK_INVALID;
473}
474
Renato Golinebdd12c2015-05-22 20:43:30 +0000475// Version number (ex. v7 = 7).
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000476unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
Renato Golinfadc2102015-05-22 18:17:55 +0000477 Arch = getCanonicalArchName(Arch);
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000478 switch (parseArch(Arch)) {
Renato Golinfadc2102015-05-22 18:17:55 +0000479 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:
Vedant Kumar366dd9fd2015-08-21 21:52:48 +0000515 case ARM::AK_ARMV7K:
Renato Golinfadc2102015-05-22 18:17:55 +0000516 return 7;
517 case ARM::AK_ARMV8A:
518 case ARM::AK_ARMV8_1A:
519 return 8;
520 }
521 return 0;
522}