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/StringMap.h" 20 #include "llvm/ADT/StringRef.h" 21 #include "llvm/Support/VersionTuple.h" 22 #include <array> 23 #include <vector> 24 25 namespace llvm { 26 27 class Triple; 28 29 namespace AArch64 { 30 31 struct ArchInfo; 32 struct CpuInfo; 33 34 // Function Multi Versioning CPU features. They must be kept in sync with 35 // compiler-rt enum CPUFeatures in lib/builtins/cpu_model/aarch64.c with 36 // FEAT_MAX as sentinel. 37 enum CPUFeatures { 38 FEAT_RNG, 39 FEAT_FLAGM, 40 FEAT_FLAGM2, 41 FEAT_FP16FML, 42 FEAT_DOTPROD, 43 FEAT_SM4, 44 FEAT_RDM, 45 FEAT_LSE, 46 FEAT_FP, 47 FEAT_SIMD, 48 FEAT_CRC, 49 FEAT_SHA1, 50 FEAT_SHA2, 51 FEAT_SHA3, 52 FEAT_AES, 53 FEAT_PMULL, 54 FEAT_FP16, 55 FEAT_DIT, 56 FEAT_DPB, 57 FEAT_DPB2, 58 FEAT_JSCVT, 59 FEAT_FCMA, 60 FEAT_RCPC, 61 FEAT_RCPC2, 62 FEAT_FRINTTS, 63 FEAT_DGH, 64 FEAT_I8MM, 65 FEAT_BF16, 66 FEAT_EBF16, 67 FEAT_RPRES, 68 FEAT_SVE, 69 FEAT_SVE_BF16, 70 FEAT_SVE_EBF16, 71 FEAT_SVE_I8MM, 72 FEAT_SVE_F32MM, 73 FEAT_SVE_F64MM, 74 FEAT_SVE2, 75 FEAT_SVE_AES, 76 FEAT_SVE_PMULL128, 77 FEAT_SVE_BITPERM, 78 FEAT_SVE_SHA3, 79 FEAT_SVE_SM4, 80 FEAT_SME, 81 FEAT_MEMTAG, 82 FEAT_MEMTAG2, 83 FEAT_MEMTAG3, 84 FEAT_SB, 85 FEAT_PREDRES, 86 FEAT_SSBS, 87 FEAT_SSBS2, 88 FEAT_BTI, 89 FEAT_LS64, 90 FEAT_LS64_V, 91 FEAT_LS64_ACCDATA, 92 FEAT_WFXT, 93 FEAT_SME_F64, 94 FEAT_SME_I64, 95 FEAT_SME2, 96 FEAT_RCPC3, 97 FEAT_MOPS, 98 FEAT_MAX, 99 FEAT_EXT = 62, 100 FEAT_INIT 101 }; 102 103 static_assert(FEAT_MAX < 62, 104 "Number of features in CPUFeatures are limited to 62 entries"); 105 106 // Each ArchExtKind correponds directly to a possible -target-feature. 107 #define EMIT_ARCHEXTKIND_ENUM 108 #include "llvm/TargetParser/AArch64TargetParserDef.inc" 109 110 using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>; 111 112 // Represents an extension that can be enabled with -march=<arch>+<extension>. 113 // Typically these correspond to Arm Architecture extensions, unlike 114 // SubtargetFeature which may represent either an actual extension or some 115 // internal LLVM property. 116 struct ExtensionInfo { 117 StringRef Name; // Human readable name, e.g. "profile". 118 ArchExtKind ID; // Corresponding to the ArchExtKind, this 119 // extensions representation in the bitfield. 120 StringRef Feature; // -mattr enable string, e.g. "+spe" 121 StringRef NegFeature; // -mattr disable string, e.g. "-spe" 122 CPUFeatures CPUFeature; // Function Multi Versioning (FMV) bitfield value 123 // set in __aarch64_cpu_features 124 StringRef DependentFeatures; // FMV enabled features string, 125 // e.g. "+dotprod,+fp-armv8,+neon" 126 unsigned FmvPriority; // FMV feature priority 127 static constexpr unsigned MaxFMVPriority = 128 1000; // Maximum priority for FMV feature 129 }; 130 131 #define EMIT_EXTENSIONS 132 #include "llvm/TargetParser/AArch64TargetParserDef.inc" 133 134 struct ExtensionSet { 135 // Set of extensions which are currently enabled. 136 ExtensionBitset Enabled; 137 // Set of extensions which have been enabled or disabled at any point. Used 138 // to avoid cluttering the cc1 command-line with lots of unneeded features. 139 ExtensionBitset Touched; 140 // Base architecture version, which we need to know because some feature 141 // dependencies change depending on this. 142 const ArchInfo *BaseArch; 143 ExtensionSetExtensionSet144 ExtensionSet() : Enabled(), Touched(), BaseArch(nullptr) {} 145 146 // Enable the given architecture extension, and any other extensions it 147 // depends on. Does not change the base architecture, or follow dependencies 148 // between features which are only related by required arcitecture versions. 149 void enable(ArchExtKind E); 150 151 // Disable the given architecture extension, and any other extensions which 152 // depend on it. Does not change the base architecture, or follow 153 // dependencies between features which are only related by required 154 // arcitecture versions. 155 void disable(ArchExtKind E); 156 157 // Add default extensions for the given CPU. Records the base architecture, 158 // to later resolve dependencies which depend on it. 159 void addCPUDefaults(const CpuInfo &CPU); 160 161 // Add default extensions for the given architecture version. Records the 162 // base architecture, to later resolve dependencies which depend on it. 163 void addArchDefaults(const ArchInfo &Arch); 164 165 // Add or remove a feature based on a modifier string. The string must be of 166 // the form "<name>" to enable a feature or "no<name>" to disable it. This 167 // will also enable or disable any features as required by the dependencies 168 // between them. 169 bool parseModifier(StringRef Modifier); 170 171 // Convert the set of enabled extension to an LLVM feature list, appending 172 // them to Features. 173 void toLLVMFeatureList(std::vector<StringRef> &Features) const; 174 }; 175 176 // Represents a dependency between two architecture extensions. Later is the 177 // feature which was added to the architecture after Earlier, and expands the 178 // functionality provided by it. If Later is enabled, then Earlier will also be 179 // enabled. If Earlier is disabled, then Later will also be disabled. 180 struct ExtensionDependency { 181 ArchExtKind Earlier; 182 ArchExtKind Later; 183 }; 184 185 // clang-format off 186 // Each entry here is a link in the dependency chain starting from the 187 // extension that was added to the architecture first. 188 inline constexpr ExtensionDependency ExtensionDependencies[] = { 189 {AEK_FP, AEK_FP16}, 190 {AEK_FP, AEK_SIMD}, 191 {AEK_FP, AEK_JSCVT}, 192 {AEK_FP, AEK_FP8}, 193 {AEK_SIMD, AEK_CRYPTO}, 194 {AEK_SIMD, AEK_AES}, 195 {AEK_SIMD, AEK_SHA2}, 196 {AEK_SIMD, AEK_SHA3}, 197 {AEK_SIMD, AEK_SM4}, 198 {AEK_SIMD, AEK_RDM}, 199 {AEK_SIMD, AEK_DOTPROD}, 200 {AEK_SIMD, AEK_FCMA}, 201 {AEK_FP16, AEK_FP16FML}, 202 {AEK_FP16, AEK_SVE}, 203 {AEK_BF16, AEK_SME}, 204 {AEK_BF16, AEK_B16B16}, 205 {AEK_SVE, AEK_SVE2}, 206 {AEK_SVE, AEK_F32MM}, 207 {AEK_SVE, AEK_F64MM}, 208 {AEK_SVE2, AEK_SVE2P1}, 209 {AEK_SVE2, AEK_SVE2BITPERM}, 210 {AEK_SVE2, AEK_SVE2AES}, 211 {AEK_SVE2, AEK_SVE2SHA3}, 212 {AEK_SVE2, AEK_SVE2SM4}, 213 {AEK_SVE2, AEK_SMEFA64}, 214 {AEK_SVE2, AEK_SMEFA64}, 215 {AEK_SME, AEK_SME2}, 216 {AEK_SME, AEK_SMEF16F16}, 217 {AEK_SME, AEK_SMEF64F64}, 218 {AEK_SME, AEK_SMEI16I64}, 219 {AEK_SME, AEK_SMEFA64}, 220 {AEK_SME2, AEK_SME2P1}, 221 {AEK_SME2, AEK_SSVE_FP8FMA}, 222 {AEK_SME2, AEK_SSVE_FP8DOT2}, 223 {AEK_SME2, AEK_SSVE_FP8DOT4}, 224 {AEK_SME2, AEK_SMEF8F16}, 225 {AEK_SME2, AEK_SMEF8F32}, 226 {AEK_FP8, AEK_SMEF8F16}, 227 {AEK_FP8, AEK_SMEF8F32}, 228 {AEK_LSE, AEK_LSE128}, 229 {AEK_PREDRES, AEK_SPECRES2}, 230 {AEK_RAS, AEK_RASV2}, 231 {AEK_RCPC, AEK_RCPC3}, 232 }; 233 // clang-format on 234 235 enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' }; 236 237 // Information about a specific architecture, e.g. V8.1-A 238 struct ArchInfo { 239 VersionTuple Version; // Architecture version, major + minor. 240 ArchProfile Profile; // Architecuture profile 241 StringRef Name; // Human readable name, e.g. "armv8.1-a" 242 StringRef ArchFeature; // Command line feature flag, e.g. +v8a 243 AArch64::ExtensionBitset 244 DefaultExts; // bitfield of default extensions ArchExtKind 245 246 bool operator==(const ArchInfo &Other) const { 247 return this->Name == Other.Name; 248 } 249 bool operator!=(const ArchInfo &Other) const { 250 return this->Name != Other.Name; 251 } 252 253 // Defines the following partial order, indicating when an architecture is 254 // a superset of another: 255 // 256 // v9.5a > v9.4a > v9.3a > v9.2a > v9.1a > v9a; 257 // v v v v v 258 // v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > v8.4a > ... > v8a; 259 // 260 // v8r has no relation to anything. This is used to determine which 261 // features to enable for a given architecture. See 262 // AArch64TargetInfo::setFeatureEnabled. impliesArchInfo263 bool implies(const ArchInfo &Other) const { 264 if (this->Profile != Other.Profile) 265 return false; // ARMV8R 266 if (this->Version.getMajor() == Other.Version.getMajor()) { 267 return this->Version > Other.Version; 268 } 269 if (this->Version.getMajor() == 9 && Other.Version.getMajor() == 8) { 270 assert(this->Version.getMinor() && Other.Version.getMinor() && 271 "AArch64::ArchInfo should have a minor version."); 272 return this->Version.getMinor().value_or(0) + 5 >= 273 Other.Version.getMinor().value_or(0); 274 } 275 return false; 276 } 277 278 // True if this architecture is a superset of Other (including being equal to 279 // it). is_supersetArchInfo280 bool is_superset(const ArchInfo &Other) const { 281 return (*this == Other) || implies(Other); 282 } 283 284 // Return ArchFeature without the leading "+". getSubArchArchInfo285 StringRef getSubArch() const { return ArchFeature.substr(1); } 286 287 // Search for ArchInfo by SubArch name 288 static std::optional<ArchInfo> findBySubArch(StringRef SubArch); 289 }; 290 291 // clang-format off 292 inline constexpr ArchInfo ARMV8A = { VersionTuple{8, 0}, AProfile, "armv8-a", "+v8a", ( 293 AArch64::ExtensionBitset({AArch64::AEK_FP, AArch64::AEK_SIMD})), }; 294 inline constexpr ArchInfo ARMV8_1A = { VersionTuple{8, 1}, AProfile, "armv8.1-a", "+v8.1a", (ARMV8A.DefaultExts | 295 AArch64::ExtensionBitset({AArch64::AEK_CRC, AArch64::AEK_LSE, AArch64::AEK_RDM}))}; 296 inline constexpr ArchInfo ARMV8_2A = { VersionTuple{8, 2}, AProfile, "armv8.2-a", "+v8.2a", (ARMV8_1A.DefaultExts | 297 AArch64::ExtensionBitset({AArch64::AEK_RAS}))}; 298 inline constexpr ArchInfo ARMV8_3A = { VersionTuple{8, 3}, AProfile, "armv8.3-a", "+v8.3a", (ARMV8_2A.DefaultExts | 299 AArch64::ExtensionBitset({AArch64::AEK_FCMA, AArch64::AEK_JSCVT, AArch64::AEK_PAUTH, AArch64::AEK_RCPC}))}; 300 inline constexpr ArchInfo ARMV8_4A = { VersionTuple{8, 4}, AProfile, "armv8.4-a", "+v8.4a", (ARMV8_3A.DefaultExts | 301 AArch64::ExtensionBitset({AArch64::AEK_DOTPROD}))}; 302 inline constexpr ArchInfo ARMV8_5A = { VersionTuple{8, 5}, AProfile, "armv8.5-a", "+v8.5a", (ARMV8_4A.DefaultExts)}; 303 inline constexpr ArchInfo ARMV8_6A = { VersionTuple{8, 6}, AProfile, "armv8.6-a", "+v8.6a", (ARMV8_5A.DefaultExts | 304 AArch64::ExtensionBitset({AArch64::AEK_BF16, AArch64::AEK_I8MM}))}; 305 inline constexpr ArchInfo ARMV8_7A = { VersionTuple{8, 7}, AProfile, "armv8.7-a", "+v8.7a", (ARMV8_6A.DefaultExts)}; 306 inline constexpr ArchInfo ARMV8_8A = { VersionTuple{8, 8}, AProfile, "armv8.8-a", "+v8.8a", (ARMV8_7A.DefaultExts | 307 AArch64::ExtensionBitset({AArch64::AEK_MOPS, AArch64::AEK_HBC}))}; 308 inline constexpr ArchInfo ARMV8_9A = { VersionTuple{8, 9}, AProfile, "armv8.9-a", "+v8.9a", (ARMV8_8A.DefaultExts | 309 AArch64::ExtensionBitset({AArch64::AEK_SPECRES2, AArch64::AEK_CSSC, AArch64::AEK_RASV2}))}; 310 inline constexpr ArchInfo ARMV9A = { VersionTuple{9, 0}, AProfile, "armv9-a", "+v9a", (ARMV8_5A.DefaultExts | 311 AArch64::ExtensionBitset({AArch64::AEK_FP16, AArch64::AEK_SVE, AArch64::AEK_SVE2}))}; 312 inline constexpr ArchInfo ARMV9_1A = { VersionTuple{9, 1}, AProfile, "armv9.1-a", "+v9.1a", (ARMV9A.DefaultExts | 313 AArch64::ExtensionBitset({AArch64::AEK_BF16, AArch64::AEK_I8MM}))}; 314 inline constexpr ArchInfo ARMV9_2A = { VersionTuple{9, 2}, AProfile, "armv9.2-a", "+v9.2a", (ARMV9_1A.DefaultExts)}; 315 inline constexpr ArchInfo ARMV9_3A = { VersionTuple{9, 3}, AProfile, "armv9.3-a", "+v9.3a", (ARMV9_2A.DefaultExts | 316 AArch64::ExtensionBitset({AArch64::AEK_MOPS, AArch64::AEK_HBC}))}; 317 inline constexpr ArchInfo ARMV9_4A = { VersionTuple{9, 4}, AProfile, "armv9.4-a", "+v9.4a", (ARMV9_3A.DefaultExts | 318 AArch64::ExtensionBitset({AArch64::AEK_SPECRES2, AArch64::AEK_CSSC, AArch64::AEK_RASV2}))}; 319 inline constexpr ArchInfo ARMV9_5A = { VersionTuple{9, 5}, AProfile, "armv9.5-a", "+v9.5a", (ARMV9_4A.DefaultExts | 320 AArch64::ExtensionBitset({AArch64::AEK_CPA}))}; 321 // For v8-R, we do not enable crypto and align with GCC that enables a more minimal set of optional architecture extensions. 322 inline constexpr ArchInfo ARMV8R = { VersionTuple{8, 0}, RProfile, "armv8-r", "+v8r", (ARMV8_5A.DefaultExts | 323 AArch64::ExtensionBitset({AArch64::AEK_SSBS, 324 AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_SB}).flip(AArch64::AEK_LSE))}; 325 // clang-format on 326 327 // The set of all architectures 328 static constexpr std::array<const ArchInfo *, 17> ArchInfos = { 329 &ARMV8A, &ARMV8_1A, &ARMV8_2A, &ARMV8_3A, &ARMV8_4A, &ARMV8_5A, 330 &ARMV8_6A, &ARMV8_7A, &ARMV8_8A, &ARMV8_9A, &ARMV9A, &ARMV9_1A, 331 &ARMV9_2A, &ARMV9_3A, &ARMV9_4A, &ARMV9_5A, &ARMV8R, 332 }; 333 334 // Details of a specific CPU. 335 struct CpuInfo { 336 StringRef Name; // Name, as written for -mcpu. 337 const ArchInfo &Arch; 338 AArch64::ExtensionBitset 339 DefaultExtensions; // Default extensions for this CPU. These will be 340 // ORd with the architecture defaults. 341 getImpliedExtensionsCpuInfo342 AArch64::ExtensionBitset getImpliedExtensions() const { 343 AArch64::ExtensionBitset ImpliedExts; 344 ImpliedExts |= DefaultExtensions; 345 ImpliedExts |= Arch.DefaultExts; 346 return ImpliedExts; 347 } 348 }; 349 350 inline constexpr CpuInfo CpuInfos[] = { 351 {"cortex-a34", ARMV8A, 352 AArch64::ExtensionBitset( 353 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 354 {"cortex-a35", ARMV8A, 355 AArch64::ExtensionBitset( 356 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 357 {"cortex-a53", ARMV8A, 358 AArch64::ExtensionBitset( 359 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 360 {"cortex-a55", ARMV8_2A, 361 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 362 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 363 AArch64::AEK_RCPC})}, 364 {"cortex-a510", ARMV9A, 365 AArch64::ExtensionBitset( 366 {AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_SB, 367 AArch64::AEK_PAUTH, AArch64::AEK_MTE, AArch64::AEK_SSBS, 368 AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM, 369 AArch64::AEK_FP16FML})}, 370 {"cortex-a520", ARMV9_2A, 371 AArch64::ExtensionBitset( 372 {AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_MTE, 373 AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, 374 AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, AArch64::AEK_PREDRES})}, 375 {"cortex-a520ae", ARMV9_2A, 376 AArch64::ExtensionBitset( 377 {AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_MTE, 378 AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, 379 AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, AArch64::AEK_PREDRES})}, 380 {"cortex-a57", ARMV8A, 381 AArch64::ExtensionBitset( 382 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 383 {"cortex-a65", ARMV8_2A, 384 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 385 AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 386 AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, 387 {"cortex-a65ae", ARMV8_2A, 388 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 389 AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 390 AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, 391 {"cortex-a72", ARMV8A, 392 AArch64::ExtensionBitset( 393 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 394 {"cortex-a73", ARMV8A, 395 AArch64::ExtensionBitset( 396 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 397 {"cortex-a75", ARMV8_2A, 398 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 399 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 400 AArch64::AEK_RCPC})}, 401 {"cortex-a76", ARMV8_2A, 402 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 403 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 404 AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, 405 {"cortex-a76ae", ARMV8_2A, 406 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 407 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 408 AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, 409 {"cortex-a77", ARMV8_2A, 410 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 411 AArch64::AEK_FP16, AArch64::AEK_RCPC, 412 AArch64::AEK_DOTPROD, AArch64::AEK_SSBS})}, 413 {"cortex-a78", ARMV8_2A, 414 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 415 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 416 AArch64::AEK_RCPC, AArch64::AEK_SSBS, 417 AArch64::AEK_PROFILE})}, 418 {"cortex-a78ae", ARMV8_2A, 419 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 420 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 421 AArch64::AEK_RCPC, AArch64::AEK_SSBS, 422 AArch64::AEK_PROFILE})}, 423 {"cortex-a78c", ARMV8_2A, 424 AArch64::ExtensionBitset( 425 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, 426 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS, 427 AArch64::AEK_PROFILE, AArch64::AEK_FLAGM, AArch64::AEK_PAUTH})}, 428 {"cortex-a710", ARMV9A, 429 AArch64::ExtensionBitset({AArch64::AEK_MTE, AArch64::AEK_PAUTH, 430 AArch64::AEK_FLAGM, AArch64::AEK_SB, 431 AArch64::AEK_I8MM, AArch64::AEK_FP16FML, 432 AArch64::AEK_SVE, AArch64::AEK_SVE2, 433 AArch64::AEK_SVE2BITPERM, AArch64::AEK_BF16})}, 434 {"cortex-a715", ARMV9A, 435 AArch64::ExtensionBitset( 436 {AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_MTE, 437 AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, 438 AArch64::AEK_I8MM, AArch64::AEK_PREDRES, AArch64::AEK_PERFMON, 439 AArch64::AEK_PROFILE, AArch64::AEK_SVE, AArch64::AEK_SVE2BITPERM, 440 AArch64::AEK_BF16, AArch64::AEK_FLAGM})}, 441 {"cortex-a720", ARMV9_2A, 442 AArch64::ExtensionBitset({AArch64::AEK_SB, AArch64::AEK_SSBS, 443 AArch64::AEK_MTE, AArch64::AEK_FP16FML, 444 AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, 445 AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, 446 AArch64::AEK_PREDRES, AArch64::AEK_PROFILE})}, 447 {"cortex-a720ae", ARMV9_2A, 448 AArch64::ExtensionBitset({AArch64::AEK_SB, AArch64::AEK_SSBS, 449 AArch64::AEK_MTE, AArch64::AEK_FP16FML, 450 AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, 451 AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, 452 AArch64::AEK_PREDRES, AArch64::AEK_PROFILE})}, 453 {"cortex-r82", ARMV8R, 454 AArch64::ExtensionBitset({AArch64::AEK_LSE, AArch64::AEK_FLAGM, 455 AArch64::AEK_PERFMON, AArch64::AEK_PREDRES})}, 456 {"cortex-r82ae", ARMV8R, 457 AArch64::ExtensionBitset({AArch64::AEK_LSE, AArch64::AEK_FLAGM, 458 AArch64::AEK_PERFMON, AArch64::AEK_PREDRES})}, 459 {"cortex-x1", ARMV8_2A, 460 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 461 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 462 AArch64::AEK_RCPC, AArch64::AEK_SSBS, 463 AArch64::AEK_PROFILE})}, 464 {"cortex-x1c", ARMV8_2A, 465 AArch64::ExtensionBitset( 466 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, 467 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS, 468 AArch64::AEK_PAUTH, AArch64::AEK_PROFILE, AArch64::AEK_FLAGM})}, 469 {"cortex-x2", ARMV9A, 470 AArch64::ExtensionBitset( 471 {AArch64::AEK_MTE, AArch64::AEK_BF16, AArch64::AEK_I8MM, 472 AArch64::AEK_PAUTH, AArch64::AEK_SSBS, AArch64::AEK_SB, 473 AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM, 474 AArch64::AEK_FP16FML, AArch64::AEK_FLAGM})}, 475 {"cortex-x3", ARMV9A, 476 AArch64::ExtensionBitset( 477 {AArch64::AEK_SVE, AArch64::AEK_PERFMON, AArch64::AEK_PROFILE, 478 AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_MTE, 479 AArch64::AEK_SVE2BITPERM, AArch64::AEK_SB, AArch64::AEK_PAUTH, 480 AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_PREDRES, 481 AArch64::AEK_FLAGM, AArch64::AEK_SSBS})}, 482 {"cortex-x4", ARMV9_2A, 483 AArch64::ExtensionBitset({AArch64::AEK_SB, AArch64::AEK_SSBS, 484 AArch64::AEK_MTE, AArch64::AEK_FP16FML, 485 AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, 486 AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, 487 AArch64::AEK_PREDRES, AArch64::AEK_PROFILE})}, 488 {"neoverse-e1", ARMV8_2A, 489 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 490 AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 491 AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, 492 {"neoverse-n1", ARMV8_2A, 493 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 494 AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 495 AArch64::AEK_PROFILE, AArch64::AEK_RCPC, 496 AArch64::AEK_SSBS})}, 497 {"neoverse-n2", ARMV9A, 498 AArch64::ExtensionBitset( 499 {AArch64::AEK_BF16, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 500 AArch64::AEK_FP16FML, AArch64::AEK_I8MM, AArch64::AEK_MTE, 501 AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_SVE, 502 AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM})}, 503 {"neoverse-n3", ARMV9_2A, 504 AArch64::ExtensionBitset({AArch64::AEK_MTE, AArch64::AEK_SSBS, 505 AArch64::AEK_SB, AArch64::AEK_PREDRES, 506 AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, 507 AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, 508 AArch64::AEK_RAND, AArch64::AEK_SVE2BITPERM, 509 AArch64::AEK_PROFILE, AArch64::AEK_PERFMON})}, 510 {"neoverse-512tvb", ARMV8_4A, 511 AArch64::ExtensionBitset( 512 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, 513 AArch64::AEK_SM4, AArch64::AEK_SVE, AArch64::AEK_SSBS, 514 AArch64::AEK_FP16, AArch64::AEK_BF16, AArch64::AEK_DOTPROD, 515 AArch64::AEK_PROFILE, AArch64::AEK_RAND, AArch64::AEK_FP16FML, 516 AArch64::AEK_I8MM})}, 517 {"neoverse-v1", ARMV8_4A, 518 AArch64::ExtensionBitset( 519 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, 520 AArch64::AEK_SM4, AArch64::AEK_SVE, AArch64::AEK_SSBS, 521 AArch64::AEK_FP16, AArch64::AEK_BF16, AArch64::AEK_DOTPROD, 522 AArch64::AEK_PROFILE, AArch64::AEK_RAND, AArch64::AEK_FP16FML, 523 AArch64::AEK_I8MM})}, 524 {"neoverse-v2", ARMV9A, 525 AArch64::ExtensionBitset( 526 {AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SSBS, 527 AArch64::AEK_FP16, AArch64::AEK_BF16, AArch64::AEK_RAND, 528 AArch64::AEK_DOTPROD, AArch64::AEK_PROFILE, AArch64::AEK_SVE2BITPERM, 529 AArch64::AEK_FP16FML, AArch64::AEK_I8MM, AArch64::AEK_MTE})}, 530 {"neoverse-v3", ARMV9_2A, 531 AArch64::ExtensionBitset( 532 {AArch64::AEK_PROFILE, AArch64::AEK_MTE, AArch64::AEK_SSBS, 533 AArch64::AEK_SB, AArch64::AEK_PREDRES, AArch64::AEK_LS64, 534 AArch64::AEK_BRBE, AArch64::AEK_PAUTH, AArch64::AEK_FLAGM, 535 AArch64::AEK_PERFMON, AArch64::AEK_RAND, AArch64::AEK_SVE2BITPERM, 536 AArch64::AEK_FP16FML})}, 537 {"neoverse-v3ae", ARMV9_2A, 538 (AArch64::ExtensionBitset( 539 {AArch64::AEK_PROFILE, AArch64::AEK_MTE, AArch64::AEK_SSBS, 540 AArch64::AEK_SB, AArch64::AEK_PREDRES, AArch64::AEK_LS64, 541 AArch64::AEK_BRBE, AArch64::AEK_PAUTH, AArch64::AEK_FLAGM, 542 AArch64::AEK_PERFMON, AArch64::AEK_RAND, AArch64::AEK_SVE2BITPERM, 543 AArch64::AEK_FP16FML}))}, 544 {"cyclone", ARMV8A, 545 AArch64::ExtensionBitset( 546 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE})}, 547 {"apple-a7", ARMV8A, 548 AArch64::ExtensionBitset( 549 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE})}, 550 {"apple-a8", ARMV8A, 551 AArch64::ExtensionBitset( 552 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE})}, 553 {"apple-a9", ARMV8A, 554 AArch64::ExtensionBitset( 555 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE})}, 556 {"apple-a10", ARMV8A, 557 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 558 AArch64::AEK_CRC, AArch64::AEK_RDM})}, 559 {"apple-a11", ARMV8_2A, 560 AArch64::ExtensionBitset( 561 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, 562 {"apple-a12", ARMV8_3A, 563 AArch64::ExtensionBitset( 564 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, 565 {"apple-a13", ARMV8_4A, 566 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 567 AArch64::AEK_SHA3, AArch64::AEK_FP16, 568 AArch64::AEK_FP16FML})}, 569 {"apple-a14", ARMV8_5A, 570 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 571 AArch64::AEK_SHA3, AArch64::AEK_FP16, 572 AArch64::AEK_FP16FML})}, 573 {"apple-a15", ARMV8_6A, 574 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 575 AArch64::AEK_SHA3, AArch64::AEK_FP16, 576 AArch64::AEK_FP16FML})}, 577 {"apple-a16", ARMV8_6A, 578 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 579 AArch64::AEK_SHA3, AArch64::AEK_FP16, 580 AArch64::AEK_FP16FML})}, 581 {"apple-a17", ARMV8_6A, 582 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 583 AArch64::AEK_SHA3, AArch64::AEK_FP16, 584 AArch64::AEK_FP16FML})}, 585 586 {"apple-m1", ARMV8_5A, 587 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 588 AArch64::AEK_SHA3, AArch64::AEK_FP16, 589 AArch64::AEK_FP16FML})}, 590 {"apple-m2", ARMV8_6A, 591 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 592 AArch64::AEK_SHA3, AArch64::AEK_FP16, 593 AArch64::AEK_FP16FML})}, 594 {"apple-m3", ARMV8_6A, 595 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 596 AArch64::AEK_SHA3, AArch64::AEK_FP16, 597 AArch64::AEK_FP16FML})}, 598 599 {"apple-s4", ARMV8_3A, 600 AArch64::ExtensionBitset( 601 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, 602 {"apple-s5", ARMV8_3A, 603 AArch64::ExtensionBitset( 604 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, 605 {"exynos-m3", ARMV8A, 606 AArch64::ExtensionBitset( 607 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 608 {"exynos-m4", ARMV8_2A, 609 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 610 AArch64::AEK_DOTPROD, AArch64::AEK_FP16})}, 611 {"exynos-m5", ARMV8_2A, 612 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 613 AArch64::AEK_DOTPROD, AArch64::AEK_FP16})}, 614 {"falkor", ARMV8A, 615 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 616 AArch64::AEK_CRC, AArch64::AEK_RDM})}, 617 {"saphira", ARMV8_3A, 618 AArch64::ExtensionBitset( 619 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_PROFILE})}, 620 {"kryo", ARMV8A, 621 AArch64::ExtensionBitset( 622 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 623 {"thunderx2t99", ARMV8_1A, 624 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2})}, 625 {"thunderx3t110", ARMV8_3A, 626 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2})}, 627 {"thunderx", ARMV8A, 628 AArch64::ExtensionBitset( 629 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 630 {"thunderxt88", ARMV8A, 631 AArch64::ExtensionBitset( 632 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 633 {"thunderxt81", ARMV8A, 634 AArch64::ExtensionBitset( 635 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 636 {"thunderxt83", ARMV8A, 637 AArch64::ExtensionBitset( 638 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 639 {"tsv110", ARMV8_2A, 640 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 641 AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 642 AArch64::AEK_FP16FML, AArch64::AEK_PROFILE, 643 AArch64::AEK_JSCVT, AArch64::AEK_FCMA})}, 644 {"a64fx", ARMV8_2A, 645 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 646 AArch64::AEK_FP16, AArch64::AEK_SVE})}, 647 {"carmel", ARMV8_2A, 648 AArch64::ExtensionBitset( 649 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, 650 {"ampere1", ARMV8_6A, 651 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 652 AArch64::AEK_SHA3, AArch64::AEK_FP16, 653 AArch64::AEK_SB, AArch64::AEK_SSBS, 654 AArch64::AEK_RAND})}, 655 {"ampere1a", ARMV8_6A, 656 AArch64::ExtensionBitset( 657 {AArch64::AEK_FP16, AArch64::AEK_RAND, AArch64::AEK_SM4, 658 AArch64::AEK_SHA3, AArch64::AEK_SHA2, AArch64::AEK_AES, 659 AArch64::AEK_MTE, AArch64::AEK_SB, AArch64::AEK_SSBS})}, 660 {"ampere1b", ARMV8_7A, 661 AArch64::ExtensionBitset({AArch64::AEK_FP16, AArch64::AEK_RAND, 662 AArch64::AEK_SM4, AArch64::AEK_SHA3, 663 AArch64::AEK_SHA2, AArch64::AEK_AES, 664 AArch64::AEK_MTE, AArch64::AEK_SB, 665 AArch64::AEK_SSBS, AArch64::AEK_CSSC})}, 666 }; 667 668 // Name alias. 669 struct Alias { 670 StringRef AltName; 671 StringRef Name; 672 }; 673 674 inline constexpr Alias CpuAliases[] = {{"cobalt-100", "neoverse-n2"}, 675 {"grace", "neoverse-v2"}}; 676 677 inline constexpr Alias ExtAliases[] = {{"rdma", "rdm"}}; 678 679 const ExtensionInfo &getExtensionByID(ArchExtKind(ExtID)); 680 681 bool getExtensionFeatures( 682 const AArch64::ExtensionBitset &Extensions, 683 std::vector<StringRef> &Features); 684 685 StringRef getArchExtFeature(StringRef ArchExt); 686 StringRef resolveCPUAlias(StringRef CPU); 687 StringRef resolveExtAlias(StringRef ArchExt); 688 689 // Information by Name 690 const ArchInfo *getArchForCpu(StringRef CPU); 691 692 // Parser 693 const ArchInfo *parseArch(StringRef Arch); 694 std::optional<ExtensionInfo> parseArchExtension(StringRef Extension); 695 // Given the name of a CPU or alias, return the correponding CpuInfo. 696 std::optional<CpuInfo> parseCpu(StringRef Name); 697 // Used by target parser tests 698 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values); 699 700 bool isX18ReservedByDefault(const Triple &TT); 701 702 // For given feature names, return a bitmask corresponding to the entries of 703 // AArch64::CPUFeatures. The values in CPUFeatures are not bitmasks 704 // themselves, they are sequential (0, 1, 2, 3, ...). 705 uint64_t getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs); 706 707 void PrintSupportedExtensions(StringMap<StringRef> DescMap); 708 709 } // namespace AArch64 710 } // namespace llvm 711 712 #endif 713