LLVM  12.0.0git
AArch64TargetParser.cpp
Go to the documentation of this file.
1 //===-- AArch64TargetParser - Parser for AArch64 features -------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements a target parser to recognise AArch64 hardware features
10 // such as FPU/CPU/ARCH and extension names.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/ADT/Triple.h"
17 #include <cctype>
18 
19 using namespace llvm;
20 
21 static unsigned checkArchVersion(llvm::StringRef Arch) {
22  if (Arch.size() >= 2 && Arch[0] == 'v' && std::isdigit(Arch[1]))
23  return (Arch[1] - 48);
24  return 0;
25 }
26 
28  if (CPU == "generic")
29  return AArch64ARCHNames[static_cast<unsigned>(AK)].DefaultFPU;
30 
31  return StringSwitch<unsigned>(CPU)
32 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
33  .Case(NAME, ARM::DEFAULT_FPU)
34 #include "../../include/llvm/Support/AArch64TargetParser.def"
35  .Default(ARM::FK_INVALID);
36 }
37 
39  if (CPU == "generic")
40  return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchBaseExtensions;
41 
42  return StringSwitch<unsigned>(CPU)
43 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
44  .Case(NAME, AArch64ARCHNames[static_cast<unsigned>(ArchKind::ID)] \
45  .ArchBaseExtensions | \
46  DEFAULT_EXT)
47 #include "../../include/llvm/Support/AArch64TargetParser.def"
48  .Default(AArch64::AEK_INVALID);
49 }
50 
52  if (CPU == "generic")
53  return ArchKind::ARMV8A;
54 
56 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
57  .Case(NAME, ArchKind::ID)
58 #include "../../include/llvm/Support/AArch64TargetParser.def"
59  .Default(ArchKind::INVALID);
60 }
61 
62 bool AArch64::getExtensionFeatures(unsigned Extensions,
63  std::vector<StringRef> &Features) {
64  if (Extensions == AArch64::AEK_INVALID)
65  return false;
66 
67  if (Extensions & AEK_FP)
68  Features.push_back("+fp-armv8");
69  if (Extensions & AEK_SIMD)
70  Features.push_back("+neon");
71  if (Extensions & AEK_CRC)
72  Features.push_back("+crc");
73  if (Extensions & AEK_CRYPTO)
74  Features.push_back("+crypto");
75  if (Extensions & AEK_DOTPROD)
76  Features.push_back("+dotprod");
77  if (Extensions & AEK_FP16FML)
78  Features.push_back("+fp16fml");
79  if (Extensions & AEK_FP16)
80  Features.push_back("+fullfp16");
81  if (Extensions & AEK_PROFILE)
82  Features.push_back("+spe");
83  if (Extensions & AEK_RAS)
84  Features.push_back("+ras");
85  if (Extensions & AEK_LSE)
86  Features.push_back("+lse");
87  if (Extensions & AEK_RDM)
88  Features.push_back("+rdm");
89  if (Extensions & AEK_SVE)
90  Features.push_back("+sve");
91  if (Extensions & AEK_SVE2)
92  Features.push_back("+sve2");
93  if (Extensions & AEK_SVE2AES)
94  Features.push_back("+sve2-aes");
95  if (Extensions & AEK_SVE2SM4)
96  Features.push_back("+sve2-sm4");
97  if (Extensions & AEK_SVE2SHA3)
98  Features.push_back("+sve2-sha3");
99  if (Extensions & AEK_SVE2BITPERM)
100  Features.push_back("+sve2-bitperm");
101  if (Extensions & AEK_RCPC)
102  Features.push_back("+rcpc");
103 
104  return true;
105 }
106 
108  std::vector<StringRef> &Features) {
109  if (AK == ArchKind::ARMV8_1A)
110  Features.push_back("+v8.1a");
111  if (AK == ArchKind::ARMV8_2A)
112  Features.push_back("+v8.2a");
113  if (AK == ArchKind::ARMV8_3A)
114  Features.push_back("+v8.3a");
115  if (AK == ArchKind::ARMV8_4A)
116  Features.push_back("+v8.4a");
117  if (AK == ArchKind::ARMV8_5A)
118  Features.push_back("+v8.5a");
119  if (AK == AArch64::ArchKind::ARMV8_6A)
120  Features.push_back("+v8.6a");
121 
122  return AK != ArchKind::INVALID;
123 }
124 
126  return AArch64ARCHNames[static_cast<unsigned>(AK)].getName();
127 }
128 
130  return AArch64ARCHNames[static_cast<unsigned>(AK)].getCPUAttr();
131 }
132 
134  return AArch64ARCHNames[static_cast<unsigned>(AK)].getSubArch();
135 }
136 
138  return AArch64ARCHNames[static_cast<unsigned>(AK)].ArchAttr;
139 }
140 
142  for (const auto &AE : AArch64ARCHExtNames)
143  if (ArchExtKind == AE.ID)
144  return AE.getName();
145  return StringRef();
146 }
147 
149  if (ArchExt.startswith("no")) {
150  StringRef ArchExtBase(ArchExt.substr(2));
151  for (const auto &AE : AArch64ARCHExtNames) {
152  if (AE.NegFeature && ArchExtBase == AE.getName())
153  return StringRef(AE.NegFeature);
154  }
155  }
156 
157  for (const auto &AE : AArch64ARCHExtNames)
158  if (AE.Feature && ArchExt == AE.getName())
159  return StringRef(AE.Feature);
160  return StringRef();
161 }
162 
164  ArchKind AK = parseArch(Arch);
165  if (AK == ArchKind::INVALID)
166  return StringRef();
167 
168  // Look for multiple AKs to find the default for pair AK+Name.
169  for (const auto &CPU : AArch64CPUNames)
170  if (CPU.ArchID == AK && CPU.Default)
171  return CPU.getName();
172 
173  // If we can't find a default then target the architecture instead
174  return "generic";
175 }
176 
178  for (const auto &Arch : AArch64CPUNames) {
179  if (Arch.ArchID != ArchKind::INVALID)
180  Values.push_back(Arch.getName());
181  }
182 }
183 
185  return TT.isAndroid() || TT.isOSDarwin() || TT.isOSFuchsia() ||
186  TT.isOSWindows();
187 }
188 
189 // Allows partial match, ex. "v8a" matches "armv8a".
191  Arch = ARM::getCanonicalArchName(Arch);
192  if (checkArchVersion(Arch) < 8)
193  return ArchKind::INVALID;
194 
195  StringRef Syn = ARM::getArchSynonym(Arch);
196  for (const auto &A : AArch64ARCHNames) {
197  if (A.getName().endswith(Syn))
198  return A.ID;
199  }
200  return ArchKind::INVALID;
201 }
202 
204  for (const auto &A : AArch64ARCHExtNames) {
205  if (ArchExt == A.getName())
206  return static_cast<ArchExtKind>(A.ID);
207  }
208  return AArch64::AEK_INVALID;
209 }
210 
212  for (const auto &C : AArch64CPUNames) {
213  if (CPU == C.getName())
214  return C.ArchID;
215  }
216  return ArchKind::INVALID;
217 }
218 
219 // Parse a branch protection specification, which has the form
220 // standard | none | [bti,pac-ret[+b-key,+leaf]*]
221 // Returns true on success, with individual elements of the specification
222 // returned in `PBP`. Returns false in error, with `Err` containing
223 // an erroneous part of the spec.
225  StringRef &Err) {
226  PBP = {"none", "a_key", false};
227  if (Spec == "none")
228  return true; // defaults are ok
229 
230  if (Spec == "standard") {
231  PBP.Scope = "non-leaf";
232  PBP.BranchTargetEnforcement = true;
233  return true;
234  }
235 
237  Spec.split(Opts, "+");
238  for (int I = 0, E = Opts.size(); I != E; ++I) {
239  StringRef Opt = Opts[I].trim();
240  if (Opt == "bti") {
241  PBP.BranchTargetEnforcement = true;
242  continue;
243  }
244  if (Opt == "pac-ret") {
245  PBP.Scope = "non-leaf";
246  for (; I + 1 != E; ++I) {
247  StringRef PACOpt = Opts[I + 1].trim();
248  if (PACOpt == "leaf")
249  PBP.Scope = "all";
250  else if (PACOpt == "b-key")
251  PBP.Key = "b_key";
252  else
253  break;
254  }
255  continue;
256  }
257  if (Opt == "")
258  Err = "<empty>";
259  else
260  Err = Opt;
261  return false;
262  }
263 
264  return true;
265 }
unsigned getArchAttr(ArchKind AK)
uint64_t CallInst * C
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (macOS, iOS, tvOS or watchOS).
Definition: Triple.h:475
This class represents lattice values for constants.
Definition: AllocatorList.h:23
ArchKind getCPUArchKind(StringRef CPU)
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:289
bool isOSFuchsia() const
Definition: Triple.h:499
StringRef getCPUAttr(ArchKind AK)
ArchExtKind parseArchExt(StringRef ArchExt)
StringRef getArchExtName(unsigned ArchExtKind)
unsigned getDefaultFPU(StringRef CPU, ArchKind AK)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
StringRef getArchExtFeature(StringRef ArchExt)
static StringRef getName(Value *V)
StringRef getCanonicalArchName(StringRef Arch)
bool getExtensionFeatures(unsigned Extensions, std::vector< StringRef > &Features)
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:612
ArchKind parseArch(StringRef Arch)
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:160
#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)
StringRef getArchName(ArchKind AK)
bool isOSWindows() const
Tests whether the OS is Windows.
Definition: Triple.h:532
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
bool parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP, StringRef &Err)
bool isX18ReservedByDefault(const Triple &TT)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const ARM::ExtName AArch64ARCHExtNames[]
const ARM::CpuNames< ArchKind > AArch64CPUNames[]
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
StringRef getArchSynonym(StringRef Arch)
void fillValidCPUArchList(SmallVectorImpl< StringRef > &Values)
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:883
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:730
const ARM::ArchNames< ArchKind > AArch64ARCHNames[]
static unsigned checkArchVersion(llvm::StringRef Arch)
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:270
#define I(x, y, z)
Definition: MD5.cpp:59
ArchKind parseCPUArch(StringRef CPU)
static Triple::ArchType parseArch(StringRef ArchName)
Definition: Triple.cpp:392
StringRef getSubArch(ArchKind AK)
bool isAndroid() const
Tests whether the target is Android.
Definition: Triple.h:655
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
bool getArchFeatures(ArchKind AK, std::vector< StringRef > &Features)
StringRef getDefaultCPU(StringRef Arch)
unsigned getDefaultExtensions(StringRef CPU, ArchKind AK)