LLVM: lib/TargetParser/ARMTargetParser.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
20#include
21
22using namespace llvm;
23
26 .Case("thumb,arm", "arm,thumb")
28}
29
30
34 for (const auto &A : ARMArchNames) {
35 if (A.Name.ends_with(Syn))
36 return A.ID;
37 }
38 return ArchKind::INVALID;
39}
40
41
45 case ArchKind::ARMV4:
46 case ArchKind::ARMV4T:
47 return 4;
48 case ArchKind::ARMV5T:
49 case ArchKind::ARMV5TE:
50 case ArchKind::IWMMXT:
51 case ArchKind::IWMMXT2:
52 case ArchKind::XSCALE:
53 case ArchKind::ARMV5TEJ:
54 return 5;
55 case ArchKind::ARMV6:
56 case ArchKind::ARMV6K:
57 case ArchKind::ARMV6T2:
58 case ArchKind::ARMV6KZ:
59 case ArchKind::ARMV6M:
60 return 6;
61 case ArchKind::ARMV7A:
62 case ArchKind::ARMV7VE:
63 case ArchKind::ARMV7R:
64 case ArchKind::ARMV7M:
65 case ArchKind::ARMV7S:
66 case ArchKind::ARMV7EM:
67 case ArchKind::ARMV7K:
68 return 7;
69 case ArchKind::ARMV8A:
70 case ArchKind::ARMV8_1A:
71 case ArchKind::ARMV8_2A:
72 case ArchKind::ARMV8_3A:
73 case ArchKind::ARMV8_4A:
74 case ArchKind::ARMV8_5A:
75 case ArchKind::ARMV8_6A:
76 case ArchKind::ARMV8_7A:
77 case ArchKind::ARMV8_8A:
78 case ArchKind::ARMV8_9A:
79 case ArchKind::ARMV8R:
80 case ArchKind::ARMV8MBaseline:
81 case ArchKind::ARMV8MMainline:
82 case ArchKind::ARMV8_1MMainline:
83 return 8;
84 case ArchKind::ARMV9A:
85 case ArchKind::ARMV9_1A:
86 case ArchKind::ARMV9_2A:
87 case ArchKind::ARMV9_3A:
88 case ArchKind::ARMV9_4A:
89 case ArchKind::ARMV9_5A:
90 case ArchKind::ARMV9_6A:
91 return 9;
92 case ArchKind::INVALID:
93 return 0;
94 }
96}
97
99 switch (AK) {
100 case ARM::ArchKind::ARMV6M:
101 case ARM::ArchKind::ARMV7M:
102 case ARM::ArchKind::ARMV7EM:
103 case ARM::ArchKind::ARMV8MMainline:
104 case ARM::ArchKind::ARMV8MBaseline:
105 case ARM::ArchKind::ARMV8_1MMainline:
106 return ARM::ProfileKind::M;
107 case ARM::ArchKind::ARMV7R:
108 case ARM::ArchKind::ARMV8R:
109 return ARM::ProfileKind::R;
110 case ARM::ArchKind::ARMV7A:
111 case ARM::ArchKind::ARMV7VE:
112 case ARM::ArchKind::ARMV7K:
113 case ARM::ArchKind::ARMV8A:
114 case ARM::ArchKind::ARMV8_1A:
115 case ARM::ArchKind::ARMV8_2A:
116 case ARM::ArchKind::ARMV8_3A:
117 case ARM::ArchKind::ARMV8_4A:
118 case ARM::ArchKind::ARMV8_5A:
119 case ARM::ArchKind::ARMV8_6A:
120 case ARM::ArchKind::ARMV8_7A:
121 case ARM::ArchKind::ARMV8_8A:
122 case ARM::ArchKind::ARMV8_9A:
123 case ARM::ArchKind::ARMV9A:
124 case ARM::ArchKind::ARMV9_1A:
125 case ARM::ArchKind::ARMV9_2A:
126 case ARM::ArchKind::ARMV9_3A:
127 case ARM::ArchKind::ARMV9_4A:
128 case ARM::ArchKind::ARMV9_5A:
129 case ARM::ArchKind::ARMV9_6A:
130 return ARM::ProfileKind::A;
131 case ARM::ArchKind::ARMV4:
132 case ARM::ArchKind::ARMV4T:
133 case ARM::ArchKind::ARMV5T:
134 case ARM::ArchKind::ARMV5TE:
135 case ARM::ArchKind::ARMV5TEJ:
136 case ARM::ArchKind::ARMV6:
137 case ARM::ArchKind::ARMV6K:
138 case ARM::ArchKind::ARMV6T2:
139 case ARM::ArchKind::ARMV6KZ:
140 case ARM::ArchKind::ARMV7S:
141 case ARM::ArchKind::IWMMXT:
142 case ARM::ArchKind::IWMMXT2:
143 case ARM::ArchKind::XSCALE:
144 case ARM::ArchKind::INVALID:
145 return ARM::ProfileKind::INVALID;
146 }
148}
149
150
154}
155
157 std::vector &Features) {
158
160 return false;
161
162 static const struct FPUFeatureNameInfo {
163 const char *PlusName, *MinusName;
166 } FPUFeatureInfoList[] = {
167
168
169
170
171
172
173
174 {"+vfp2", "-vfp2", FPUVersion::VFPV2, FPURestriction::D16},
175 {"+vfp2sp", "-vfp2sp", FPUVersion::VFPV2, FPURestriction::SP_D16},
176 {"+vfp3", "-vfp3", FPUVersion::VFPV3, FPURestriction::None},
177 {"+vfp3d16", "-vfp3d16", FPUVersion::VFPV3, FPURestriction::D16},
178 {"+vfp3d16sp", "-vfp3d16sp", FPUVersion::VFPV3, FPURestriction::SP_D16},
179 {"+vfp3sp", "-vfp3sp", FPUVersion::VFPV3, FPURestriction::None},
180 {"+fp16", "-fp16", FPUVersion::VFPV3_FP16, FPURestriction::SP_D16},
181 {"+vfp4", "-vfp4", FPUVersion::VFPV4, FPURestriction::None},
182 {"+vfp4d16", "-vfp4d16", FPUVersion::VFPV4, FPURestriction::D16},
183 {"+vfp4d16sp", "-vfp4d16sp", FPUVersion::VFPV4, FPURestriction::SP_D16},
184 {"+vfp4sp", "-vfp4sp", FPUVersion::VFPV4, FPURestriction::None},
185 {"+fp-armv8", "-fp-armv8", FPUVersion::VFPV5, FPURestriction::None},
186 {"+fp-armv8d16", "-fp-armv8d16", FPUVersion::VFPV5, FPURestriction::D16},
187 {"+fp-armv8d16sp", "-fp-armv8d16sp", FPUVersion::VFPV5, FPURestriction::SP_D16},
188 {"+fp-armv8sp", "-fp-armv8sp", FPUVersion::VFPV5, FPURestriction::None},
189 {"+fullfp16", "-fullfp16", FPUVersion::VFPV5_FULLFP16, FPURestriction::SP_D16},
190 {"+fp64", "-fp64", FPUVersion::VFPV2, FPURestriction::D16},
191 {"+d32", "-d32", FPUVersion::VFPV3, FPURestriction::None},
192 };
193
194 for (const auto &Info: FPUFeatureInfoList) {
195 if (FPUNames[FPUKind].FPUVer >= Info.MinVersion &&
196 FPUNames[FPUKind].Restriction <= Info.MaxRestriction)
197 Features.push_back(Info.PlusName);
198 else
199 Features.push_back(Info.MinusName);
200 }
201
202 static const struct NeonFeatureNameInfo {
203 const char *PlusName, *MinusName;
205 } NeonFeatureInfoList[] = {
206 {"+neon", "-neon", NeonSupportLevel::Neon},
207 {"+sha2", "-sha2", NeonSupportLevel::Crypto},
208 {"+aes", "-aes", NeonSupportLevel::Crypto},
209 };
210
211 for (const auto &Info: NeonFeatureInfoList) {
212 if (FPUNames[FPUKind].NeonSupport >= Info.MinSupportLevel)
213 Features.push_back(Info.PlusName);
214 else
215 Features.push_back(Info.MinusName);
216 }
217
218 return true;
219}
220
223 for (const auto &F : FPUNames) {
224 if (Syn == F.Name)
225 return F.ID;
226 }
227 return FK_INVALID;
228}
229
232 return NeonSupportLevel::None;
233 return FPUNames[FPUKind].NeonSupport;
234}
235
238 .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid")
239 .Case("vfp2", "vfpv2")
240 .Case("vfp3", "vfpv3")
241 .Case("vfp4", "vfpv4")
242 .Case("vfp3-d16", "vfpv3-d16")
243 .Case("vfp4-d16", "vfpv4-d16")
244 .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
245 .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
246 .Case("fp5-sp-d16", "fpv5-sp-d16")
247 .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
248
249 .Case("neon-vfpv3", "neon")
251}
252
256 return FPUNames[FPUKind].Name;
257}
258
261 return FPUVersion::NONE;
262 return FPUNames[FPUKind].FPUVer;
263}
264
267 return FPURestriction::None;
268 return FPUNames[FPUKind].Restriction;
269}
270
272 if (CPU == "generic")
274
276#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
277 .Case(NAME, DEFAULT_FPU)
278#include "llvm/TargetParser/ARMTargetParser.def"
279 .Default(ARM::FK_INVALID);
280}
281
283 if (CPU == "generic")
284 return ARM::ARMArchNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
285
287#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
288 .Case(NAME, \
289 ARMArchNames[static_cast(ArchKind::ID)].ArchBaseExtensions | \
290 DEFAULT_EXT)
291#include "llvm/TargetParser/ARMTargetParser.def"
293}
294
296 std::vector &Features) {
297
299 return false;
300
302 Features.push_back("+hwdiv-arm");
303 else
304 Features.push_back("-hwdiv-arm");
305
307 Features.push_back("+hwdiv");
308 else
309 Features.push_back("-hwdiv");
310
311 return true;
312}
313
315 std::vector &Features) {
316
318 return false;
319
321 if ((Extensions & AE.ID) == AE.ID && !AE.Feature.empty())
322 Features.push_back(AE.Feature);
323 else if (!AE.NegFeature.empty())
324 Features.push_back(AE.NegFeature);
325 }
326
328}
329
331 return ARMArchNames[static_cast<unsigned>(AK)].Name;
332}
333
335 return ARMArchNames[static_cast<unsigned>(AK)].CPUAttr;
336}
337
339 return ARMArchNames[static_cast<unsigned>(AK)].getSubArch();
340}
341
343 return ARMArchNames[static_cast<unsigned>(AK)].ArchAttr;
344}
345
349 return AE.Name;
350 }
352}
353
355 return Name.consume_front("no");
356}
357
361 if (!AE.Feature.empty() && ArchExt == AE.Name)
362 return StringRef(Negated ? AE.NegFeature : AE.Feature);
363 }
364
366}
367
369 if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
370 return ARM::FK_INVALID;
371
373
374
375
377 return InputFPUKind;
378
379
380
382 if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
383 CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
387 return CandidateFPU.ID;
388 }
389 }
390
391
392 return ARM::FK_INVALID;
393}
394
396 if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
397 return ARM::FK_INVALID;
398
400
401
402
404 return InputFPUKind;
405
406
407
409 if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
410 CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
414 return CandidateFPU.ID;
415 }
416 }
417
418
419 return ARM::FK_INVALID;
420}
421
424 std::vector &Features,
426
427 size_t StartingNumFeatures = Features.size();
430
432 return false;
433
435 if (Negated) {
436 if ((AE.ID & ID) == ID && !AE.NegFeature.empty())
437 Features.push_back(AE.NegFeature);
438 } else {
439 if ((AE.ID & ID) == AE.ID && !AE.Feature.empty())
440 Features.push_back(AE.Feature);
441 }
442 }
443
444 if (CPU == "")
445 CPU = "generic";
446
447 if (ArchExt == "fp" || ArchExt == "fp.dp") {
450 if (ArchExt == "fp.dp") {
451 const bool IsDP = ArgFPUKind != ARM::FK_INVALID &&
452 ArgFPUKind != ARM::FK_NONE &&
454 if (Negated) {
455
456
457
458 if (ArgFPUKind != ARM::FK_INVALID && !IsDP)
459 return true;
461 if (FPUKind == ARM::FK_INVALID)
463 } else {
464 if (IsDP)
465 return true;
467 if (FPUKind == ARM::FK_INVALID)
468 return false;
469 }
470 } else if (Negated) {
472 } else {
474 }
476 return true;
477 }
478 return StartingNumFeatures != Features.size();
479}
480
483 return ARM::ArchKind::INVALID;
484 if (AK < ARM::ArchKind::ARMV9A || AK > ARM::ArchKind::ARMV9_3A)
485 return ARM::ArchKind::INVALID;
486 unsigned AK_v8 = static_cast<unsigned>(ARM::ArchKind::ARMV8_5A);
487 AK_v8 += static_cast<unsigned>(AK) -
488 static_cast<unsigned>(ARM::ArchKind::ARMV9A);
490}
491
494 if (AK == ArchKind::INVALID)
496
497
498 for (const auto &CPU : CPUNames) {
499 if (CPU.ArchID == AK && CPU.Default)
500 return CPU.Name;
501 }
502
503
504 return "generic";
505}
506
510 if (Syn == D.Name)
511 return D.ID;
512 }
514}
515
518 if (ArchExt == A.Name)
519 return A.ID;
520 }
522}
523
526 if (CPU == C.Name)
527 return C.ArchID;
528 }
529 return ArchKind::INVALID;
530}
531
533 for (const auto &Arch : CPUNames) {
534 if (Arch.ArchID != ArchKind::INVALID)
536 }
537}
538
542
543 if (TT.isOSBinFormatMachO()) {
547 return "aapcs";
548 if (TT.isWatchABI())
549 return "aapcs16";
550 return "apcs-gnu";
551 } else if (TT.isOSWindows())
552
553 return "aapcs";
554
555
556 switch (TT.getEnvironment()) {
565 return "aapcs-linux";
568 return "aapcs";
569 default:
570 if (TT.isOSNetBSD())
571 return "apcs-gnu";
572 if (TT.isOSFreeBSD() || TT.isOSOpenBSD() || TT.isOSHaiku() ||
573 TT.isOHOSFamily())
574 return "aapcs-linux";
575 return "aapcs";
576 }
577}
578
580 if (MArch.empty())
583
584
590 if (!MArch.empty() && MArch == "v6")
591 return "arm1176jzf-s";
592 if (!MArch.empty() && MArch == "v7")
593 return "cortex-a8";
594 break;
596
598 return "cortex-a9";
599 break;
606 if (MArch == "v7k")
607 return "cortex-a7";
608 break;
609 default:
610 break;
611 }
612
613 if (MArch.empty())
615
617 if (!CPU.empty() && CPU != "invalid")
618 return CPU;
619
620
621
624 return "arm1176jzf-s";
631 return "arm926ej-s";
632 default:
633 return "strongarm";
634 }
637 return "cortex-a8";
638 default:
644 return "arm1176jzf-s";
645 default:
646 return "arm7tdmi";
647 }
648 }
649
651}
652
654 outs() << "All available -march extensions for ARM\n\n"
656 << (DescMap.empty() ? "\n" : "Description\n");
658
659 if (!Ext.Feature.empty()) {
660 std::string Description = DescMap[Ext.Name].str();
661 outs() << " "
662 << format(Description.empty() ? "%s\n" : "%-20s%s\n",
663 Ext.Name.str().c_str(), Description.c_str());
664 }
665 }
666}
static ARM::FPUKind findSinglePrecisionFPU(ARM::FPUKind InputFPUKind)
static StringRef getHWDivSynonym(StringRef HWDiv)
static bool stripNegationPrefix(StringRef &Name)
static ARM::ProfileKind getProfileKind(ARM::ArchKind AK)
static ARM::FPUKind findDoublePrecisionFPU(ARM::FPUKind InputFPUKind)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Analysis containing CSE Info
static cl::opt< std::set< SPIRV::Extension::Extension >, false, SPIRVExtensionsParser > Extensions("spirv-ext", cl::desc("Specify list of enabled SPIR-V extensions"))
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static Triple::ArchType parseArch(StringRef ArchName)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Triple - Helper class for working with autoconf configuration names.
OSType getOS() const
Get the parsed operating system type of this triple.
EnvironmentType getEnvironment() const
Get the parsed environment type of this triple.
StringRef getArchName() const
Get the architecture (first) component of the triple.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
StringRef getArchExtName(uint64_t ArchExtKind)
StringRef getFPUSynonym(StringRef FPU)
bool getFPUFeatures(FPUKind FPUKind, std::vector< StringRef > &Features)
StringRef getCanonicalArchName(StringRef Arch)
MArch is expected to be of the form (arm|thumb)?(eb)?(v.
uint64_t parseHWDiv(StringRef HWDiv)
StringRef getCPUAttr(ArchKind AK)
const struct llvm::ARM::@432 HWDivNames[]
StringRef getArchName(ArchKind AK)
StringRef computeDefaultTargetABI(const Triple &TT, StringRef CPU)
void fillValidCPUArchList(SmallVectorImpl< StringRef > &Values)
static const FPUName FPUNames[]
uint64_t parseArchExt(StringRef ArchExt)
ArchKind convertV9toV8(ArchKind AK)
ArchKind parseArch(StringRef Arch)
FPURestriction getFPURestriction(FPUKind FPUKind)
bool appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK, StringRef ArchExt, std::vector< StringRef > &Features, FPUKind &ArgFPUKind)
StringRef getArchSynonym(StringRef Arch)
Converts e.g. "armv8" -> "armv8-a".
StringRef getDefaultCPU(StringRef Arch)
StringRef getArchExtFeature(StringRef ArchExt)
const CpuNames CPUNames[]
ProfileKind parseArchProfile(StringRef Arch)
FPUKind parseFPU(StringRef FPU)
StringRef getSubArch(ArchKind AK)
static const ArchNames ARMArchNames[]
StringRef getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch={})
Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
unsigned parseArchVersion(StringRef Arch)
const ExtName ARCHExtNames[]
bool has32Regs(const FPURestriction restriction)
NeonSupportLevel getFPUNeonSupportLevel(FPUKind FPUKind)
ArchKind parseCPUArch(StringRef CPU)
bool isDoublePrecision(const FPURestriction restriction)
unsigned getArchAttr(ArchKind AK)
StringRef getFPUName(FPUKind FPUKind)
FPUVersion getFPUVersion(FPUKind FPUKind)
bool getHWDivFeatures(uint64_t HWDivKind, std::vector< StringRef > &Features)
uint64_t getDefaultExtensions(StringRef CPU, ArchKind AK)
FPUKind getDefaultFPU(StringRef CPU, ArchKind AK)
bool getExtensionFeatures(uint64_t Extensions, std::vector< StringRef > &Features)
void PrintSupportedExtensions(StringMap< StringRef > DescMap)
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
FormattedString left_justify(StringRef Str, unsigned Width)
left_justify - append spaces after string so total output is Width characters.
FPURestriction Restriction
NeonSupportLevel NeonSupport