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/StringRef.h" 19 #include "llvm/Support/VersionTuple.h" 20 #include <array> 21 #include <vector> 22 23 namespace llvm { 24 25 class Triple; 26 27 namespace AArch64 { 28 // Function Multi Versioning CPU features. They must be kept in sync with 29 // compiler-rt enum CPUFeatures in lib/builtins/cpu_model.c with FEAT_MAX as 30 // sentinel. 31 enum CPUFeatures { 32 FEAT_RNG, 33 FEAT_FLAGM, 34 FEAT_FLAGM2, 35 FEAT_FP16FML, 36 FEAT_DOTPROD, 37 FEAT_SM4, 38 FEAT_RDM, 39 FEAT_LSE, 40 FEAT_FP, 41 FEAT_SIMD, 42 FEAT_CRC, 43 FEAT_SHA1, 44 FEAT_SHA2, 45 FEAT_SHA3, 46 FEAT_AES, 47 FEAT_PMULL, 48 FEAT_FP16, 49 FEAT_DIT, 50 FEAT_DPB, 51 FEAT_DPB2, 52 FEAT_JSCVT, 53 FEAT_FCMA, 54 FEAT_RCPC, 55 FEAT_RCPC2, 56 FEAT_FRINTTS, 57 FEAT_DGH, 58 FEAT_I8MM, 59 FEAT_BF16, 60 FEAT_EBF16, 61 FEAT_RPRES, 62 FEAT_SVE, 63 FEAT_SVE_BF16, 64 FEAT_SVE_EBF16, 65 FEAT_SVE_I8MM, 66 FEAT_SVE_F32MM, 67 FEAT_SVE_F64MM, 68 FEAT_SVE2, 69 FEAT_SVE_AES, 70 FEAT_SVE_PMULL128, 71 FEAT_SVE_BITPERM, 72 FEAT_SVE_SHA3, 73 FEAT_SVE_SM4, 74 FEAT_SME, 75 FEAT_MEMTAG, 76 FEAT_MEMTAG2, 77 FEAT_MEMTAG3, 78 FEAT_SB, 79 FEAT_PREDRES, 80 FEAT_SSBS, 81 FEAT_SSBS2, 82 FEAT_BTI, 83 FEAT_LS64, 84 FEAT_LS64_V, 85 FEAT_LS64_ACCDATA, 86 FEAT_WFXT, 87 FEAT_SME_F64, 88 FEAT_SME_I64, 89 FEAT_SME2, 90 FEAT_MAX 91 }; 92 93 static_assert(FEAT_MAX <= 64, 94 "CPUFeatures enum must not have more than 64 entries"); 95 96 // Arch extension modifiers for CPUs. These are labelled with their Arm ARM 97 // feature name (though the canonical reference for those is AArch64.td) 98 // clang-format off 99 enum ArchExtKind : uint64_t { 100 AEK_NONE = 1, 101 AEK_CRC = 1 << 1, // FEAT_CRC32 102 AEK_CRYPTO = 1 << 2, 103 AEK_FP = 1 << 3, // FEAT_FP 104 AEK_SIMD = 1 << 4, // FEAT_AdvSIMD 105 AEK_FP16 = 1 << 5, // FEAT_FP16 106 AEK_PROFILE = 1 << 6, // FEAT_SPE 107 AEK_RAS = 1 << 7, // FEAT_RAS, FEAT_RASv1p1 108 AEK_LSE = 1 << 8, // FEAT_LSE 109 AEK_SVE = 1 << 9, // FEAT_SVE 110 AEK_DOTPROD = 1 << 10, // FEAT_DotProd 111 AEK_RCPC = 1 << 11, // FEAT_LRCPC 112 AEK_RDM = 1 << 12, // FEAT_RDM 113 AEK_SM4 = 1 << 13, // FEAT_SM4, FEAT_SM3 114 AEK_SHA3 = 1 << 14, // FEAT_SHA3, FEAT_SHA512 115 AEK_SHA2 = 1 << 15, // FEAT_SHA1, FEAT_SHA256 116 AEK_AES = 1 << 16, // FEAT_AES, FEAT_PMULL 117 AEK_FP16FML = 1 << 17, // FEAT_FHM 118 AEK_RAND = 1 << 18, // FEAT_RNG 119 AEK_MTE = 1 << 19, // FEAT_MTE, FEAT_MTE2 120 AEK_SSBS = 1 << 20, // FEAT_SSBS, FEAT_SSBS2 121 AEK_SB = 1 << 21, // FEAT_SB 122 AEK_PREDRES = 1 << 22, // FEAT_SPECRES 123 AEK_SVE2 = 1 << 23, // FEAT_SVE2 124 AEK_SVE2AES = 1 << 24, // FEAT_SVE_AES, FEAT_SVE_PMULL128 125 AEK_SVE2SM4 = 1 << 25, // FEAT_SVE_SM4 126 AEK_SVE2SHA3 = 1 << 26, // FEAT_SVE_SHA3 127 AEK_SVE2BITPERM = 1 << 27, // FEAT_SVE_BitPerm 128 AEK_TME = 1 << 28, // FEAT_TME 129 AEK_BF16 = 1 << 29, // FEAT_BF16 130 AEK_I8MM = 1 << 30, // FEAT_I8MM 131 AEK_F32MM = 1ULL << 31, // FEAT_F32MM 132 AEK_F64MM = 1ULL << 32, // FEAT_F64MM 133 AEK_LS64 = 1ULL << 33, // FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA 134 AEK_BRBE = 1ULL << 34, // FEAT_BRBE 135 AEK_PAUTH = 1ULL << 35, // FEAT_PAuth 136 AEK_FLAGM = 1ULL << 36, // FEAT_FlagM 137 AEK_SME = 1ULL << 37, // FEAT_SME 138 AEK_SMEF64F64 = 1ULL << 38, // FEAT_SME_F64F64 139 AEK_SMEI16I64 = 1ULL << 39, // FEAT_SME_I16I64 140 AEK_HBC = 1ULL << 40, // FEAT_HBC 141 AEK_MOPS = 1ULL << 41, // FEAT_MOPS 142 AEK_PERFMON = 1ULL << 42, // FEAT_PMUv3 143 AEK_SME2 = 1ULL << 43, // FEAT_SME2 144 AEK_SVE2p1 = 1ULL << 44, // FEAT_SVE2p1 145 AEK_SME2p1 = 1ULL << 45, // FEAT_SME2p1 146 AEK_B16B16 = 1ULL << 46, // FEAT_B16B16 147 AEK_SMEF16F16 = 1ULL << 47, // FEAT_SMEF16F16 148 AEK_CSSC = 1ULL << 48, // FEAT_CSSC 149 AEK_RCPC3 = 1ULL << 49, // FEAT_LRCPC3 150 AEK_THE = 1ULL << 50, // FEAT_THE 151 AEK_D128 = 1ULL << 51, // FEAT_D128 152 AEK_LSE128 = 1ULL << 52, // FEAT_LSE128 153 AEK_SPECRES2 = 1ULL << 53, // FEAT_SPECRES2 154 AEK_RASv2 = 1ULL << 54, // FEAT_RASv2 155 AEK_ITE = 1ULL << 55, // FEAT_ITE 156 AEK_GCS = 1ULL << 56, // FEAT_GCS 157 }; 158 // clang-format on 159 160 // Represents an extension that can be enabled with -march=<arch>+<extension>. 161 // Typically these correspond to Arm Architecture extensions, unlike 162 // SubtargetFeature which may represent either an actual extension or some 163 // internal LLVM property. 164 struct ExtensionInfo { 165 StringRef Name; // Human readable name, e.g. "profile". 166 ArchExtKind ID; // Corresponding to the ArchExtKind, this 167 // extensions representation in the bitfield. 168 StringRef Feature; // -mattr enable string, e.g. "+spe" 169 StringRef NegFeature; // -mattr disable string, e.g. "-spe" 170 CPUFeatures CPUFeature; // Function Multi Versioning (FMV) bitfield value 171 // set in __aarch64_cpu_features 172 StringRef DependentFeatures; // FMV enabled features string, 173 // e.g. "+dotprod,+fp-armv8,+neon" 174 unsigned FmvPriority; // FMV feature priority 175 static constexpr unsigned MaxFMVPriority = 176 1000; // Maximum priority for FMV feature 177 }; 178 179 // NOTE: If adding a new extension here, consider adding it to ExtensionMap 180 // in AArch64AsmParser too, if supported as an extension name by binutils. 181 // clang-format off 182 inline constexpr ExtensionInfo Extensions[] = { 183 {"aes", AArch64::AEK_AES, "+aes", "-aes", FEAT_AES, "+fp-armv8,+neon", 150}, 184 {"b16b16", AArch64::AEK_B16B16, "+b16b16", "-b16b16", FEAT_MAX, "", 0}, 185 {"bf16", AArch64::AEK_BF16, "+bf16", "-bf16", FEAT_BF16, "+bf16", 280}, 186 {"brbe", AArch64::AEK_BRBE, "+brbe", "-brbe", FEAT_MAX, "", 0}, 187 {"bti", AArch64::AEK_NONE, {}, {}, FEAT_BTI, "+bti", 510}, 188 {"crc", AArch64::AEK_CRC, "+crc", "-crc", FEAT_CRC, "+crc", 110}, 189 {"crypto", AArch64::AEK_CRYPTO, "+crypto", "-crypto", FEAT_MAX, "+aes,+sha2", 0}, 190 {"cssc", AArch64::AEK_CSSC, "+cssc", "-cssc", FEAT_MAX, "", 0}, 191 {"d128", AArch64::AEK_D128, "+d128", "-d128", FEAT_MAX, "", 0}, 192 {"dgh", AArch64::AEK_NONE, {}, {}, FEAT_DGH, "", 260}, 193 {"dit", AArch64::AEK_NONE, {}, {}, FEAT_DIT, "+dit", 180}, 194 {"dotprod", AArch64::AEK_DOTPROD, "+dotprod", "-dotprod", FEAT_DOTPROD, "+dotprod,+fp-armv8,+neon", 50}, 195 {"dpb", AArch64::AEK_NONE, {}, {}, FEAT_DPB, "+ccpp", 190}, 196 {"dpb2", AArch64::AEK_NONE, {}, {}, FEAT_DPB2, "+ccpp,+ccdp", 200}, 197 {"ebf16", AArch64::AEK_NONE, {}, {}, FEAT_EBF16, "+bf16", 290}, 198 {"f32mm", AArch64::AEK_F32MM, "+f32mm", "-f32mm", FEAT_SVE_F32MM, "+sve,+f32mm,+fullfp16,+fp-armv8,+neon", 350}, 199 {"f64mm", AArch64::AEK_F64MM, "+f64mm", "-f64mm", FEAT_SVE_F64MM, "+sve,+f64mm,+fullfp16,+fp-armv8,+neon", 360}, 200 {"fcma", AArch64::AEK_NONE, {}, {}, FEAT_FCMA, "+fp-armv8,+neon,+complxnum", 220}, 201 {"flagm", AArch64::AEK_FLAGM, "+flagm", "-flagm", FEAT_FLAGM, "+flagm", 20}, 202 {"flagm2", AArch64::AEK_NONE, {}, {}, FEAT_FLAGM2, "+flagm,+altnzcv", 30}, 203 {"fp", AArch64::AEK_FP, "+fp-armv8", "-fp-armv8", FEAT_FP, "+fp-armv8,+neon", 90}, 204 {"fp16", AArch64::AEK_FP16, "+fullfp16", "-fullfp16", FEAT_FP16, "+fullfp16,+fp-armv8,+neon", 170}, 205 {"fp16fml", AArch64::AEK_FP16FML, "+fp16fml", "-fp16fml", FEAT_FP16FML, "+fp16fml,+fullfp16,+fp-armv8,+neon", 40}, 206 {"frintts", AArch64::AEK_NONE, {}, {}, FEAT_FRINTTS, "+fptoint", 250}, 207 {"hbc", AArch64::AEK_HBC, "+hbc", "-hbc", FEAT_MAX, "", 0}, 208 {"i8mm", AArch64::AEK_I8MM, "+i8mm", "-i8mm", FEAT_I8MM, "+i8mm", 270}, 209 {"ite", AArch64::AEK_ITE, "+ite", "-ite", FEAT_MAX, "", 0}, 210 {"jscvt", AArch64::AEK_NONE, {}, {}, FEAT_JSCVT, "+fp-armv8,+neon,+jsconv", 210}, 211 {"ls64_accdata", AArch64::AEK_NONE, {}, {}, FEAT_LS64_ACCDATA, "+ls64", 540}, 212 {"ls64_v", AArch64::AEK_NONE, {}, {}, FEAT_LS64_V, "", 530}, 213 {"ls64", AArch64::AEK_LS64, "+ls64", "-ls64", FEAT_LS64, "", 520}, 214 {"lse", AArch64::AEK_LSE, "+lse", "-lse", FEAT_LSE, "+lse", 80}, 215 {"lse128", AArch64::AEK_LSE128, "+lse128", "-lse128", FEAT_MAX, "", 0}, 216 {"memtag", AArch64::AEK_MTE, "+mte", "-mte", FEAT_MEMTAG, "", 440}, 217 {"memtag2", AArch64::AEK_NONE, {}, {}, FEAT_MEMTAG2, "+mte", 450}, 218 {"memtag3", AArch64::AEK_NONE, {}, {}, FEAT_MEMTAG3, "+mte", 460}, 219 {"mops", AArch64::AEK_MOPS, "+mops", "-mops", FEAT_MAX, "", 0}, 220 {"pauth", AArch64::AEK_PAUTH, "+pauth", "-pauth", FEAT_MAX, "", 0}, 221 {"pmull", AArch64::AEK_NONE, {}, {}, FEAT_PMULL, "+aes,+fp-armv8,+neon", 160}, 222 {"pmuv3", AArch64::AEK_PERFMON, "+perfmon", "-perfmon", FEAT_MAX, "", 0}, 223 {"predres", AArch64::AEK_PREDRES, "+predres", "-predres", FEAT_PREDRES, "+predres", 480}, 224 {"predres2", AArch64::AEK_SPECRES2, "+specres2", "-specres2", FEAT_MAX, "", 0}, 225 {"profile", AArch64::AEK_PROFILE, "+spe", "-spe", FEAT_MAX, "", 0}, 226 {"ras", AArch64::AEK_RAS, "+ras", "-ras", FEAT_MAX, "", 0}, 227 {"rasv2", AArch64::AEK_RASv2, "+rasv2", "-rasv2", FEAT_MAX, "", 0}, 228 {"rcpc", AArch64::AEK_RCPC, "+rcpc", "-rcpc", FEAT_RCPC, "+rcpc", 230}, 229 {"rcpc2", AArch64::AEK_NONE, {}, {}, FEAT_RCPC2, "+rcpc", 240}, 230 {"rcpc3", AArch64::AEK_RCPC3, "+rcpc3", "-rcpc3", FEAT_MAX, "", 0}, 231 {"rdm", AArch64::AEK_RDM, "+rdm", "-rdm", FEAT_RDM, "+rdm,+fp-armv8,+neon", 70}, 232 {"rng", AArch64::AEK_RAND, "+rand", "-rand", FEAT_RNG, "+rand", 10}, 233 {"rpres", AArch64::AEK_NONE, {}, {}, FEAT_RPRES, "", 300}, 234 {"sb", AArch64::AEK_SB, "+sb", "-sb", FEAT_SB, "+sb", 470}, 235 {"sha1", AArch64::AEK_NONE, {}, {}, FEAT_SHA1, "+fp-armv8,+neon", 120}, 236 {"sha2", AArch64::AEK_SHA2, "+sha2", "-sha2", FEAT_SHA2, "+sha2,+fp-armv8,+neon", 130}, 237 {"sha3", AArch64::AEK_SHA3, "+sha3", "-sha3", FEAT_SHA3, "+sha3,+sha2,+fp-armv8,+neon", 140}, 238 {"simd", AArch64::AEK_SIMD, "+neon", "-neon", FEAT_SIMD, "+fp-armv8,+neon", 100}, 239 {"sm4", AArch64::AEK_SM4, "+sm4", "-sm4", FEAT_SM4, "+sm4,+fp-armv8,+neon", 60}, 240 {"sme-f16f16", AArch64::AEK_SMEF16F16, "+sme-f16f16", "-sme-f16f16", FEAT_MAX, "", 0}, 241 {"sme-f64f64", AArch64::AEK_SMEF64F64, "+sme-f64f64", "-sme-f64f64", FEAT_SME_F64, "+sme,+sme-f64f64,+bf16", 560}, 242 {"sme-i16i64", AArch64::AEK_SMEI16I64, "+sme-i16i64", "-sme-i16i64", FEAT_SME_I64, "+sme,+sme-i16i64,+bf16", 570}, 243 {"sme", AArch64::AEK_SME, "+sme", "-sme", FEAT_SME, "+sme,+bf16", 430}, 244 {"sme2", AArch64::AEK_SME2, "+sme2", "-sme2", FEAT_SME2, "+sme2,+sme,+bf16", 580}, 245 {"sme2p1", AArch64::AEK_SME2p1, "+sme2p1", "-sme2p1", FEAT_MAX, "", 0}, 246 {"ssbs", AArch64::AEK_SSBS, "+ssbs", "-ssbs", FEAT_SSBS, "", 490}, 247 {"ssbs2", AArch64::AEK_NONE, {}, {}, FEAT_SSBS2, "+ssbs", 500}, 248 {"sve-bf16", AArch64::AEK_NONE, {}, {}, FEAT_SVE_BF16, "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 320}, 249 {"sve-ebf16", AArch64::AEK_NONE, {}, {}, FEAT_SVE_EBF16, "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 330}, 250 {"sve-i8mm", AArch64::AEK_NONE, {}, {}, FEAT_SVE_I8MM, "+sve,+i8mm,+fullfp16,+fp-armv8,+neon", 340}, 251 {"sve", AArch64::AEK_SVE, "+sve", "-sve", FEAT_SVE, "+sve,+fullfp16,+fp-armv8,+neon", 310}, 252 {"sve2-aes", AArch64::AEK_SVE2AES, "+sve2-aes", "-sve2-aes", FEAT_SVE_AES, "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 380}, 253 {"sve2-bitperm", AArch64::AEK_SVE2BITPERM, "+sve2-bitperm", "-sve2-bitperm", FEAT_SVE_BITPERM, "+sve2,+sve,+sve2-bitperm,+fullfp16,+fp-armv8,+neon", 400}, 254 {"sve2-pmull128", AArch64::AEK_NONE, {}, {}, FEAT_SVE_PMULL128, "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 390}, 255 {"sve2-sha3", AArch64::AEK_SVE2SHA3, "+sve2-sha3", "-sve2-sha3", FEAT_SVE_SHA3, "+sve2,+sve,+sve2-sha3,+fullfp16,+fp-armv8,+neon", 410}, 256 {"sve2-sm4", AArch64::AEK_SVE2SM4, "+sve2-sm4", "-sve2-sm4", FEAT_SVE_SM4, "+sve2,+sve,+sve2-sm4,+fullfp16,+fp-armv8,+neon", 420}, 257 {"sve2", AArch64::AEK_SVE2, "+sve2", "-sve2", FEAT_SVE2, "+sve2,+sve,+fullfp16,+fp-armv8,+neon", 370}, 258 {"sve2p1", AArch64::AEK_SVE2p1, "+sve2p1", "-sve2p1", FEAT_MAX, "+sve2p1,+sve2,+sve,+fullfp16,+fp-armv8,+neon", 0}, 259 {"the", AArch64::AEK_THE, "+the", "-the", FEAT_MAX, "", 0}, 260 {"tme", AArch64::AEK_TME, "+tme", "-tme", FEAT_MAX, "", 0}, 261 {"wfxt", AArch64::AEK_NONE, {}, {}, FEAT_WFXT, "+wfxt", 550}, 262 {"gcs", AArch64::AEK_GCS, "+gcs", "-gcs", FEAT_MAX, "", 0}, 263 // Special cases 264 {"none", AArch64::AEK_NONE, {}, {}, FEAT_MAX, "", ExtensionInfo::MaxFMVPriority}, 265 }; 266 // clang-format on 267 268 enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' }; 269 270 // Information about a specific architecture, e.g. V8.1-A 271 struct ArchInfo { 272 VersionTuple Version; // Architecture version, major + minor. 273 ArchProfile Profile; // Architecuture profile 274 StringRef Name; // Human readable name, e.g. "armv8.1-a" 275 StringRef ArchFeature; // Command line feature flag, e.g. +v8a 276 uint64_t DefaultExts; // bitfield of default extensions ArchExtKind 277 278 bool operator==(const ArchInfo &Other) const { 279 return this->Name == Other.Name; 280 } 281 bool operator!=(const ArchInfo &Other) const { 282 return this->Name != Other.Name; 283 } 284 285 // Defines the following partial order, indicating when an architecture is 286 // a superset of another: 287 // 288 // v9.4a > v9.3a > v9.3a > v9.3a > v9a; 289 // v v v v v 290 // v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > v8.4a > ... > v8a; 291 // 292 // v8r has no relation to anything. This is used to determine which 293 // features to enable for a given architecture. See 294 // AArch64TargetInfo::setFeatureEnabled. 295 bool implies(const ArchInfo &Other) const { 296 if (this->Profile != Other.Profile) 297 return false; // ARMV8R 298 if (this->Version.getMajor() == Other.Version.getMajor()) { 299 return this->Version > Other.Version; 300 } 301 if (this->Version.getMajor() == 9 && Other.Version.getMajor() == 8) { 302 assert(this->Version.getMinor() && Other.Version.getMinor() && 303 "AArch64::ArchInfo should have a minor version."); 304 return this->Version.getMinor().value_or(0) + 5 >= 305 Other.Version.getMinor().value_or(0); 306 } 307 return false; 308 } 309 310 // Return ArchFeature without the leading "+". 311 StringRef getSubArch() const { return ArchFeature.substr(1); } 312 313 // Search for ArchInfo by SubArch name 314 static std::optional<ArchInfo> findBySubArch(StringRef SubArch); 315 }; 316 317 // clang-format off 318 inline constexpr ArchInfo ARMV8A = { VersionTuple{8, 0}, AProfile, "armv8-a", "+v8a", (AArch64::AEK_FP | AArch64::AEK_SIMD), }; 319 inline constexpr ArchInfo ARMV8_1A = { VersionTuple{8, 1}, AProfile, "armv8.1-a", "+v8.1a", (ARMV8A.DefaultExts | AArch64::AEK_CRC | AArch64::AEK_LSE | AArch64::AEK_RDM)}; 320 inline constexpr ArchInfo ARMV8_2A = { VersionTuple{8, 2}, AProfile, "armv8.2-a", "+v8.2a", (ARMV8_1A.DefaultExts | AArch64::AEK_RAS)}; 321 inline constexpr ArchInfo ARMV8_3A = { VersionTuple{8, 3}, AProfile, "armv8.3-a", "+v8.3a", (ARMV8_2A.DefaultExts | AArch64::AEK_RCPC)}; 322 inline constexpr ArchInfo ARMV8_4A = { VersionTuple{8, 4}, AProfile, "armv8.4-a", "+v8.4a", (ARMV8_3A.DefaultExts | AArch64::AEK_DOTPROD)}; 323 inline constexpr ArchInfo ARMV8_5A = { VersionTuple{8, 5}, AProfile, "armv8.5-a", "+v8.5a", (ARMV8_4A.DefaultExts)}; 324 inline constexpr ArchInfo ARMV8_6A = { VersionTuple{8, 6}, AProfile, "armv8.6-a", "+v8.6a", (ARMV8_5A.DefaultExts | AArch64::AEK_BF16 | AArch64::AEK_I8MM)}; 325 inline constexpr ArchInfo ARMV8_7A = { VersionTuple{8, 7}, AProfile, "armv8.7-a", "+v8.7a", (ARMV8_6A.DefaultExts)}; 326 inline constexpr ArchInfo ARMV8_8A = { VersionTuple{8, 8}, AProfile, "armv8.8-a", "+v8.8a", (ARMV8_7A.DefaultExts | AArch64::AEK_MOPS | AArch64::AEK_HBC)}; 327 inline constexpr ArchInfo ARMV8_9A = { VersionTuple{8, 9}, AProfile, "armv8.9-a", "+v8.9a", (ARMV8_8A.DefaultExts | AArch64::AEK_SPECRES2 | AArch64::AEK_CSSC | AArch64::AEK_RASv2)}; 328 inline constexpr ArchInfo ARMV9A = { VersionTuple{9, 0}, AProfile, "armv9-a", "+v9a", (ARMV8_5A.DefaultExts | AArch64::AEK_FP16 | AArch64::AEK_SVE | AArch64::AEK_SVE2)}; 329 inline constexpr ArchInfo ARMV9_1A = { VersionTuple{9, 1}, AProfile, "armv9.1-a", "+v9.1a", (ARMV9A.DefaultExts | AArch64::AEK_BF16 | AArch64::AEK_I8MM)}; 330 inline constexpr ArchInfo ARMV9_2A = { VersionTuple{9, 2}, AProfile, "armv9.2-a", "+v9.2a", (ARMV9_1A.DefaultExts)}; 331 inline constexpr ArchInfo ARMV9_3A = { VersionTuple{9, 3}, AProfile, "armv9.3-a", "+v9.3a", (ARMV9_2A.DefaultExts | AArch64::AEK_MOPS | AArch64::AEK_HBC)}; 332 inline constexpr ArchInfo ARMV9_4A = { VersionTuple{9, 4}, AProfile, "armv9.4-a", "+v9.4a", (ARMV9_3A.DefaultExts | AArch64::AEK_SPECRES2 | AArch64::AEK_CSSC | AArch64::AEK_RASv2)}; 333 // For v8-R, we do not enable crypto and align with GCC that enables a more minimal set of optional architecture extensions. 334 inline constexpr ArchInfo ARMV8R = { VersionTuple{8, 0}, RProfile, "armv8-r", "+v8r", ((ARMV8_5A.DefaultExts ^ AArch64::AEK_LSE) | AArch64::AEK_SSBS | AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SB), }; 335 // clang-format on 336 337 // The set of all architectures 338 static constexpr std::array<const ArchInfo *, 16> ArchInfos = { 339 &ARMV8A, &ARMV8_1A, &ARMV8_2A, &ARMV8_3A, &ARMV8_4A, &ARMV8_5A, 340 &ARMV8_6A, &ARMV8_7A, &ARMV8_8A, &ARMV8_9A, &ARMV9A, &ARMV9_1A, 341 &ARMV9_2A, &ARMV9_3A, &ARMV9_4A, &ARMV8R, 342 }; 343 344 // Details of a specific CPU. 345 struct CpuInfo { 346 StringRef Name; // Name, as written for -mcpu. 347 const ArchInfo &Arch; 348 uint64_t DefaultExtensions; // Default extensions for this CPU. These will be 349 // ORd with the architecture defaults. 350 351 uint64_t getImpliedExtensions() const { 352 return DefaultExtensions | Arch.DefaultExts; 353 } 354 }; 355 356 inline constexpr CpuInfo CpuInfos[] = { 357 {"cortex-a34", ARMV8A, 358 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)}, 359 {"cortex-a35", ARMV8A, 360 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)}, 361 {"cortex-a53", ARMV8A, 362 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)}, 363 {"cortex-a55", ARMV8_2A, 364 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 | 365 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC)}, 366 {"cortex-a510", ARMV9A, 367 (AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_SB | 368 AArch64::AEK_PAUTH | AArch64::AEK_MTE | AArch64::AEK_SSBS | 369 AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM | 370 AArch64::AEK_FP16FML)}, 371 {"cortex-a57", ARMV8A, 372 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)}, 373 {"cortex-a65", ARMV8_2A, 374 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD | 375 AArch64::AEK_FP16 | AArch64::AEK_RCPC | AArch64::AEK_SSBS)}, 376 {"cortex-a65ae", ARMV8_2A, 377 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD | 378 AArch64::AEK_FP16 | AArch64::AEK_RCPC | AArch64::AEK_SSBS)}, 379 {"cortex-a72", ARMV8A, 380 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)}, 381 {"cortex-a73", ARMV8A, 382 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)}, 383 {"cortex-a75", ARMV8_2A, 384 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 | 385 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC)}, 386 {"cortex-a76", ARMV8_2A, 387 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 | 388 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | AArch64::AEK_SSBS)}, 389 {"cortex-a76ae", ARMV8_2A, 390 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 | 391 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | AArch64::AEK_SSBS)}, 392 {"cortex-a77", ARMV8_2A, 393 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 | 394 AArch64::AEK_RCPC | AArch64::AEK_DOTPROD | AArch64::AEK_SSBS)}, 395 {"cortex-a78", ARMV8_2A, 396 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 | 397 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | AArch64::AEK_SSBS | 398 AArch64::AEK_PROFILE)}, 399 {"cortex-a78c", ARMV8_2A, 400 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 | 401 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | AArch64::AEK_SSBS | 402 AArch64::AEK_PROFILE | AArch64::AEK_FLAGM | AArch64::AEK_PAUTH | 403 AArch64::AEK_FP16FML)}, 404 {"cortex-a710", ARMV9A, 405 (AArch64::AEK_MTE | AArch64::AEK_PAUTH | AArch64::AEK_FLAGM | 406 AArch64::AEK_SB | AArch64::AEK_I8MM | AArch64::AEK_FP16FML | 407 AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM | 408 AArch64::AEK_BF16)}, 409 {"cortex-a715", ARMV9A, 410 (AArch64::AEK_SB | AArch64::AEK_SSBS | AArch64::AEK_MTE | 411 AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_PAUTH | 412 AArch64::AEK_I8MM | AArch64::AEK_PREDRES | AArch64::AEK_PERFMON | 413 AArch64::AEK_PROFILE | AArch64::AEK_SVE | AArch64::AEK_SVE2BITPERM | 414 AArch64::AEK_BF16 | AArch64::AEK_FLAGM)}, 415 {"cortex-r82", ARMV8R, (AArch64::AEK_LSE)}, 416 {"cortex-x1", ARMV8_2A, 417 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 | 418 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | AArch64::AEK_SSBS | 419 AArch64::AEK_PROFILE)}, 420 {"cortex-x1c", ARMV8_2A, 421 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 | 422 AArch64::AEK_DOTPROD | AArch64::AEK_RCPC | AArch64::AEK_SSBS | 423 AArch64::AEK_PAUTH | AArch64::AEK_PROFILE)}, 424 {"cortex-x2", ARMV9A, 425 (AArch64::AEK_MTE | AArch64::AEK_BF16 | AArch64::AEK_I8MM | 426 AArch64::AEK_PAUTH | AArch64::AEK_SSBS | AArch64::AEK_SB | 427 AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM | 428 AArch64::AEK_FP16FML)}, 429 {"cortex-x3", ARMV9A, 430 (AArch64::AEK_SVE | AArch64::AEK_PERFMON | AArch64::AEK_PROFILE | 431 AArch64::AEK_BF16 | AArch64::AEK_I8MM | AArch64::AEK_MTE | 432 AArch64::AEK_SVE2BITPERM | AArch64::AEK_SB | AArch64::AEK_PAUTH | 433 AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_PREDRES | 434 AArch64::AEK_FLAGM | AArch64::AEK_SSBS)}, 435 {"neoverse-e1", ARMV8_2A, 436 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD | 437 AArch64::AEK_FP16 | AArch64::AEK_RCPC | AArch64::AEK_SSBS)}, 438 {"neoverse-n1", ARMV8_2A, 439 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD | 440 AArch64::AEK_FP16 | AArch64::AEK_PROFILE | AArch64::AEK_RCPC | 441 AArch64::AEK_SSBS)}, 442 {"neoverse-n2", ARMV8_5A, 443 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 | 444 AArch64::AEK_SM4 | AArch64::AEK_BF16 | AArch64::AEK_DOTPROD | 445 AArch64::AEK_FP16 | AArch64::AEK_I8MM | AArch64::AEK_MTE | 446 AArch64::AEK_SB | AArch64::AEK_SSBS | AArch64::AEK_SVE | 447 AArch64::AEK_SVE2 | AArch64::AEK_SVE2BITPERM)}, 448 {"neoverse-512tvb", ARMV8_4A, 449 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 | 450 AArch64::AEK_SM4 | AArch64::AEK_SVE | AArch64::AEK_SSBS | 451 AArch64::AEK_FP16 | AArch64::AEK_BF16 | AArch64::AEK_DOTPROD | 452 AArch64::AEK_PROFILE | AArch64::AEK_RAND | AArch64::AEK_FP16FML | 453 AArch64::AEK_I8MM)}, 454 {"neoverse-v1", ARMV8_4A, 455 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 | 456 AArch64::AEK_SM4 | AArch64::AEK_SVE | AArch64::AEK_SSBS | 457 AArch64::AEK_FP16 | AArch64::AEK_BF16 | AArch64::AEK_DOTPROD | 458 AArch64::AEK_PROFILE | AArch64::AEK_RAND | AArch64::AEK_FP16FML | 459 AArch64::AEK_I8MM)}, 460 {"neoverse-v2", ARMV9A, 461 (AArch64::AEK_SVE | AArch64::AEK_SVE2 | AArch64::AEK_SSBS | 462 AArch64::AEK_FP16 | AArch64::AEK_BF16 | AArch64::AEK_RAND | 463 AArch64::AEK_DOTPROD | AArch64::AEK_PROFILE | AArch64::AEK_SVE2BITPERM | 464 AArch64::AEK_FP16FML | AArch64::AEK_I8MM | AArch64::AEK_MTE)}, 465 {"cyclone", ARMV8A, 466 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_NONE)}, 467 {"apple-a7", ARMV8A, 468 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_NONE)}, 469 {"apple-a8", ARMV8A, 470 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_NONE)}, 471 {"apple-a9", ARMV8A, 472 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_NONE)}, 473 {"apple-a10", ARMV8A, 474 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC | 475 AArch64::AEK_RDM)}, 476 {"apple-a11", ARMV8_2A, 477 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16)}, 478 {"apple-a12", ARMV8_3A, 479 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16)}, 480 {"apple-a13", ARMV8_4A, 481 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 | 482 AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3)}, 483 {"apple-a14", ARMV8_5A, 484 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 | 485 AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3)}, 486 {"apple-a15", ARMV8_5A, 487 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 | 488 AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3 | 489 AArch64::AEK_BF16 | AArch64::AEK_I8MM)}, 490 {"apple-a16", ARMV8_5A, 491 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 | 492 AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3 | 493 AArch64::AEK_BF16 | AArch64::AEK_I8MM)}, 494 {"apple-m1", ARMV8_5A, 495 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 | 496 AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3)}, 497 {"apple-m2", ARMV8_5A, 498 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 | 499 AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_SHA3 | 500 AArch64::AEK_BF16 | AArch64::AEK_I8MM)}, 501 {"apple-s4", ARMV8_3A, 502 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16)}, 503 {"apple-s5", ARMV8_3A, 504 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16)}, 505 {"exynos-m3", ARMV8A, 506 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)}, 507 {"exynos-m4", ARMV8_2A, 508 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD | 509 AArch64::AEK_FP16)}, 510 {"exynos-m5", ARMV8_2A, 511 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD | 512 AArch64::AEK_FP16)}, 513 {"falkor", ARMV8A, 514 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC | 515 AArch64::AEK_RDM)}, 516 {"saphira", ARMV8_3A, 517 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_PROFILE)}, 518 {"kryo", ARMV8A, (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)}, 519 {"thunderx2t99", ARMV8_1A, (AArch64::AEK_AES | AArch64::AEK_SHA2)}, 520 {"thunderx3t110", ARMV8_3A, (AArch64::AEK_AES | AArch64::AEK_SHA2)}, 521 {"thunderx", ARMV8A, 522 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)}, 523 {"thunderxt88", ARMV8A, 524 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)}, 525 {"thunderxt81", ARMV8A, 526 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)}, 527 {"thunderxt83", ARMV8A, 528 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_CRC)}, 529 {"tsv110", ARMV8_2A, 530 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_DOTPROD | 531 AArch64::AEK_FP16 | AArch64::AEK_FP16FML | AArch64::AEK_PROFILE)}, 532 {"a64fx", ARMV8_2A, 533 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16 | 534 AArch64::AEK_SVE)}, 535 {"carmel", ARMV8_2A, 536 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_FP16)}, 537 {"ampere1", ARMV8_6A, 538 (AArch64::AEK_AES | AArch64::AEK_SHA2 | AArch64::AEK_SHA3 | 539 AArch64::AEK_FP16 | AArch64::AEK_SB | AArch64::AEK_SSBS | 540 AArch64::AEK_RAND)}, 541 {"ampere1a", ARMV8_6A, 542 (AArch64::AEK_FP16 | AArch64::AEK_RAND | AArch64::AEK_SM4 | 543 AArch64::AEK_SHA3 | AArch64::AEK_SHA2 | AArch64::AEK_AES | 544 AArch64::AEK_MTE | AArch64::AEK_SB | AArch64::AEK_SSBS)}, 545 }; 546 547 // An alias for a CPU. 548 struct CpuAlias { 549 StringRef Alias; 550 StringRef Name; 551 }; 552 553 inline constexpr CpuAlias CpuAliases[] = {{"grace", "neoverse-v2"}}; 554 555 bool getExtensionFeatures(uint64_t Extensions, 556 std::vector<StringRef> &Features); 557 558 StringRef getArchExtFeature(StringRef ArchExt); 559 StringRef resolveCPUAlias(StringRef CPU); 560 561 // Information by Name 562 std::optional<ArchInfo> getArchForCpu(StringRef CPU); 563 564 // Parser 565 std::optional<ArchInfo> parseArch(StringRef Arch); 566 std::optional<ExtensionInfo> parseArchExtension(StringRef Extension); 567 // Given the name of a CPU or alias, return the correponding CpuInfo. 568 std::optional<CpuInfo> parseCpu(StringRef Name); 569 // Used by target parser tests 570 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values); 571 572 bool isX18ReservedByDefault(const Triple &TT); 573 574 // For given feature names, return a bitmask corresponding to the entries of 575 // AArch64::CPUFeatures. The values in CPUFeatures are not bitmasks 576 // themselves, they are sequential (0, 1, 2, 3, ...). 577 uint64_t getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs); 578 579 } // namespace AArch64 580 } // namespace llvm 581 582 #endif 583