blob: a57b48f8a4eca365b0c2c06582a560c2bcc90341 [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
Artyom Skrobovbc09f392015-11-16 12:08:05 +000030static const struct {
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.
Artyom Skrobovbc09f392015-11-16 12:08:05 +000053static const struct {
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.
Bradley Smith4adcb732015-11-16 11:15:22 +000062 unsigned DefaultFPU;
Alexandros Lamprineasea33e5e2015-09-05 17:05:33 +000063 unsigned ArchBaseExtensions;
Chandler Carruth3309ef62015-08-30 07:51:04 +000064
65 StringRef getName() const { return StringRef(NameCStr, NameLength); }
66
67 // CPU class in build attributes.
68 StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }
69
70 // Sub-Arch name.
71 StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
Renato Golinf5f373f2015-05-08 21:04:27 +000072} ARCHNames[] = {
Bradley Smith4adcb732015-11-16 11:15:22 +000073#define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
Chandler Carruth3309ef62015-08-30 07:51:04 +000074 {NAME, sizeof(NAME) - 1, ID, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
Bradley Smith4adcb732015-11-16 11:15:22 +000075 sizeof(SUB_ARCH) - 1, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT},
Chandler Carruth799e8802015-08-30 05:27:31 +000076#include "llvm/Support/ARMTargetParser.def"
Renato Golinf5f373f2015-05-08 21:04:27 +000077};
Chandler Carruth3309ef62015-08-30 07:51:04 +000078
Renato Goline1326ca2015-05-28 08:59:03 +000079// List of Arch Extension names.
Renato Golinf5f373f2015-05-08 21:04:27 +000080// FIXME: TableGen this.
Artyom Skrobovbc09f392015-11-16 12:08:05 +000081static const struct {
Chandler Carruth3309ef62015-08-30 07:51:04 +000082 const char *NameCStr;
83 size_t NameLength;
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +000084 unsigned ID;
Chandler Carruth3309ef62015-08-30 07:51:04 +000085
86 StringRef getName() const { return StringRef(NameCStr, NameLength); }
Renato Golinf5f373f2015-05-08 21:04:27 +000087} ARCHExtNames[] = {
Chandler Carruth3309ef62015-08-30 07:51:04 +000088#define ARM_ARCH_EXT_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
Chandler Carruth799e8802015-08-30 05:27:31 +000089#include "llvm/Support/ARMTargetParser.def"
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +000090};
Chandler Carruth3309ef62015-08-30 07:51:04 +000091
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +000092// List of HWDiv names (use getHWDivSynonym) and which architectural
93// features they correspond to (use getHWDivFeatures).
94// FIXME: TableGen this.
Artyom Skrobovbc09f392015-11-16 12:08:05 +000095static const struct {
Chandler Carruth3309ef62015-08-30 07:51:04 +000096 const char *NameCStr;
97 size_t NameLength;
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +000098 unsigned ID;
Chandler Carruth3309ef62015-08-30 07:51:04 +000099
100 StringRef getName() const { return StringRef(NameCStr, NameLength); }
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000101} HWDivNames[] = {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000102#define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
Chandler Carruth799e8802015-08-30 05:27:31 +0000103#include "llvm/Support/ARMTargetParser.def"
Renato Golinf5f373f2015-05-08 21:04:27 +0000104};
Chandler Carruth3309ef62015-08-30 07:51:04 +0000105
Renato Goline8048f02015-05-20 15:05:07 +0000106// List of CPU names and their arches.
107// The same CPU can have multiple arches and can be default on multiple arches.
108// When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
Renato Golin7374fcd2015-05-28 12:10:37 +0000109// When this becomes table-generated, we'd probably need two tables.
Renato Goline8048f02015-05-20 15:05:07 +0000110// FIXME: TableGen this.
Artyom Skrobovbc09f392015-11-16 12:08:05 +0000111static const struct {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000112 const char *NameCStr;
113 size_t NameLength;
Renato Goline8048f02015-05-20 15:05:07 +0000114 ARM::ArchKind ArchID;
Alexandros Lamprineasfcd93d52015-07-15 10:46:21 +0000115 bool Default; // is $Name the default CPU for $ArchID ?
Alexandros Lamprineasea33e5e2015-09-05 17:05:33 +0000116 unsigned DefaultExtensions;
Chandler Carruth3309ef62015-08-30 07:51:04 +0000117
118 StringRef getName() const { return StringRef(NameCStr, NameLength); }
Renato Goline8048f02015-05-20 15:05:07 +0000119} CPUNames[] = {
Alexandros Lamprineasea33e5e2015-09-05 17:05:33 +0000120#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
121 { NAME, sizeof(NAME) - 1, ID, IS_DEFAULT, DEFAULT_EXT },
Chandler Carruth799e8802015-08-30 05:27:31 +0000122#include "llvm/Support/ARMTargetParser.def"
Renato Goline8048f02015-05-20 15:05:07 +0000123};
Renato Golinf5f373f2015-05-08 21:04:27 +0000124
125} // namespace
126
Renato Golinf5f373f2015-05-08 21:04:27 +0000127// ======================================================= //
128// Information by ID
129// ======================================================= //
130
Chandler Carruth3309ef62015-08-30 07:51:04 +0000131StringRef llvm::ARM::getFPUName(unsigned FPUKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000132 if (FPUKind >= ARM::FK_LAST)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000133 return StringRef();
134 return FPUNames[FPUKind].getName();
Renato Golinf5f373f2015-05-08 21:04:27 +0000135}
136
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000137unsigned llvm::ARM::getFPUVersion(unsigned FPUKind) {
John Brawnd03d2292015-06-05 13:29:24 +0000138 if (FPUKind >= ARM::FK_LAST)
139 return 0;
140 return FPUNames[FPUKind].FPUVersion;
141}
142
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000143unsigned llvm::ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
John Brawnd03d2292015-06-05 13:29:24 +0000144 if (FPUKind >= ARM::FK_LAST)
145 return 0;
146 return FPUNames[FPUKind].NeonSupport;
147}
148
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000149unsigned llvm::ARM::getFPURestriction(unsigned FPUKind) {
John Brawnd03d2292015-06-05 13:29:24 +0000150 if (FPUKind >= ARM::FK_LAST)
151 return 0;
152 return FPUNames[FPUKind].Restriction;
153}
154
Bradley Smith4adcb732015-11-16 11:15:22 +0000155unsigned llvm::ARM::getDefaultFPU(StringRef CPU, unsigned ArchKind) {
156 if (CPU == "generic")
157 return ARCHNames[ArchKind].DefaultFPU;
158
Chandler Carruth822d54a2015-08-30 09:01:38 +0000159 return StringSwitch<unsigned>(CPU)
Alexandros Lamprineasea33e5e2015-09-05 17:05:33 +0000160#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
Chandler Carruth822d54a2015-08-30 09:01:38 +0000161 .Case(NAME, DEFAULT_FPU)
162#include "llvm/Support/ARMTargetParser.def"
163 .Default(ARM::FK_INVALID);
Alexandros Lamprineasfcd93d52015-07-15 10:46:21 +0000164}
165
Artyom Skrobovbc09f392015-11-16 12:08:05 +0000166unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, unsigned ArchKind) {
167 if (CPU == "generic")
168 return ARCHNames[ArchKind].ArchBaseExtensions;
169
170 return StringSwitch<unsigned>(CPU)
171#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
172 .Case(NAME, ARCHNames[ID].ArchBaseExtensions | DEFAULT_EXT)
173#include "llvm/Support/ARMTargetParser.def"
174 .Default(ARM::AEK_INVALID);
175}
176
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000177bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000178 std::vector<const char *> &Features) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000179
180 if (HWDivKind == ARM::AEK_INVALID)
181 return false;
182
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000183 if (HWDivKind & ARM::AEK_HWDIVARM)
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000184 Features.push_back("+hwdiv-arm");
185 else
186 Features.push_back("-hwdiv-arm");
187
188 if (HWDivKind & ARM::AEK_HWDIV)
189 Features.push_back("+hwdiv");
190 else
191 Features.push_back("-hwdiv");
192
193 return true;
194}
195
Alexandros Lamprineasea33e5e2015-09-05 17:05:33 +0000196bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
197 std::vector<const char *> &Features) {
198
199 if (Extensions == ARM::AEK_INVALID)
200 return false;
201
202 if (Extensions & ARM::AEK_CRC)
203 Features.push_back("+crc");
204 else
205 Features.push_back("-crc");
206
Artyom Skrobovcf296442015-09-24 17:31:16 +0000207 if (Extensions & ARM::AEK_DSP)
Artyom Skrobov5a6e3942015-10-23 17:19:19 +0000208 Features.push_back("+dsp");
Artyom Skrobovcf296442015-09-24 17:31:16 +0000209 else
Artyom Skrobov5a6e3942015-10-23 17:19:19 +0000210 Features.push_back("-dsp");
Artyom Skrobovcf296442015-09-24 17:31:16 +0000211
Alexandros Lamprineasea33e5e2015-09-05 17:05:33 +0000212 return getHWDivFeatures(Extensions, Features);
213}
214
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000215bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000216 std::vector<const char *> &Features) {
John Brawnd03d2292015-06-05 13:29:24 +0000217
218 if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
219 return false;
220
221 // fp-only-sp and d16 subtarget features are independent of each other, so we
222 // must enable/disable both.
223 switch (FPUNames[FPUKind].Restriction) {
224 case ARM::FR_SP_D16:
225 Features.push_back("+fp-only-sp");
226 Features.push_back("+d16");
227 break;
228 case ARM::FR_D16:
229 Features.push_back("-fp-only-sp");
230 Features.push_back("+d16");
231 break;
232 case ARM::FR_None:
233 Features.push_back("-fp-only-sp");
234 Features.push_back("-d16");
235 break;
236 }
237
238 // FPU version subtarget features are inclusive of lower-numbered ones, so
239 // enable the one corresponding to this version and disable all that are
John Brawnd9e39d52015-06-12 09:38:51 +0000240 // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
241 // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
John Brawnd03d2292015-06-05 13:29:24 +0000242 switch (FPUNames[FPUKind].FPUVersion) {
Javed Absard5526302015-06-29 09:32:29 +0000243 case ARM::FV_VFPV5:
John Brawnd03d2292015-06-05 13:29:24 +0000244 Features.push_back("+fp-armv8");
245 break;
Javed Absard5526302015-06-29 09:32:29 +0000246 case ARM::FV_VFPV4:
John Brawnd03d2292015-06-05 13:29:24 +0000247 Features.push_back("+vfp4");
248 Features.push_back("-fp-armv8");
249 break;
Javed Absard5526302015-06-29 09:32:29 +0000250 case ARM::FV_VFPV3_FP16:
251 Features.push_back("+vfp3");
252 Features.push_back("+fp16");
253 Features.push_back("-vfp4");
254 Features.push_back("-fp-armv8");
255 break;
256 case ARM::FV_VFPV3:
John Brawnd03d2292015-06-05 13:29:24 +0000257 Features.push_back("+vfp3");
John Brawnd9e39d52015-06-12 09:38:51 +0000258 Features.push_back("-fp16");
John Brawnd03d2292015-06-05 13:29:24 +0000259 Features.push_back("-vfp4");
260 Features.push_back("-fp-armv8");
261 break;
Javed Absard5526302015-06-29 09:32:29 +0000262 case ARM::FV_VFPV2:
John Brawnd03d2292015-06-05 13:29:24 +0000263 Features.push_back("+vfp2");
264 Features.push_back("-vfp3");
John Brawnd9e39d52015-06-12 09:38:51 +0000265 Features.push_back("-fp16");
John Brawnd03d2292015-06-05 13:29:24 +0000266 Features.push_back("-vfp4");
267 Features.push_back("-fp-armv8");
268 break;
Javed Absard5526302015-06-29 09:32:29 +0000269 case ARM::FV_NONE:
John Brawnd03d2292015-06-05 13:29:24 +0000270 Features.push_back("-vfp2");
271 Features.push_back("-vfp3");
John Brawnd9e39d52015-06-12 09:38:51 +0000272 Features.push_back("-fp16");
John Brawnd03d2292015-06-05 13:29:24 +0000273 Features.push_back("-vfp4");
274 Features.push_back("-fp-armv8");
275 break;
276 }
277
278 // crypto includes neon, so we handle this similarly to FPU version.
279 switch (FPUNames[FPUKind].NeonSupport) {
280 case ARM::NS_Crypto:
Alexandros Lamprineasea33e5e2015-09-05 17:05:33 +0000281 Features.push_back("+neon");
John Brawnd03d2292015-06-05 13:29:24 +0000282 Features.push_back("+crypto");
283 break;
284 case ARM::NS_Neon:
285 Features.push_back("+neon");
286 Features.push_back("-crypto");
287 break;
288 case ARM::NS_None:
289 Features.push_back("-neon");
290 Features.push_back("-crypto");
291 break;
292 }
293
294 return true;
295}
296
Chandler Carruth3309ef62015-08-30 07:51:04 +0000297StringRef llvm::ARM::getArchName(unsigned ArchKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000298 if (ArchKind >= ARM::AK_LAST)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000299 return StringRef();
300 return ARCHNames[ArchKind].getName();
Renato Golinf5f373f2015-05-08 21:04:27 +0000301}
302
Chandler Carruth3309ef62015-08-30 07:51:04 +0000303StringRef llvm::ARM::getCPUAttr(unsigned ArchKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000304 if (ArchKind >= ARM::AK_LAST)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000305 return StringRef();
306 return ARCHNames[ArchKind].getCPUAttr();
Renato Golinf5f373f2015-05-08 21:04:27 +0000307}
308
Chandler Carruth3309ef62015-08-30 07:51:04 +0000309StringRef llvm::ARM::getSubArch(unsigned ArchKind) {
Renato Golin42dad642015-05-28 15:05:18 +0000310 if (ArchKind >= ARM::AK_LAST)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000311 return StringRef();
312 return ARCHNames[ArchKind].getSubArch();
Renato Golin42dad642015-05-28 15:05:18 +0000313}
314
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000315unsigned llvm::ARM::getArchAttr(unsigned ArchKind) {
Renato Goline8048f02015-05-20 15:05:07 +0000316 if (ArchKind >= ARM::AK_LAST)
317 return ARMBuildAttrs::CPUArch::Pre_v4;
Renato Golinf7c0d5f2015-05-27 18:15:37 +0000318 return ARCHNames[ArchKind].ArchAttr;
Renato Golinf5f373f2015-05-08 21:04:27 +0000319}
320
Chandler Carruth3309ef62015-08-30 07:51:04 +0000321StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000322 for (const auto AE : ARCHExtNames) {
323 if (ArchExtKind == AE.ID)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000324 return AE.getName();
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000325 }
Chandler Carruth3309ef62015-08-30 07:51:04 +0000326 return StringRef();
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000327}
328
Chandler Carruth3309ef62015-08-30 07:51:04 +0000329StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000330 for (const auto D : HWDivNames) {
331 if (HWDivKind == D.ID)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000332 return D.getName();
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000333 }
Chandler Carruth3309ef62015-08-30 07:51:04 +0000334 return StringRef();
Renato Goline8048f02015-05-20 15:05:07 +0000335}
336
Chandler Carruth3309ef62015-08-30 07:51:04 +0000337StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {
Renato Goline8048f02015-05-20 15:05:07 +0000338 unsigned AK = parseArch(Arch);
339 if (AK == ARM::AK_INVALID)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000340 return StringRef();
Renato Goline8048f02015-05-20 15:05:07 +0000341
342 // Look for multiple AKs to find the default for pair AK+Name.
343 for (const auto CPU : CPUNames) {
344 if (CPU.ArchID == AK && CPU.Default)
Chandler Carruth3309ef62015-08-30 07:51:04 +0000345 return CPU.getName();
Renato Goline8048f02015-05-20 15:05:07 +0000346 }
Bradley Smith4adcb732015-11-16 11:15:22 +0000347
348 // If we can't find a default then target the architecture instead
349 return "generic";
Renato Golinf5f373f2015-05-08 21:04:27 +0000350}
351
352// ======================================================= //
353// Parsers
354// ======================================================= //
355
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000356static StringRef getHWDivSynonym(StringRef HWDiv) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000357 return StringSwitch<StringRef>(HWDiv)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000358 .Case("thumb,arm", "arm,thumb")
359 .Default(HWDiv);
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000360}
361
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000362static StringRef getFPUSynonym(StringRef FPU) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000363 return StringSwitch<StringRef>(FPU)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000364 .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
365 .Case("vfp2", "vfpv2")
366 .Case("vfp3", "vfpv3")
367 .Case("vfp4", "vfpv4")
368 .Case("vfp3-d16", "vfpv3-d16")
369 .Case("vfp4-d16", "vfpv4-d16")
370 .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
371 .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
372 .Case("fp5-sp-d16", "fpv5-sp-d16")
373 .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
374 // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
375 .Case("neon-vfpv3", "neon")
376 .Default(FPU);
Renato Golinf5f373f2015-05-08 21:04:27 +0000377}
378
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000379static StringRef getArchSynonym(StringRef Arch) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000380 return StringSwitch<StringRef>(Arch)
Artyom Skrobov2c2f3782015-11-12 15:51:41 +0000381 .Case("v5", "v5t")
382 .Case("v5e", "v5te")
383 .Case("v6hl", "v6k")
384 .Cases("v6m", "v6sm", "v6s-m", "v6-m")
Artyom Skrobovf187a652015-11-16 14:05:32 +0000385 .Cases("v6z", "v6zk", "v6kz")
Artyom Skrobov2c2f3782015-11-12 15:51:41 +0000386 .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000387 .Case("v7r", "v7-r")
388 .Case("v7m", "v7-m")
389 .Case("v7em", "v7e-m")
390 .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
391 .Case("v8.1a", "v8.1-a")
392 .Default(Arch);
Renato Golinf5f373f2015-05-08 21:04:27 +0000393}
394
Renato Goline8048f02015-05-20 15:05:07 +0000395// MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
396// (iwmmxt|xscale)(eb)? is also permitted. If the former, return
Renato Golinebdd12c2015-05-22 20:43:30 +0000397// "v.+", if the latter, return unmodified string, minus 'eb'.
398// If invalid, return empty string.
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000399StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
Renato Goline8048f02015-05-20 15:05:07 +0000400 size_t offset = StringRef::npos;
401 StringRef A = Arch;
Renato Golinb6b9e052015-05-21 13:52:20 +0000402 StringRef Error = "";
Renato Goline8048f02015-05-20 15:05:07 +0000403
404 // Begins with "arm" / "thumb", move past it.
Renato Golinebdd12c2015-05-22 20:43:30 +0000405 if (A.startswith("arm64"))
406 offset = 5;
407 else if (A.startswith("arm"))
Renato Goline8048f02015-05-20 15:05:07 +0000408 offset = 3;
409 else if (A.startswith("thumb"))
410 offset = 5;
Renato Golinb6b9e052015-05-21 13:52:20 +0000411 else if (A.startswith("aarch64")) {
412 offset = 7;
413 // AArch64 uses "_be", not "eb" suffix.
414 if (A.find("eb") != StringRef::npos)
415 return Error;
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000416 if (A.substr(offset, 3) == "_be")
Renato Golinb6b9e052015-05-21 13:52:20 +0000417 offset += 3;
418 }
419
Renato Goline8048f02015-05-20 15:05:07 +0000420 // Ex. "armebv7", move past the "eb".
421 if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
422 offset += 2;
423 // Or, if it ends with eb ("armv7eb"), chop it off.
424 else if (A.endswith("eb"))
425 A = A.substr(0, A.size() - 2);
Renato Golinebdd12c2015-05-22 20:43:30 +0000426 // Trim the head
427 if (offset != StringRef::npos)
Renato Goline8048f02015-05-20 15:05:07 +0000428 A = A.substr(offset);
429
Renato Golinebdd12c2015-05-22 20:43:30 +0000430 // Empty string means offset reached the end, which means it's valid.
Renato Goline8048f02015-05-20 15:05:07 +0000431 if (A.empty())
432 return Arch;
433
Renato Golinebdd12c2015-05-22 20:43:30 +0000434 // Only match non-marketing names
435 if (offset != StringRef::npos) {
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000436 // Must start with 'vN'.
Renato Golinebdd12c2015-05-22 20:43:30 +0000437 if (A[0] != 'v' || !std::isdigit(A[1]))
438 return Error;
439 // Can't have an extra 'eb'.
440 if (A.find("eb") != StringRef::npos)
441 return Error;
442 }
Renato Goline8048f02015-05-20 15:05:07 +0000443
Renato Golinebdd12c2015-05-22 20:43:30 +0000444 // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
Renato Goline8048f02015-05-20 15:05:07 +0000445 return A;
446}
447
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000448unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000449 StringRef Syn = getHWDivSynonym(HWDiv);
450 for (const auto D : HWDivNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000451 if (Syn == D.getName())
Alexandros Lamprineas4ea70752015-07-27 22:26:59 +0000452 return D.ID;
453 }
454 return ARM::AEK_INVALID;
455}
456
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000457unsigned llvm::ARM::parseFPU(StringRef FPU) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000458 StringRef Syn = getFPUSynonym(FPU);
459 for (const auto F : FPUNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000460 if (Syn == F.getName())
Renato Golinf5f373f2015-05-08 21:04:27 +0000461 return F.ID;
462 }
Renato Golin35de35d2015-05-12 10:33:58 +0000463 return ARM::FK_INVALID;
Renato Golinf5f373f2015-05-08 21:04:27 +0000464}
465
Renato Goline8048f02015-05-20 15:05:07 +0000466// Allows partial match, ex. "v7a" matches "armv7a".
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000467unsigned llvm::ARM::parseArch(StringRef Arch) {
Artyom Skrobov85aebc82015-06-04 21:26:58 +0000468 Arch = getCanonicalArchName(Arch);
Renato Golinf5f373f2015-05-08 21:04:27 +0000469 StringRef Syn = getArchSynonym(Arch);
470 for (const auto A : ARCHNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000471 if (A.getName().endswith(Syn))
Renato Golinf5f373f2015-05-08 21:04:27 +0000472 return A.ID;
473 }
Renato Golin35de35d2015-05-12 10:33:58 +0000474 return ARM::AK_INVALID;
Renato Golinf5f373f2015-05-08 21:04:27 +0000475}
476
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000477unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
Renato Golinf5f373f2015-05-08 21:04:27 +0000478 for (const auto A : ARCHExtNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000479 if (ArchExt == A.getName())
Renato Golinf5f373f2015-05-08 21:04:27 +0000480 return A.ID;
481 }
Renato Golin35de35d2015-05-12 10:33:58 +0000482 return ARM::AEK_INVALID;
Renato Golinf5f373f2015-05-08 21:04:27 +0000483}
484
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000485unsigned llvm::ARM::parseCPUArch(StringRef CPU) {
Renato Goline8048f02015-05-20 15:05:07 +0000486 for (const auto C : CPUNames) {
Chandler Carruth3309ef62015-08-30 07:51:04 +0000487 if (CPU == C.getName())
Renato Goline8048f02015-05-20 15:05:07 +0000488 return C.ArchID;
489 }
490 return ARM::AK_INVALID;
491}
492
Renato Golinb6b9e052015-05-21 13:52:20 +0000493// ARM, Thumb, AArch64
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000494unsigned llvm::ARM::parseArchISA(StringRef Arch) {
Renato Golinb6b9e052015-05-21 13:52:20 +0000495 return StringSwitch<unsigned>(Arch)
496 .StartsWith("aarch64", ARM::IK_AARCH64)
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000497 .StartsWith("arm64", ARM::IK_AARCH64)
498 .StartsWith("thumb", ARM::IK_THUMB)
499 .StartsWith("arm", ARM::IK_ARM)
Renato Golinb6b9e052015-05-21 13:52:20 +0000500 .Default(ARM::EK_INVALID);
501}
502
503// Little/Big endian
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000504unsigned llvm::ARM::parseArchEndian(StringRef Arch) {
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000505 if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
Renato Golinb6b9e052015-05-21 13:52:20 +0000506 Arch.startswith("aarch64_be"))
507 return ARM::EK_BIG;
508
509 if (Arch.startswith("arm") || Arch.startswith("thumb")) {
510 if (Arch.endswith("eb"))
511 return ARM::EK_BIG;
512 else
513 return ARM::EK_LITTLE;
514 }
515
516 if (Arch.startswith("aarch64"))
517 return ARM::EK_LITTLE;
518
519 return ARM::EK_INVALID;
520}
521
Renato Golinfadc2102015-05-22 18:17:55 +0000522// Profile A/R/M
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000523unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
Renato Golinfadc2102015-05-22 18:17:55 +0000524 Arch = getCanonicalArchName(Arch);
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000525 switch (parseArch(Arch)) {
Renato Golinfadc2102015-05-22 18:17:55 +0000526 case ARM::AK_ARMV6M:
527 case ARM::AK_ARMV7M:
Renato Golinfadc2102015-05-22 18:17:55 +0000528 case ARM::AK_ARMV7EM:
529 return ARM::PK_M;
530 case ARM::AK_ARMV7R:
531 return ARM::PK_R;
Renato Golinfadc2102015-05-22 18:17:55 +0000532 case ARM::AK_ARMV7A:
Tim Northover2d4d1612015-10-28 22:36:05 +0000533 case ARM::AK_ARMV7K:
Renato Golinfadc2102015-05-22 18:17:55 +0000534 case ARM::AK_ARMV8A:
535 case ARM::AK_ARMV8_1A:
536 return ARM::PK_A;
537 }
538 return ARM::PK_INVALID;
539}
540
Renato Golinebdd12c2015-05-22 20:43:30 +0000541// Version number (ex. v7 = 7).
Chandler Carruthbb47b9a2015-08-30 02:09:48 +0000542unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
Renato Golinfadc2102015-05-22 18:17:55 +0000543 Arch = getCanonicalArchName(Arch);
Chandler Carruth4fc3a982015-08-30 02:17:15 +0000544 switch (parseArch(Arch)) {
Renato Golinfadc2102015-05-22 18:17:55 +0000545 case ARM::AK_ARMV2:
546 case ARM::AK_ARMV2A:
547 return 2;
548 case ARM::AK_ARMV3:
549 case ARM::AK_ARMV3M:
550 return 3;
551 case ARM::AK_ARMV4:
552 case ARM::AK_ARMV4T:
553 return 4;
Renato Golinfadc2102015-05-22 18:17:55 +0000554 case ARM::AK_ARMV5T:
555 case ARM::AK_ARMV5TE:
556 case ARM::AK_IWMMXT:
557 case ARM::AK_IWMMXT2:
558 case ARM::AK_XSCALE:
Renato Golinfadc2102015-05-22 18:17:55 +0000559 case ARM::AK_ARMV5TEJ:
560 return 5;
561 case ARM::AK_ARMV6:
562 case ARM::AK_ARMV6J:
563 case ARM::AK_ARMV6K:
564 case ARM::AK_ARMV6T2:
Artyom Skrobovf187a652015-11-16 14:05:32 +0000565 case ARM::AK_ARMV6KZ:
Renato Golinfadc2102015-05-22 18:17:55 +0000566 case ARM::AK_ARMV6M:
Renato Golinfadc2102015-05-22 18:17:55 +0000567 return 6;
Renato Golinfadc2102015-05-22 18:17:55 +0000568 case ARM::AK_ARMV7A:
569 case ARM::AK_ARMV7R:
570 case ARM::AK_ARMV7M:
Renato Golinfadc2102015-05-22 18:17:55 +0000571 case ARM::AK_ARMV7S:
572 case ARM::AK_ARMV7EM:
Vedant Kumar366dd9fd2015-08-21 21:52:48 +0000573 case ARM::AK_ARMV7K:
Renato Golinfadc2102015-05-22 18:17:55 +0000574 return 7;
575 case ARM::AK_ARMV8A:
576 case ARM::AK_ARMV8_1A:
577 return 8;
578 }
579 return 0;
580}