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
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 case ArchKind::ARMV9_7A:
92 return 9;
93 case ArchKind::INVALID:
94 return 0;
95 }
97}
98
100 switch (AK) {
101 case ARM::ArchKind::ARMV6M:
102 case ARM::ArchKind::ARMV7M:
103 case ARM::ArchKind::ARMV7EM:
104 case ARM::ArchKind::ARMV8MMainline:
105 case ARM::ArchKind::ARMV8MBaseline:
106 case ARM::ArchKind::ARMV8_1MMainline:
108 case ARM::ArchKind::ARMV7R:
109 case ARM::ArchKind::ARMV8R:
111 case ARM::ArchKind::ARMV7A:
112 case ARM::ArchKind::ARMV7VE:
113 case ARM::ArchKind::ARMV7K:
114 case ARM::ArchKind::ARMV8A:
115 case ARM::ArchKind::ARMV8_1A:
116 case ARM::ArchKind::ARMV8_2A:
117 case ARM::ArchKind::ARMV8_3A:
118 case ARM::ArchKind::ARMV8_4A:
119 case ARM::ArchKind::ARMV8_5A:
120 case ARM::ArchKind::ARMV8_6A:
121 case ARM::ArchKind::ARMV8_7A:
122 case ARM::ArchKind::ARMV8_8A:
123 case ARM::ArchKind::ARMV8_9A:
124 case ARM::ArchKind::ARMV9A:
125 case ARM::ArchKind::ARMV9_1A:
126 case ARM::ArchKind::ARMV9_2A:
127 case ARM::ArchKind::ARMV9_3A:
128 case ARM::ArchKind::ARMV9_4A:
129 case ARM::ArchKind::ARMV9_5A:
130 case ARM::ArchKind::ARMV9_6A:
131 case ARM::ArchKind::ARMV9_7A:
133 case ARM::ArchKind::ARMV4:
134 case ARM::ArchKind::ARMV4T:
135 case ARM::ArchKind::ARMV5T:
136 case ARM::ArchKind::ARMV5TE:
137 case ARM::ArchKind::ARMV5TEJ:
138 case ARM::ArchKind::ARMV6:
139 case ARM::ArchKind::ARMV6K:
140 case ARM::ArchKind::ARMV6T2:
141 case ARM::ArchKind::ARMV6KZ:
142 case ARM::ArchKind::ARMV7S:
143 case ARM::ArchKind::IWMMXT:
144 case ARM::ArchKind::IWMMXT2:
145 case ARM::ArchKind::XSCALE:
146 case ARM::ArchKind::INVALID:
148 }
150}
151
152
157
159 std::vector &Features) {
160
162 return false;
163
164 static const struct FPUFeatureNameInfo {
165 const char *PlusName, *MinusName;
168 } FPUFeatureInfoList[] = {
169
170
171
172
173
174
175
194 };
195
196 for (const auto &Info: FPUFeatureInfoList) {
199 Features.push_back(Info.PlusName);
200 else
201 Features.push_back(Info.MinusName);
202 }
203
204 static const struct NeonFeatureNameInfo {
205 const char *PlusName, *MinusName;
207 } NeonFeatureInfoList[] = {
211 };
212
213 for (const auto &Info: NeonFeatureInfoList) {
214 if (FPUNames[FPUKind].NeonSupport >= Info.MinSupportLevel)
215 Features.push_back(Info.PlusName);
216 else
217 Features.push_back(Info.MinusName);
218 }
219
220 return true;
221}
222
226 if (Syn == F.Name)
227 return F.ID;
228 }
229 return FK_INVALID;
230}
231
237
240 .Cases({"fpa", "fpe2", "fpe3", "maverick"}, "invalid")
241 .Case("vfp2", "vfpv2")
242 .Case("vfp3", "vfpv3")
243 .Case("vfp4", "vfpv4")
244 .Case("vfp3-d16", "vfpv3-d16")
245 .Case("vfp4-d16", "vfpv4-d16")
246 .Cases({"fp4-sp-d16", "vfpv4-sp-d16"}, "fpv4-sp-d16")
247 .Cases({"fp4-dp-d16", "fpv4-dp-d16"}, "vfpv4-d16")
248 .Case("fp5-sp-d16", "fpv5-sp-d16")
249 .Cases({"fp5-dp-d16", "fpv5-dp-d16"}, "fpv5-d16")
250
251 .Case("neon-vfpv3", "neon")
253}
254
260
266
272
274 if (CPU == "generic")
276
278#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
279 .Case(NAME, DEFAULT_FPU)
280#include "llvm/TargetParser/ARMTargetParser.def"
281 .Default(ARM::FK_INVALID);
282}
283
285 if (CPU == "generic")
286 return ARM::ARMArchNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
287
289#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
290 .Case(NAME, \
291 ARMArchNames[static_cast(ArchKind::ID)].ArchBaseExtensions | \
292 DEFAULT_EXT)
293#include "llvm/TargetParser/ARMTargetParser.def"
295}
296
298 std::vector &Features) {
299
301 return false;
302
304 Features.push_back("+hwdiv-arm");
305 else
306 Features.push_back("-hwdiv-arm");
307
309 Features.push_back("+hwdiv");
310 else
311 Features.push_back("-hwdiv");
312
313 return true;
314}
315
317 std::vector &Features) {
318
320 return false;
321
323 if ((Extensions & AE.ID) == AE.ID && !AE.Feature.empty())
324 Features.push_back(AE.Feature);
325 else if (!AE.NegFeature.empty())
326 Features.push_back(AE.NegFeature);
327 }
328
330}
331
335
337 return ARMArchNames[static_cast<unsigned>(AK)].CPUAttr;
338}
339
343
345 return ARMArchNames[static_cast<unsigned>(AK)].ArchAttr;
346}
347
351 return AE.Name;
352 }
354}
355
357 return Name.consume_front("no");
358}
359
363 if (!AE.Feature.empty() && ArchExt == AE.Name)
364 return StringRef(Negated ? AE.NegFeature : AE.Feature);
365 }
366
368}
369
371 if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
372 return ARM::FK_INVALID;
373
375
376
377
379 return InputFPUKind;
380
381
382
384 if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
385 CandidateFPU.NeonSupport == InputFPU.NeonSupport &&
389 return CandidateFPU.ID;
390 }
391 }
392
393
394 return ARM::FK_INVALID;
395}
396
398 if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE)
399 return ARM::FK_INVALID;
400
402
403
404
406 return InputFPUKind;
407
408
409
410
411
413 if (CandidateFPU.FPUVer == InputFPU.FPUVer &&
415 return CandidateFPU.ID;
416 }
417 }
418
419
420 return ARM::FK_INVALID;
421}
422
425 std::vector &Features,
427
428 size_t StartingNumFeatures = Features.size();
431
433 return false;
434
436 if (Negated) {
437 if ((AE.ID & ID) == ID && !AE.NegFeature.empty())
438 Features.push_back(AE.NegFeature);
439 } else {
440 if ((AE.ID & ID) == AE.ID && !AE.Feature.empty())
441 Features.push_back(AE.Feature);
442 }
443 }
444
445 if (CPU == "")
446 CPU = "generic";
447
448 if (ArchExt == "fp" || ArchExt == "fp.dp") {
451 if (ArchExt == "fp.dp") {
452 const bool IsDP = ArgFPUKind != ARM::FK_INVALID &&
453 ArgFPUKind != ARM::FK_NONE &&
455 if (Negated) {
456
457
458
459 if (ArgFPUKind != ARM::FK_INVALID && !IsDP)
460 return true;
462 if (FPUKind == ARM::FK_INVALID)
464 } else {
465 if (IsDP)
466 return true;
468 if (FPUKind == ARM::FK_INVALID)
469 return false;
470 }
471 } else if (Negated) {
473 } else {
475 }
477 return true;
478 }
479 return StartingNumFeatures != Features.size();
480}
481
484 return ARM::ArchKind::INVALID;
485 if (AK < ARM::ArchKind::ARMV9A || AK > ARM::ArchKind::ARMV9_3A)
486 return ARM::ArchKind::INVALID;
487 unsigned AK_v8 = static_cast<unsigned>(ARM::ArchKind::ARMV8_5A);
488 AK_v8 += static_cast<unsigned>(AK) -
489 static_cast<unsigned>(ARM::ArchKind::ARMV9A);
491}
492
495 if (AK == ArchKind::INVALID)
497
498
499 for (const auto &CPU : CPUNames) {
500 if (CPU.ArchID == AK && CPU.Default)
501 return CPU.Name;
502 }
503
504
505 return "generic";
506}
507
511 if (Syn == D.Name)
512 return D.ID;
513 }
515}
516
519 if (ArchExt == A.Name)
520 return A.ID;
521 }
523}
524
527 if (CPU == C.Name)
528 return C.ArchID;
529 }
530 return ArchKind::INVALID;
531}
532
534 for (const auto &Arch : CPUNames) {
535 if (Arch.ArchID != ArchKind::INVALID)
537 }
538}
539
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.isOSFuchsia() || TT.isOSOpenBSD() ||
573 TT.isOSHaiku() || TT.isOHOSFamily())
574 return "aapcs-linux";
575 return "aapcs";
576 }
577}
578
580 if (ABIName.empty())
582
583 if (ABIName == "aapcs16")
585
588
591
593}
594
596 if (MArch.empty())
599
600
606 if (!MArch.empty() && MArch == "v6")
607 return "arm1176jzf-s";
608 if (!MArch.empty() && MArch == "v7")
609 return "cortex-a8";
610 break;
612
614 return "cortex-a9";
615 break;
622 if (MArch == "v7k")
623 return "cortex-a7";
624 break;
625 default:
626 break;
627 }
628
629 if (MArch.empty())
631
633 if (!CPU.empty() && CPU != "invalid")
634 return CPU;
635
636
637
640 return "arm1176jzf-s";
647 return "arm926ej-s";
648 default:
649 return "strongarm";
650 }
652 return "cortex-a8";
654 return "cortex-a53";
655 default:
661 return "arm1176jzf-s";
662 default:
663 return "arm7tdmi";
664 }
665 }
666
668}
669
671 outs() << "All available -march extensions for ARM\n\n"
673 << (DescMap.empty() ? "\n" : "Description\n");
675
676 if (!Ext.Feature.empty()) {
677 std::string Description = DescMap[Ext.Name].str();
678
679
680 if (Ext.Name == "simd")
681 Description = DescMap["neon"].str();
682 outs() << " "
683 << format(Description.empty() ? "%s\n" : "%-20s%s\n",
684 Ext.Name.str().c_str(), Description.c_str());
685 }
686 }
687}
static ARM::FPUKind findSinglePrecisionFPU(ARM::FPUKind InputFPUKind)
Definition ARMTargetParser.cpp:397
static StringRef getHWDivSynonym(StringRef HWDiv)
Definition ARMTargetParser.cpp:24
static bool stripNegationPrefix(StringRef &Name)
Definition ARMTargetParser.cpp:356
static ARM::ProfileKind getProfileKind(ARM::ArchKind AK)
Definition ARMTargetParser.cpp:99
static ARM::FPUKind findDoublePrecisionFPU(ARM::FPUKind InputFPUKind)
Definition ARMTargetParser.cpp:370
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
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.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
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(std::initializer_list< StringLiteral > CaseStrings, 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.
LLVM_ABI 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.
constexpr struct llvm::ARM::@324103115345140202011004052154345301224214323271 HWDivNames[]
LLVM_ABI StringRef getArchExtName(uint64_t ArchExtKind)
Definition ARMTargetParser.cpp:348
LLVM_ABI StringRef getFPUSynonym(StringRef FPU)
Definition ARMTargetParser.cpp:238
LLVM_ABI bool getFPUFeatures(FPUKind FPUKind, std::vector< StringRef > &Features)
Definition ARMTargetParser.cpp:158
LLVM_ABI StringRef getCanonicalArchName(StringRef Arch)
MArch is expected to be of the form (arm|thumb)?(eb)?(v.
LLVM_ABI uint64_t parseHWDiv(StringRef HWDiv)
Definition ARMTargetParser.cpp:508
LLVM_ABI StringRef getCPUAttr(ArchKind AK)
Definition ARMTargetParser.cpp:336
LLVM_ABI StringRef getArchName(ArchKind AK)
Definition ARMTargetParser.cpp:332
LLVM_ABI void fillValidCPUArchList(SmallVectorImpl< StringRef > &Values)
Definition ARMTargetParser.cpp:533
LLVM_ABI LLVM_READONLY ARMABI computeTargetABI(const Triple &TT, StringRef ABIName="")
Definition ARMTargetParser.cpp:579
LLVM_ABI uint64_t parseArchExt(StringRef ArchExt)
Definition ARMTargetParser.cpp:517
LLVM_ABI ArchKind convertV9toV8(ArchKind AK)
Definition ARMTargetParser.cpp:482
LLVM_ABI LLVM_READONLY StringRef computeDefaultTargetABI(const Triple &TT)
Definition ARMTargetParser.cpp:540
@ Crypto
Neon with Crypto.
LLVM_ABI ArchKind parseArch(StringRef Arch)
Definition ARMTargetParser.cpp:31
LLVM_ABI FPURestriction getFPURestriction(FPUKind FPUKind)
Definition ARMTargetParser.cpp:267
LLVM_ABI bool appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK, StringRef ArchExt, std::vector< StringRef > &Features, FPUKind &ArgFPUKind)
Definition ARMTargetParser.cpp:423
LLVM_ABI StringRef getArchSynonym(StringRef Arch)
Converts e.g. "armv8" -> "armv8-a".
static constexpr FPUName FPUNames[]
LLVM_ABI StringRef getDefaultCPU(StringRef Arch)
Definition ARMTargetParser.cpp:493
LLVM_ABI StringRef getArchExtFeature(StringRef ArchExt)
Definition ARMTargetParser.cpp:360
LLVM_ABI ProfileKind parseArchProfile(StringRef Arch)
Definition ARMTargetParser.cpp:153
LLVM_ABI FPUKind parseFPU(StringRef FPU)
Definition ARMTargetParser.cpp:223
LLVM_ABI StringRef getSubArch(ArchKind AK)
Definition ARMTargetParser.cpp:340
LLVM_ABI StringRef getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch={})
Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
Definition ARMTargetParser.cpp:595
LLVM_ABI unsigned parseArchVersion(StringRef Arch)
Definition ARMTargetParser.cpp:42
bool has32Regs(const FPURestriction restriction)
LLVM_ABI NeonSupportLevel getFPUNeonSupportLevel(FPUKind FPUKind)
Definition ARMTargetParser.cpp:232
LLVM_ABI ArchKind parseCPUArch(StringRef CPU)
Definition ARMTargetParser.cpp:525
bool isDoublePrecision(const FPURestriction restriction)
constexpr ExtName ARCHExtNames[]
LLVM_ABI unsigned getArchAttr(ArchKind AK)
Definition ARMTargetParser.cpp:344
LLVM_ABI StringRef getFPUName(FPUKind FPUKind)
Definition ARMTargetParser.cpp:255
LLVM_ABI FPUVersion getFPUVersion(FPUKind FPUKind)
Definition ARMTargetParser.cpp:261
LLVM_ABI bool getHWDivFeatures(uint64_t HWDivKind, std::vector< StringRef > &Features)
Definition ARMTargetParser.cpp:297
@ SP_D16
Only single-precision instructions, with 16 D registers.
@ D16
Only 16 D registers.
LLVM_ABI uint64_t getDefaultExtensions(StringRef CPU, ArchKind AK)
Definition ARMTargetParser.cpp:284
LLVM_ABI FPUKind getDefaultFPU(StringRef CPU, ArchKind AK)
Definition ARMTargetParser.cpp:273
LLVM_ABI bool getExtensionFeatures(uint64_t Extensions, std::vector< StringRef > &Features)
Definition ARMTargetParser.cpp:316
static constexpr ArchNames ARMArchNames[]
constexpr CpuNames CPUNames[]
LLVM_ABI void PrintSupportedExtensions(StringMap< StringRef > DescMap)
Definition ARMTargetParser.cpp:670
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI 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