1 //===-- AArch64TargetParser - Parser for AArch64 features -------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements a target parser to recognise AArch64 hardware features
10 // such as FPU/CPU/ARCH and extension names.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/TargetParser/AArch64TargetParser.h"
15 #include "llvm/Support/Format.h"
16 #include "llvm/Support/raw_ostream.h"
17 #include "llvm/TargetParser/ARMTargetParserCommon.h"
18 #include "llvm/TargetParser/Triple.h"
23 static unsigned checkArchVersion(llvm::StringRef Arch
) {
24 if (Arch
.size() >= 2 && Arch
[0] == 'v' && std::isdigit(Arch
[1]))
25 return (Arch
[1] - 48);
29 std::optional
<AArch64::ArchInfo
> AArch64::getArchForCpu(StringRef CPU
) {
33 // Note: this now takes cpu aliases into account
34 std::optional
<CpuInfo
> Cpu
= parseCpu(CPU
);
40 std::optional
<AArch64::ArchInfo
> AArch64::ArchInfo::findBySubArch(StringRef SubArch
) {
41 for (const auto *A
: AArch64::ArchInfos
)
42 if (A
->getSubArch() == SubArch
)
47 uint64_t AArch64::getCpuSupportsMask(ArrayRef
<StringRef
> FeatureStrs
) {
48 uint64_t FeaturesMask
= 0;
49 for (const StringRef
&FeatureStr
: FeatureStrs
) {
50 for (const auto &E
: llvm::AArch64::Extensions
)
51 if (FeatureStr
== E
.Name
) {
52 FeaturesMask
|= (1ULL << E
.CPUFeature
);
59 bool AArch64::getExtensionFeatures(
60 const AArch64::ExtensionBitset
&InputExts
,
61 std::vector
<StringRef
> &Features
) {
62 for (const auto &E
: Extensions
)
63 /* INVALID and NONE have no feature name. */
64 if (InputExts
.test(E
.ID
) && !E
.Feature
.empty())
65 Features
.push_back(E
.Feature
);
70 StringRef
AArch64::resolveCPUAlias(StringRef Name
) {
71 for (const auto &A
: CpuAliases
)
77 StringRef
AArch64::getArchExtFeature(StringRef ArchExt
) {
78 if (ArchExt
.startswith("no")) {
79 StringRef
ArchExtBase(ArchExt
.substr(2));
80 for (const auto &AE
: Extensions
) {
81 if (!AE
.NegFeature
.empty() && ArchExtBase
== AE
.Name
)
86 for (const auto &AE
: Extensions
)
87 if (!AE
.Feature
.empty() && ArchExt
== AE
.Name
)
92 void AArch64::fillValidCPUArchList(SmallVectorImpl
<StringRef
> &Values
) {
93 for (const auto &C
: CpuInfos
)
94 Values
.push_back(C
.Name
);
96 for (const auto &Alias
: CpuAliases
)
97 Values
.push_back(Alias
.Alias
);
100 bool AArch64::isX18ReservedByDefault(const Triple
&TT
) {
101 return TT
.isAndroid() || TT
.isOSDarwin() || TT
.isOSFuchsia() ||
102 TT
.isOSWindows() || TT
.isOHOSFamily();
105 // Allows partial match, ex. "v8a" matches "armv8a".
106 std::optional
<AArch64::ArchInfo
> AArch64::parseArch(StringRef Arch
) {
107 Arch
= llvm::ARM::getCanonicalArchName(Arch
);
108 if (checkArchVersion(Arch
) < 8)
111 StringRef Syn
= llvm::ARM::getArchSynonym(Arch
);
112 for (const auto *A
: ArchInfos
) {
113 if (A
->Name
.endswith(Syn
))
119 std::optional
<AArch64::ExtensionInfo
> AArch64::parseArchExtension(StringRef ArchExt
) {
120 for (const auto &A
: Extensions
) {
121 if (ArchExt
== A
.Name
)
127 std::optional
<AArch64::CpuInfo
> AArch64::parseCpu(StringRef Name
) {
128 // Resolve aliases first.
129 Name
= resolveCPUAlias(Name
);
131 // Then find the CPU name.
132 for (const auto &C
: CpuInfos
)
139 void AArch64::PrintSupportedExtensions(StringMap
<StringRef
> DescMap
) {
140 outs() << "All available -march extensions for AArch64\n\n"
141 << " " << left_justify("Name", 20)
142 << (DescMap
.empty() ? "\n" : "Description\n");
143 for (const auto &Ext
: Extensions
) {
144 // Extensions without a feature cannot be used with -march.
145 if (!Ext
.Feature
.empty()) {
146 std::string Description
= DescMap
[Ext
.Name
].str();
148 << format(Description
.empty() ? "%s\n" : "%-20s%s\n",
149 Ext
.Name
.str().c_str(), Description
.c_str());