Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:36

0001 //===-- AArch64TargetParser - Parser for AArch64 features -------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file implements a target parser to recognise AArch64 hardware features
0010 // such as FPU/CPU/ARCH and extension names.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_TARGETPARSER_AARCH64TARGETPARSER_H
0015 #define LLVM_TARGETPARSER_AARCH64TARGETPARSER_H
0016 
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/Bitset.h"
0019 #include "llvm/ADT/StringExtras.h"
0020 #include "llvm/ADT/StringMap.h"
0021 #include "llvm/ADT/StringRef.h"
0022 #include "llvm/Support/VersionTuple.h"
0023 #include "llvm/Support/raw_ostream.h"
0024 #include "llvm/TargetParser/SubtargetFeature.h"
0025 #include <array>
0026 #include <set>
0027 #include <vector>
0028 
0029 namespace llvm {
0030 
0031 class Triple;
0032 
0033 namespace AArch64 {
0034 
0035 struct ArchInfo;
0036 struct CpuInfo;
0037 
0038 #include "llvm/TargetParser/AArch64CPUFeatures.inc"
0039 #include "llvm/TargetParser/AArch64FeatPriorities.inc"
0040 
0041 static_assert(FEAT_MAX < 62,
0042               "Number of features in CPUFeatures are limited to 62 entries");
0043 
0044 // Each ArchExtKind correponds directly to a possible -target-feature.
0045 #define EMIT_ARCHEXTKIND_ENUM
0046 #include "llvm/TargetParser/AArch64TargetParserDef.inc"
0047 
0048 using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>;
0049 
0050 // Represents an extension that can be enabled with -march=<arch>+<extension>.
0051 // Typically these correspond to Arm Architecture extensions, unlike
0052 // SubtargetFeature which may represent either an actual extension or some
0053 // internal LLVM property.
0054 struct ExtensionInfo {
0055   StringRef UserVisibleName;      // Human readable name used in -march, -cpu
0056                                   // and target func attribute, e.g. "profile".
0057   std::optional<StringRef> Alias; // An alias for this extension, if one exists.
0058   ArchExtKind ID;                 // Corresponding to the ArchExtKind, this
0059                                   // extensions representation in the bitfield.
0060   StringRef ArchFeatureName;      // The feature name defined by the
0061                                   // Architecture, e.g. FEAT_AdvSIMD.
0062   StringRef Description;          // The textual description of the extension.
0063   StringRef PosTargetFeature;     // -target-feature/-mattr enable string,
0064                                   // e.g. "+spe".
0065   StringRef NegTargetFeature;     // -target-feature/-mattr disable string,
0066                                   // e.g. "-spe".
0067 };
0068 
0069 #define EMIT_EXTENSIONS
0070 #include "llvm/TargetParser/AArch64TargetParserDef.inc"
0071 
0072 struct FMVInfo {
0073   StringRef Name;                // The target_version/target_clones spelling.
0074   CPUFeatures FeatureBit;        // Index of the bit in the FMV feature bitset.
0075   FeatPriorities PriorityBit;    // Index of the bit in the FMV priority bitset.
0076   std::optional<ArchExtKind> ID; // The architecture extension to enable.
0077   FMVInfo(StringRef Name, CPUFeatures FeatureBit, FeatPriorities PriorityBit,
0078           std::optional<ArchExtKind> ID)
0079       : Name(Name), FeatureBit(FeatureBit), PriorityBit(PriorityBit), ID(ID) {};
0080 };
0081 
0082 const std::vector<FMVInfo> &getFMVInfo();
0083 
0084 // Represents a dependency between two architecture extensions. Later is the
0085 // feature which was added to the architecture after Earlier, and expands the
0086 // functionality provided by it. If Later is enabled, then Earlier will also be
0087 // enabled. If Earlier is disabled, then Later will also be disabled.
0088 struct ExtensionDependency {
0089   ArchExtKind Earlier;
0090   ArchExtKind Later;
0091 };
0092 
0093 #define EMIT_EXTENSION_DEPENDENCIES
0094 #include "llvm/TargetParser/AArch64TargetParserDef.inc"
0095 
0096 enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' };
0097 
0098 // Information about a specific architecture, e.g. V8.1-A
0099 struct ArchInfo {
0100   VersionTuple Version;  // Architecture version, major + minor.
0101   ArchProfile Profile;   // Architecuture profile
0102   StringRef Name;        // Name as supplied to -march e.g. "armv8.1-a"
0103   StringRef ArchFeature; // Name as supplied to -target-feature, e.g. "+v8a"
0104   AArch64::ExtensionBitset
0105       DefaultExts; // bitfield of default extensions ArchExtKind
0106 
0107   bool operator==(const ArchInfo &Other) const {
0108     return this->Name == Other.Name;
0109   }
0110   bool operator!=(const ArchInfo &Other) const {
0111     return this->Name != Other.Name;
0112   }
0113 
0114   // Defines the following partial order, indicating when an architecture is
0115   // a superset of another:
0116   //
0117   // v9.6a > v9.5a > v9.4a > v9.3a > v9.2a > v9.1a > v9a;
0118   //                   v       v       v       v       v
0119   //                 v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > v8.4a > ... > v8a;
0120   //
0121   // v8r has no relation to anything. This is used to determine which
0122   // features to enable for a given architecture. See
0123   // AArch64TargetInfo::setFeatureEnabled.
0124   bool implies(const ArchInfo &Other) const {
0125     if (this->Profile != Other.Profile)
0126       return false; // ARMV8R
0127     if (this->Version.getMajor() == Other.Version.getMajor()) {
0128       return this->Version > Other.Version;
0129     }
0130     if (this->Version.getMajor() == 9 && Other.Version.getMajor() == 8) {
0131       assert(this->Version.getMinor() && Other.Version.getMinor() &&
0132              "AArch64::ArchInfo should have a minor version.");
0133       return this->Version.getMinor().value_or(0) + 5 >=
0134              Other.Version.getMinor().value_or(0);
0135     }
0136     return false;
0137   }
0138 
0139   // True if this architecture is a superset of Other (including being equal to
0140   // it).
0141   bool is_superset(const ArchInfo &Other) const {
0142     return (*this == Other) || implies(Other);
0143   }
0144 
0145   // Return ArchFeature without the leading "+".
0146   StringRef getSubArch() const { return ArchFeature.substr(1); }
0147 
0148   // Search for ArchInfo by SubArch name
0149   static std::optional<ArchInfo> findBySubArch(StringRef SubArch);
0150 };
0151 
0152 #define EMIT_ARCHITECTURES
0153 #include "llvm/TargetParser/AArch64TargetParserDef.inc"
0154 
0155 // Details of a specific CPU.
0156 struct CpuInfo {
0157   StringRef Name; // Name, as written for -mcpu.
0158   const ArchInfo &Arch;
0159   AArch64::ExtensionBitset
0160       DefaultExtensions; // Default extensions for this CPU.
0161 
0162   AArch64::ExtensionBitset getImpliedExtensions() const {
0163     return DefaultExtensions;
0164   }
0165 };
0166 
0167 #define EMIT_CPU_INFO
0168 #include "llvm/TargetParser/AArch64TargetParserDef.inc"
0169 
0170 struct ExtensionSet {
0171   // Set of extensions which are currently enabled.
0172   ExtensionBitset Enabled;
0173   // Set of extensions which have been enabled or disabled at any point. Used
0174   // to avoid cluttering the cc1 command-line with lots of unneeded features.
0175   ExtensionBitset Touched;
0176   // Base architecture version, which we need to know because some feature
0177   // dependencies change depending on this.
0178   const ArchInfo *BaseArch;
0179 
0180   ExtensionSet() : Enabled(), Touched(), BaseArch(nullptr) {}
0181 
0182   // Enable the given architecture extension, and any other extensions it
0183   // depends on. Does not change the base architecture, or follow dependencies
0184   // between features which are only related by required arcitecture versions.
0185   void enable(ArchExtKind E);
0186 
0187   // Disable the given architecture extension, and any other extensions which
0188   // depend on it. Does not change the base architecture, or follow
0189   // dependencies between features which are only related by required
0190   // arcitecture versions.
0191   void disable(ArchExtKind E);
0192 
0193   // Add default extensions for the given CPU. Records the base architecture,
0194   // to later resolve dependencies which depend on it.
0195   void addCPUDefaults(const CpuInfo &CPU);
0196 
0197   // Add default extensions for the given architecture version. Records the
0198   // base architecture, to later resolve dependencies which depend on it.
0199   void addArchDefaults(const ArchInfo &Arch);
0200 
0201   // Add or remove a feature based on a modifier string. The string must be of
0202   // the form "<name>" to enable a feature or "no<name>" to disable it. This
0203   // will also enable or disable any features as required by the dependencies
0204   // between them.
0205   bool parseModifier(StringRef Modifier, const bool AllowNoDashForm = false);
0206 
0207   // Constructs a new ExtensionSet by toggling the corresponding bits for every
0208   // feature in the \p Features list without expanding their dependencies. Used
0209   // for reconstructing an ExtensionSet from the output of toLLVMFeatures().
0210   // Features that are not recognized are pushed back to \p NonExtensions.
0211   void reconstructFromParsedFeatures(const std::vector<std::string> &Features,
0212                                      std::vector<std::string> &NonExtensions);
0213 
0214   // Convert the set of enabled extension to an LLVM feature list, appending
0215   // them to Features.
0216   template <typename T> void toLLVMFeatureList(std::vector<T> &Features) const {
0217     if (BaseArch && !BaseArch->ArchFeature.empty())
0218       Features.emplace_back(T(BaseArch->ArchFeature));
0219 
0220     for (const auto &E : Extensions) {
0221       if (E.PosTargetFeature.empty() || !Touched.test(E.ID))
0222         continue;
0223       if (Enabled.test(E.ID))
0224         Features.emplace_back(T(E.PosTargetFeature));
0225       else
0226         Features.emplace_back(T(E.NegTargetFeature));
0227     }
0228   }
0229 
0230   void dump() const;
0231 };
0232 
0233 // Name alias.
0234 struct Alias {
0235   StringRef AltName;
0236   StringRef Name;
0237 };
0238 
0239 #define EMIT_CPU_ALIAS
0240 #include "llvm/TargetParser/AArch64TargetParserDef.inc"
0241 
0242 const ExtensionInfo &getExtensionByID(ArchExtKind(ExtID));
0243 
0244 bool getExtensionFeatures(
0245     const AArch64::ExtensionBitset &Extensions,
0246     std::vector<StringRef> &Features);
0247 
0248 StringRef getArchExtFeature(StringRef ArchExt);
0249 StringRef resolveCPUAlias(StringRef CPU);
0250 
0251 // Information by Name
0252 const ArchInfo *getArchForCpu(StringRef CPU);
0253 
0254 // Parser
0255 const ArchInfo *parseArch(StringRef Arch);
0256 
0257 // Return the extension which has the given -target-feature name.
0258 std::optional<ExtensionInfo> targetFeatureToExtension(StringRef TargetFeature);
0259 
0260 // Parse a name as defined by the Extension class in tablegen.
0261 std::optional<ExtensionInfo> parseArchExtension(StringRef Extension);
0262 
0263 // Parse a name as defined by the FMVInfo class in tablegen.
0264 std::optional<FMVInfo> parseFMVExtension(StringRef Extension);
0265 
0266 // Given the name of a CPU or alias, return the correponding CpuInfo.
0267 std::optional<CpuInfo> parseCpu(StringRef Name);
0268 // Used by target parser tests
0269 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values);
0270 
0271 bool isX18ReservedByDefault(const Triple &TT);
0272 
0273 // For a given set of feature names, which can be either target-features, or
0274 // fmv-features metadata, expand their dependencies and then return a bitmask
0275 // corresponding to the entries of AArch64::FeatPriorities.
0276 uint64_t getFMVPriority(ArrayRef<StringRef> Features);
0277 
0278 // For a given set of FMV feature names, expand their dependencies and then
0279 // return a bitmask corresponding to the entries of AArch64::CPUFeatures.
0280 // The values in CPUFeatures are not bitmasks themselves, they are sequential
0281 // (0, 1, 2, 3, ...). The resulting bitmask is used at runtime to test whether
0282 // a certain FMV feature is available on the host.
0283 uint64_t getCpuSupportsMask(ArrayRef<StringRef> Features);
0284 
0285 void PrintSupportedExtensions();
0286 
0287 void printEnabledExtensions(const std::set<StringRef> &EnabledFeatureNames);
0288 
0289 } // namespace AArch64
0290 } // namespace llvm
0291 
0292 #endif