blob: 4f5d9acba51973d0da7b34ef900d38e66d3a49f2 [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 bool Default; // is $Name the default CPU for $ArchID ?
Chandler Carruth3309ef62015-08-30 07:51:04 +0000114
115 StringRef getName() const { return StringRef(NameCStr, NameLength); }
Renato Goline8048f02015-05-20 15:05:07 +0000116} CPUNames[] = {
Chandler Carruth799e8802015-08-30 05:27:31 +0000117#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT) \
Chandler Carruth822d54a2015-08-30 09:01:38 +0000118 { NAME, sizeof(NAME) - 1, ID, IS_DEFAULT },
Chandler Carruth799e8802015-08-30 05:27:31 +0000119#include "llvm/Support/ARMTargetParser.def"
Renato Goline8048f02015-05-20 15:05:07 +0000120};
Renato Golinf5f373f2015-05-08 21:04:27 +0000121
122} // namespace
123
Renato Golinf5f373f2015-05-08 21:04:27 +0000124// ======================================================= //
125// Information by ID
126// ======================================================= //
127
Chandler Carruth3309ef62015-08-30 07:51:04 +0000128StringRef llvm::ARM::getFPUName(unsigned FPUKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000129 if (FPUKind >= ARM::FK_LAST)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000130 return StringRef();
131 return FPUNames[FPUKind].getName();
Renato Golinf5f373f2015-05-08 21:04:27 +0000132}
133
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000134unsigned llvm::ARM::getFPUVersion(unsigned FPUKind) {
John Brawnd03d2292015-06-05 13:29:24 +0000135 if (FPUKind >= ARM::FK_LAST)
136 return 0;
137 return FPUNames[FPUKind].FPUVersion;
138}
139
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000140unsigned llvm::ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
John Brawnd03d2292015-06-05 13:29:24 +0000141 if (FPUKind >= ARM::FK_LAST)
142 return 0;
143 return FPUNames[FPUKind].NeonSupport;
144}
145
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000146unsigned llvm::ARM::getFPURestriction(unsigned FPUKind) {
John Brawnd03d2292015-06-05 13:29:24 +0000147 if (FPUKind >= ARM::FK_LAST)
148 return 0;
149 return FPUNames[FPUKind].Restriction;
150}
151
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000152unsigned llvm::ARM::getDefaultFPU(StringRef CPU) {
Chandler Carruth822d54a2015-08-30 09:01:38 +0000153 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);
Alexandros Lamprineasfcd93d52015-07-15 10:46:21 +0000158}
159
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000160bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000161 std::vector<const char *> &Features) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000162
163 if (HWDivKind == ARM::AEK_INVALID)
164 return false;
165
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000166 if (HWDivKind & ARM::AEK_HWDIVARM)
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000167 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
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000179bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000180 std::vector<const char *> &Features) {
John Brawnd03d2292015-06-05 13:29:24 +0000181
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
John Brawnd9e39d52015-06-12 09:38:51 +0000204 // 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.
John Brawnd03d2292015-06-05 13:29:24 +0000206 switch (FPUNames[FPUKind].FPUVersion) {
Javed Absard5526302015-06-29 09:32:29 +0000207 case ARM::FV_VFPV5:
John Brawnd03d2292015-06-05 13:29:24 +0000208 Features.push_back("+fp-armv8");
209 break;
Javed Absard5526302015-06-29 09:32:29 +0000210 case ARM::FV_VFPV4:
John Brawnd03d2292015-06-05 13:29:24 +0000211 Features.push_back("+vfp4");
212 Features.push_back("-fp-armv8");
213 break;
Javed Absard5526302015-06-29 09:32:29 +0000214 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:
John Brawnd03d2292015-06-05 13:29:24 +0000221 Features.push_back("+vfp3");
John Brawnd9e39d52015-06-12 09:38:51 +0000222 Features.push_back("-fp16");
John Brawnd03d2292015-06-05 13:29:24 +0000223 Features.push_back("-vfp4");
224 Features.push_back("-fp-armv8");
225 break;
Javed Absard5526302015-06-29 09:32:29 +0000226 case ARM::FV_VFPV2:
John Brawnd03d2292015-06-05 13:29:24 +0000227 Features.push_back("+vfp2");
228 Features.push_back("-vfp3");
John Brawnd9e39d52015-06-12 09:38:51 +0000229 Features.push_back("-fp16");
John Brawnd03d2292015-06-05 13:29:24 +0000230 Features.push_back("-vfp4");
231 Features.push_back("-fp-armv8");
232 break;
Javed Absard5526302015-06-29 09:32:29 +0000233 case ARM::FV_NONE:
John Brawnd03d2292015-06-05 13:29:24 +0000234 Features.push_back("-vfp2");
235 Features.push_back("-vfp3");
John Brawnd9e39d52015-06-12 09:38:51 +0000236 Features.push_back("-fp16");
John Brawnd03d2292015-06-05 13:29:24 +0000237 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
Chandler Carruth3309ef62015-08-30 07:51:04 +0000260StringRef llvm::ARM::getArchName(unsigned ArchKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000261 if (ArchKind >= ARM::AK_LAST)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000262 return StringRef();
263 return ARCHNames[ArchKind].getName();
Renato Golinf5f373f2015-05-08 21:04:27 +0000264}
265
Chandler Carruth3309ef62015-08-30 07:51:04 +0000266StringRef llvm::ARM::getCPUAttr(unsigned ArchKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000267 if (ArchKind >= ARM::AK_LAST)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000268 return StringRef();
269 return ARCHNames[ArchKind].getCPUAttr();
Renato Golinf5f373f2015-05-08 21:04:27 +0000270}
271
Chandler Carruth3309ef62015-08-30 07:51:04 +0000272StringRef llvm::ARM::getSubArch(unsigned ArchKind) {
Renato Golin42dad642015-05-28 15:05:18 +0000273 if (ArchKind >= ARM::AK_LAST)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000274 return StringRef();
275 return ARCHNames[ArchKind].getSubArch();
Renato Golin42dad642015-05-28 15:05:18 +0000276}
277
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000278unsigned llvm::ARM::getArchAttr(unsigned ArchKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000279 if (ArchKind >= ARM::AK_LAST)
280 return ARMBuildAttrs::CPUArch::Pre_v4;
Renato Golinf7c0d5f2015-05-27 18:15:37 +0000281 return ARCHNames[ArchKind].ArchAttr;
Renato Golinf5f373f2015-05-08 21:04:27 +0000282}
283
Chandler Carruth3309ef62015-08-30 07:51:04 +0000284StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000285 for (const auto AE : ARCHExtNames) {
286 if (ArchExtKind == AE.ID)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000287 return AE.getName();
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000288 }
Chandler Carruth3309ef62015-08-30 07:51:04 +0000289 return StringRef();
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000290}
291
Chandler Carruth3309ef62015-08-30 07:51:04 +0000292StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000293 for (const auto D : HWDivNames) {
294 if (HWDivKind == D.ID)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000295 return D.getName();
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000296 }
Chandler Carruth3309ef62015-08-30 07:51:04 +0000297 return StringRef();
Renato Goline8048f02015-05-20 15:05:07 +0000298}
299
Chandler Carruth3309ef62015-08-30 07:51:04 +0000300StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
Renato Goline8048f02015-05-20 15:05:07 +0000301 unsigned AK = parseArch(Arch);
302 if (AK == ARM::AK_INVALID)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000303 return StringRef();
Renato Goline8048f02015-05-20 15:05:07 +0000304
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)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000308 return CPU.getName();
Renato Goline8048f02015-05-20 15:05:07 +0000309 }
Chandler Carruth3309ef62015-08-30 07:51:04 +0000310 return StringRef();
Renato Golinf5f373f2015-05-08 21:04:27 +0000311}
312
313// ======================================================= //
314// Parsers
315// ======================================================= //
316
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000317static StringRef getHWDivSynonym(StringRef HWDiv) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000318 return StringSwitch<StringRef>(HWDiv)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000319 .Case("thumb,arm", "arm,thumb")
320 .Default(HWDiv);
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000321}
322
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000323static StringRef getFPUSynonym(StringRef FPU) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000324 return StringSwitch<StringRef>(FPU)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000325 .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);
Renato Golinf5f373f2015-05-08 21:04:27 +0000338}
339
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000340static StringRef getArchSynonym(StringRef Arch) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000341 return StringSwitch<StringRef>(Arch)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000342 .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);
Renato Golinf5f373f2015-05-08 21:04:27 +0000351}
352
Renato Goline8048f02015-05-20 15:05:07 +0000353// 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
Renato Golinebdd12c2015-05-22 20:43:30 +0000355// "v.+", if the latter, return unmodified string, minus 'eb'.
356// If invalid, return empty string.
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000357StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
Renato Goline8048f02015-05-20 15:05:07 +0000358 size_t offset = StringRef::npos;
359 StringRef A = Arch;
Renato Golinb6b9e052015-05-21 13:52:20 +0000360 StringRef Error = "";
Renato Goline8048f02015-05-20 15:05:07 +0000361
362 // Begins with "arm" / "thumb", move past it.
Renato Golinebdd12c2015-05-22 20:43:30 +0000363 if (A.startswith("arm64"))
364 offset = 5;
365 else if (A.startswith("arm"))
Renato Goline8048f02015-05-20 15:05:07 +0000366 offset = 3;
367 else if (A.startswith("thumb"))
368 offset = 5;
Renato Golinb6b9e052015-05-21 13:52:20 +0000369 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;
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000374 if (A.substr(offset, 3) == "_be")
Renato Golinb6b9e052015-05-21 13:52:20 +0000375 offset += 3;
376 }
377
Renato Goline8048f02015-05-20 15:05:07 +0000378 // 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);
Renato Golinebdd12c2015-05-22 20:43:30 +0000384 // Trim the head
385 if (offset != StringRef::npos)
Renato Goline8048f02015-05-20 15:05:07 +0000386 A = A.substr(offset);
387
Renato Golinebdd12c2015-05-22 20:43:30 +0000388 // Empty string means offset reached the end, which means it's valid.
Renato Goline8048f02015-05-20 15:05:07 +0000389 if (A.empty())
390 return Arch;
391
Renato Golinebdd12c2015-05-22 20:43:30 +0000392 // Only match non-marketing names
393 if (offset != StringRef::npos) {
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000394 // Must start with 'vN'.
Renato Golinebdd12c2015-05-22 20:43:30 +0000395 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 }
Renato Goline8048f02015-05-20 15:05:07 +0000401
Renato Golinebdd12c2015-05-22 20:43:30 +0000402 // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
Renato Goline8048f02015-05-20 15:05:07 +0000403 return A;
404}
405
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000406unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000407 StringRef Syn = getHWDivSynonym(HWDiv);
408 for (const auto D : HWDivNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000409 if (Syn == D.getName())
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000410 return D.ID;
411 }
412 return ARM::AEK_INVALID;
413}
414
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000415unsigned llvm::ARM::parseFPU(StringRef FPU) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000416 StringRef Syn = getFPUSynonym(FPU);
417 for (const auto F : FPUNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000418 if (Syn == F.getName())
Renato Golinf5f373f2015-05-08 21:04:27 +0000419 return F.ID;
420 }
Renato Golin35de35d2015-05-12 10:33:58 +0000421 return ARM::FK_INVALID;
Renato Golinf5f373f2015-05-08 21:04:27 +0000422}
423
Renato Goline8048f02015-05-20 15:05:07 +0000424// Allows partial match, ex. "v7a" matches "armv7a".
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000425unsigned llvm::ARM::parseArch(StringRef Arch) {
Artyom Skrobov85aebc82015-06-04 21:26:58 +0000426 Arch = getCanonicalArchName(Arch);
Renato Golinf5f373f2015-05-08 21:04:27 +0000427 StringRef Syn = getArchSynonym(Arch);
428 for (const auto A : ARCHNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000429 if (A.getName().endswith(Syn))
Renato Golinf5f373f2015-05-08 21:04:27 +0000430 return A.ID;
431 }
Renato Golin35de35d2015-05-12 10:33:58 +0000432 return ARM::AK_INVALID;
Renato Golinf5f373f2015-05-08 21:04:27 +0000433}
434
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000435unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000436 for (const auto A : ARCHExtNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000437 if (ArchExt == A.getName())
Renato Golinf5f373f2015-05-08 21:04:27 +0000438 return A.ID;
439 }
Renato Golin35de35d2015-05-12 10:33:58 +0000440 return ARM::AEK_INVALID;
Renato Golinf5f373f2015-05-08 21:04:27 +0000441}
442
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000443unsigned llvm::ARM::parseCPUArch(StringRef CPU) {
Renato Goline8048f02015-05-20 15:05:07 +0000444 for (const auto C : CPUNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000445 if (CPU == C.getName())
Renato Goline8048f02015-05-20 15:05:07 +0000446 return C.ArchID;
447 }
448 return ARM::AK_INVALID;
449}
450
Renato Golinb6b9e052015-05-21 13:52:20 +0000451// ARM, Thumb, AArch64
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000452unsigned llvm::ARM::parseArchISA(StringRef Arch) {
Renato Golinb6b9e052015-05-21 13:52:20 +0000453 return StringSwitch<unsigned>(Arch)
454 .StartsWith("aarch64", ARM::IK_AARCH64)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000455 .StartsWith("arm64", ARM::IK_AARCH64)
456 .StartsWith("thumb", ARM::IK_THUMB)
457 .StartsWith("arm", ARM::IK_ARM)
Renato Golinb6b9e052015-05-21 13:52:20 +0000458 .Default(ARM::EK_INVALID);
459}
460
461// Little/Big endian
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000462unsigned llvm::ARM::parseArchEndian(StringRef Arch) {
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000463 if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
Renato Golinb6b9e052015-05-21 13:52:20 +0000464 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
Renato Golinfadc2102015-05-22 18:17:55 +0000480// Profile A/R/M
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000481unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
Renato Golinfadc2102015-05-22 18:17:55 +0000482 Arch = getCanonicalArchName(Arch);
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000483 switch (parseArch(Arch)) {
Renato Golinfadc2102015-05-22 18:17:55 +0000484 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:
Alexandros Lamprineas0e20b8d2015-07-16 14:54:41 +0000493 case ARM::AK_ARMV7L:
Renato Golinfadc2102015-05-22 18:17:55 +0000494 case ARM::AK_ARMV8A:
495 case ARM::AK_ARMV8_1A:
496 return ARM::PK_A;
497 }
498 return ARM::PK_INVALID;
499}
500
Renato Golinebdd12c2015-05-22 20:43:30 +0000501// Version number (ex. v7 = 7).
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000502unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
Renato Golinfadc2102015-05-22 18:17:55 +0000503 Arch = getCanonicalArchName(Arch);
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000504 switch (parseArch(Arch)) {
Renato Golinfadc2102015-05-22 18:17:55 +0000505 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:
Vedant Kumar366dd9fd2015-08-21 21:52:48 +0000541 case ARM::AK_ARMV7K:
Renato Golinfadc2102015-05-22 18:17:55 +0000542 return 7;
543 case ARM::AK_ARMV8A:
544 case ARM::AK_ARMV8_1A:
545 return 8;
546 }
547 return 0;
548}