xref: /freebsd/contrib/llvm-project/llvm/include/llvm/TargetParser/AArch64TargetParser.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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 
14 #ifndef LLVM_TARGETPARSER_AARCH64TARGETPARSER_H
15 #define LLVM_TARGETPARSER_AARCH64TARGETPARSER_H
16 
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/ADT/Bitset.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/ADT/StringMap.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Support/Compiler.h"
23 #include "llvm/Support/VersionTuple.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include "llvm/TargetParser/SubtargetFeature.h"
26 #include <array>
27 #include <set>
28 #include <vector>
29 
30 namespace llvm {
31 
32 class Triple;
33 
34 namespace AArch64 {
35 
36 struct ArchInfo;
37 struct CpuInfo;
38 
39 #include "llvm/TargetParser/AArch64CPUFeatures.inc"
40 #include "llvm/TargetParser/AArch64FeatPriorities.inc"
41 
42 static_assert(FEAT_MAX < 62,
43               "Number of features in CPUFeatures are limited to 62 entries");
44 
45 // Each ArchExtKind correponds directly to a possible -target-feature.
46 #define EMIT_ARCHEXTKIND_ENUM
47 #include "llvm/TargetParser/AArch64TargetParserDef.inc"
48 
49 using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>;
50 
51 // Represents an extension that can be enabled with -march=<arch>+<extension>.
52 // Typically these correspond to Arm Architecture extensions, unlike
53 // SubtargetFeature which may represent either an actual extension or some
54 // internal LLVM property.
55 struct ExtensionInfo {
56   StringRef UserVisibleName;      // Human readable name used in -march, -cpu
57                                   // and target func attribute, e.g. "profile".
58   std::optional<StringRef> Alias; // An alias for this extension, if one exists.
59   ArchExtKind ID;                 // Corresponding to the ArchExtKind, this
60                                   // extensions representation in the bitfield.
61   StringRef ArchFeatureName;      // The feature name defined by the
62                                   // Architecture, e.g. FEAT_AdvSIMD.
63   StringRef Description;          // The textual description of the extension.
64   StringRef PosTargetFeature;     // -target-feature/-mattr enable string,
65                                   // e.g. "+spe".
66   StringRef NegTargetFeature;     // -target-feature/-mattr disable string,
67                                   // e.g. "-spe".
68 };
69 
70 #define EMIT_EXTENSIONS
71 #include "llvm/TargetParser/AArch64TargetParserDef.inc"
72 
73 struct FMVInfo {
74   StringRef Name;                // The target_version/target_clones spelling.
75   CPUFeatures FeatureBit;        // Index of the bit in the FMV feature bitset.
76   FeatPriorities PriorityBit;    // Index of the bit in the FMV priority bitset.
77   std::optional<ArchExtKind> ID; // The architecture extension to enable.
FMVInfoFMVInfo78   FMVInfo(StringRef Name, CPUFeatures FeatureBit, FeatPriorities PriorityBit,
79           std::optional<ArchExtKind> ID)
80       : Name(Name), FeatureBit(FeatureBit), PriorityBit(PriorityBit), ID(ID) {};
81 };
82 
83 LLVM_ABI const std::vector<FMVInfo> &getFMVInfo();
84 
85 // Represents a dependency between two architecture extensions. Later is the
86 // feature which was added to the architecture after Earlier, and expands the
87 // functionality provided by it. If Later is enabled, then Earlier will also be
88 // enabled. If Earlier is disabled, then Later will also be disabled.
89 struct ExtensionDependency {
90   ArchExtKind Earlier;
91   ArchExtKind Later;
92 };
93 
94 #define EMIT_EXTENSION_DEPENDENCIES
95 #include "llvm/TargetParser/AArch64TargetParserDef.inc"
96 
97 enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' };
98 
99 // Information about a specific architecture, e.g. V8.1-A
100 struct ArchInfo {
101   VersionTuple Version;  // Architecture version, major + minor.
102   ArchProfile Profile;   // Architecuture profile
103   StringRef Name;        // Name as supplied to -march e.g. "armv8.1-a"
104   StringRef ArchFeature; // Name as supplied to -target-feature, e.g. "+v8a"
105   AArch64::ExtensionBitset
106       DefaultExts; // bitfield of default extensions ArchExtKind
107 
108   bool operator==(const ArchInfo &Other) const {
109     return this->Name == Other.Name;
110   }
111   bool operator!=(const ArchInfo &Other) const {
112     return this->Name != Other.Name;
113   }
114 
115   // Defines the following partial order, indicating when an architecture is
116   // a superset of another:
117   //
118   // v9.6a > v9.5a > v9.4a > v9.3a > v9.2a > v9.1a > v9a;
119   //                   v       v       v       v       v
120   //                 v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > v8.4a > ... > v8a;
121   //
122   // v8r has no relation to anything. This is used to determine which
123   // features to enable for a given architecture. See
124   // AArch64TargetInfo::setFeatureEnabled.
impliesArchInfo125   bool implies(const ArchInfo &Other) const {
126     if (this->Profile != Other.Profile)
127       return false; // ARMV8R
128     if (this->Version.getMajor() == Other.Version.getMajor()) {
129       return this->Version > Other.Version;
130     }
131     if (this->Version.getMajor() == 9 && Other.Version.getMajor() == 8) {
132       assert(this->Version.getMinor() && Other.Version.getMinor() &&
133              "AArch64::ArchInfo should have a minor version.");
134       return this->Version.getMinor().value_or(0) + 5 >=
135              Other.Version.getMinor().value_or(0);
136     }
137     return false;
138   }
139 
140   // True if this architecture is a superset of Other (including being equal to
141   // it).
is_supersetArchInfo142   bool is_superset(const ArchInfo &Other) const {
143     return (*this == Other) || implies(Other);
144   }
145 
146   // Return ArchFeature without the leading "+".
getSubArchArchInfo147   StringRef getSubArch() const { return ArchFeature.substr(1); }
148 
149   // Search for ArchInfo by SubArch name
150   LLVM_ABI static std::optional<ArchInfo> findBySubArch(StringRef SubArch);
151 };
152 
153 #define EMIT_ARCHITECTURES
154 #include "llvm/TargetParser/AArch64TargetParserDef.inc"
155 
156 // Details of a specific CPU.
157 struct CpuInfo {
158   StringRef Name; // Name, as written for -mcpu.
159   const ArchInfo &Arch;
160   AArch64::ExtensionBitset
161       DefaultExtensions; // Default extensions for this CPU.
162 
getImpliedExtensionsCpuInfo163   AArch64::ExtensionBitset getImpliedExtensions() const {
164     return DefaultExtensions;
165   }
166 };
167 
168 #define EMIT_CPU_INFO
169 #include "llvm/TargetParser/AArch64TargetParserDef.inc"
170 
171 struct ExtensionSet {
172   // Set of extensions which are currently enabled.
173   ExtensionBitset Enabled;
174   // Set of extensions which have been enabled or disabled at any point. Used
175   // to avoid cluttering the cc1 command-line with lots of unneeded features.
176   ExtensionBitset Touched;
177   // Base architecture version, which we need to know because some feature
178   // dependencies change depending on this.
179   const ArchInfo *BaseArch;
180 
ExtensionSetExtensionSet181   ExtensionSet() : Enabled(), Touched(), BaseArch(nullptr) {}
182 
183   // Enable the given architecture extension, and any other extensions it
184   // depends on. Does not change the base architecture, or follow dependencies
185   // between features which are only related by required arcitecture versions.
186   LLVM_ABI void enable(ArchExtKind E);
187 
188   // Disable the given architecture extension, and any other extensions which
189   // depend on it. Does not change the base architecture, or follow
190   // dependencies between features which are only related by required
191   // arcitecture versions.
192   LLVM_ABI void disable(ArchExtKind E);
193 
194   // Add default extensions for the given CPU. Records the base architecture,
195   // to later resolve dependencies which depend on it.
196   LLVM_ABI void addCPUDefaults(const CpuInfo &CPU);
197 
198   // Add default extensions for the given architecture version. Records the
199   // base architecture, to later resolve dependencies which depend on it.
200   LLVM_ABI void addArchDefaults(const ArchInfo &Arch);
201 
202   // Add or remove a feature based on a modifier string. The string must be of
203   // the form "<name>" to enable a feature or "no<name>" to disable it. This
204   // will also enable or disable any features as required by the dependencies
205   // between them.
206   LLVM_ABI bool parseModifier(StringRef Modifier,
207                               const bool AllowNoDashForm = false);
208 
209   // Constructs a new ExtensionSet by toggling the corresponding bits for every
210   // feature in the \p Features list without expanding their dependencies. Used
211   // for reconstructing an ExtensionSet from the output of toLLVMFeatures().
212   // Features that are not recognized are pushed back to \p NonExtensions.
213   LLVM_ABI void
214   reconstructFromParsedFeatures(const std::vector<std::string> &Features,
215                                 std::vector<std::string> &NonExtensions);
216 
217   // Convert the set of enabled extension to an LLVM feature list, appending
218   // them to Features.
toLLVMFeatureListExtensionSet219   template <typename T> void toLLVMFeatureList(std::vector<T> &Features) const {
220     if (BaseArch && !BaseArch->ArchFeature.empty())
221       Features.emplace_back(T(BaseArch->ArchFeature));
222 
223     for (const auto &E : Extensions) {
224       if (E.PosTargetFeature.empty() || !Touched.test(E.ID))
225         continue;
226       if (Enabled.test(E.ID))
227         Features.emplace_back(T(E.PosTargetFeature));
228       else
229         Features.emplace_back(T(E.NegTargetFeature));
230     }
231   }
232 
233   LLVM_ABI void dump() const;
234 };
235 
236 // Name alias.
237 struct Alias {
238   StringRef AltName;
239   StringRef Name;
240 };
241 
242 #define EMIT_CPU_ALIAS
243 #include "llvm/TargetParser/AArch64TargetParserDef.inc"
244 
245 LLVM_ABI const ExtensionInfo &getExtensionByID(ArchExtKind(ExtID));
246 
247 LLVM_ABI bool getExtensionFeatures(const AArch64::ExtensionBitset &Extensions,
248                                    std::vector<StringRef> &Features);
249 
250 LLVM_ABI StringRef getArchExtFeature(StringRef ArchExt);
251 LLVM_ABI StringRef resolveCPUAlias(StringRef CPU);
252 
253 // Information by Name
254 LLVM_ABI const ArchInfo *getArchForCpu(StringRef CPU);
255 
256 // Parser
257 LLVM_ABI const ArchInfo *parseArch(StringRef Arch);
258 
259 // Return the extension which has the given -target-feature name.
260 LLVM_ABI std::optional<ExtensionInfo>
261 targetFeatureToExtension(StringRef TargetFeature);
262 
263 // Parse a name as defined by the Extension class in tablegen.
264 LLVM_ABI std::optional<ExtensionInfo> parseArchExtension(StringRef Extension);
265 
266 // Parse a name as defined by the FMVInfo class in tablegen.
267 LLVM_ABI std::optional<FMVInfo> parseFMVExtension(StringRef Extension);
268 
269 // Given the name of a CPU or alias, return the correponding CpuInfo.
270 LLVM_ABI std::optional<CpuInfo> parseCpu(StringRef Name);
271 // Used by target parser tests
272 LLVM_ABI void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values);
273 
274 LLVM_ABI bool isX18ReservedByDefault(const Triple &TT);
275 
276 // For a given set of feature names, which can be either target-features, or
277 // fmv-features metadata, expand their dependencies and then return a bitmask
278 // corresponding to the entries of AArch64::FeatPriorities.
279 LLVM_ABI uint64_t getFMVPriority(ArrayRef<StringRef> Features);
280 
281 // For a given set of FMV feature names, expand their dependencies and then
282 // return a bitmask corresponding to the entries of AArch64::CPUFeatures.
283 // The values in CPUFeatures are not bitmasks themselves, they are sequential
284 // (0, 1, 2, 3, ...). The resulting bitmask is used at runtime to test whether
285 // a certain FMV feature is available on the host.
286 LLVM_ABI uint64_t getCpuSupportsMask(ArrayRef<StringRef> Features);
287 
288 LLVM_ABI void PrintSupportedExtensions();
289 
290 LLVM_ABI void
291 printEnabledExtensions(const std::set<StringRef> &EnabledFeatureNames);
292 
293 } // namespace AArch64
294 } // namespace llvm
295 
296 #endif
297