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 // Arch extension modifiers for CPUs. These are labelled with their Arm ARM 107 // feature name (though the canonical reference for those is AArch64.td) 108 // clang-format off 109 enum ArchExtKind : unsigned { 110 AEK_NONE = 1, 111 AEK_CRC = 2, // FEAT_CRC32 112 AEK_CRYPTO = 3, 113 AEK_FP = 4, // FEAT_FP 114 AEK_SIMD = 5, // FEAT_AdvSIMD 115 AEK_FP16 = 6, // FEAT_FP16 116 AEK_PROFILE = 7, // FEAT_SPE 117 AEK_RAS = 8, // FEAT_RAS, FEAT_RASv1p1 118 AEK_LSE = 9, // FEAT_LSE 119 AEK_SVE = 10, // FEAT_SVE 120 AEK_DOTPROD = 11, // FEAT_DotProd 121 AEK_RCPC = 12, // FEAT_LRCPC 122 AEK_RDM = 13, // FEAT_RDM 123 AEK_SM4 = 14, // FEAT_SM4, FEAT_SM3 124 AEK_SHA3 = 15, // FEAT_SHA3, FEAT_SHA512 125 AEK_SHA2 = 16, // FEAT_SHA1, FEAT_SHA256 126 AEK_AES = 17, // FEAT_AES, FEAT_PMULL 127 AEK_FP16FML = 18, // FEAT_FHM 128 AEK_RAND = 19, // FEAT_RNG 129 AEK_MTE = 20, // FEAT_MTE, FEAT_MTE2 130 AEK_SSBS = 21, // FEAT_SSBS, FEAT_SSBS2 131 AEK_SB = 22, // FEAT_SB 132 AEK_PREDRES = 23, // FEAT_SPECRES 133 AEK_SVE2 = 24, // FEAT_SVE2 134 AEK_SVE2AES = 25, // FEAT_SVE_AES, FEAT_SVE_PMULL128 135 AEK_SVE2SM4 = 26, // FEAT_SVE_SM4 136 AEK_SVE2SHA3 = 27, // FEAT_SVE_SHA3 137 AEK_SVE2BITPERM = 28, // FEAT_SVE_BitPerm 138 AEK_TME = 29, // FEAT_TME 139 AEK_BF16 = 30, // FEAT_BF16 140 AEK_I8MM = 31, // FEAT_I8MM 141 AEK_F32MM = 32, // FEAT_F32MM 142 AEK_F64MM = 33, // FEAT_F64MM 143 AEK_LS64 = 34, // FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA 144 AEK_BRBE = 35, // FEAT_BRBE 145 AEK_PAUTH = 36, // FEAT_PAuth 146 AEK_FLAGM = 37, // FEAT_FlagM 147 AEK_SME = 38, // FEAT_SME 148 AEK_SMEF64F64 = 39, // FEAT_SME_F64F64 149 AEK_SMEI16I64 = 40, // FEAT_SME_I16I64 150 AEK_HBC = 41, // FEAT_HBC 151 AEK_MOPS = 42, // FEAT_MOPS 152 AEK_PERFMON = 43, // FEAT_PMUv3 153 AEK_SME2 = 44, // FEAT_SME2 154 AEK_SVE2p1 = 45, // FEAT_SVE2p1 155 AEK_SME2p1 = 46, // FEAT_SME2p1 156 AEK_B16B16 = 47, // FEAT_B16B16 157 AEK_SMEF16F16 = 48, // FEAT_SMEF16F16 158 AEK_CSSC = 49, // FEAT_CSSC 159 AEK_RCPC3 = 50, // FEAT_LRCPC3 160 AEK_THE = 51, // FEAT_THE 161 AEK_D128 = 52, // FEAT_D128 162 AEK_LSE128 = 53, // FEAT_LSE128 163 AEK_SPECRES2 = 54, // FEAT_SPECRES2 164 AEK_RASv2 = 55, // FEAT_RASv2 165 AEK_ITE = 56, // FEAT_ITE 166 AEK_GCS = 57, // FEAT_GCS 167 AEK_FPMR = 58, // FEAT_FPMR 168 AEK_FP8 = 59, // FEAT_FP8 169 AEK_FAMINMAX = 60, // FEAT_FAMINMAX 170 AEK_FP8FMA = 61, // FEAT_FP8FMA 171 AEK_SSVE_FP8FMA = 62, // FEAT_SSVE_FP8FMA 172 AEK_FP8DOT2 = 63, // FEAT_FP8DOT2 173 AEK_SSVE_FP8DOT2 = 64, // FEAT_SSVE_FP8DOT2 174 AEK_FP8DOT4 = 65, // FEAT_FP8DOT4 175 AEK_SSVE_FP8DOT4 = 66, // FEAT_SSVE_FP8DOT4 176 AEK_LUT = 67, // FEAT_LUT 177 AEK_SME_LUTv2 = 68, // FEAT_SME_LUTv2 178 AEK_SMEF8F16 = 69, // FEAT_SME_F8F16 179 AEK_SMEF8F32 = 70, // FEAT_SME_F8F32 180 AEK_SMEFA64 = 71, // FEAT_SME_FA64 181 AEK_CPA = 72, // FEAT_CPA 182 AEK_PAUTHLR = 73, // FEAT_PAuth_LR 183 AEK_TLBIW = 74, // FEAT_TLBIW 184 AEK_JSCVT = 75, // FEAT_JSCVT 185 AEK_FCMA = 76, // FEAT_FCMA 186 AEK_NUM_EXTENSIONS 187 }; 188 using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>; 189 // clang-format on 190 191 // Represents an extension that can be enabled with -march=<arch>+<extension>. 192 // Typically these correspond to Arm Architecture extensions, unlike 193 // SubtargetFeature which may represent either an actual extension or some 194 // internal LLVM property. 195 struct ExtensionInfo { 196 StringRef Name; // Human readable name, e.g. "profile". 197 ArchExtKind ID; // Corresponding to the ArchExtKind, this 198 // extensions representation in the bitfield. 199 StringRef Feature; // -mattr enable string, e.g. "+spe" 200 StringRef NegFeature; // -mattr disable string, e.g. "-spe" 201 CPUFeatures CPUFeature; // Function Multi Versioning (FMV) bitfield value 202 // set in __aarch64_cpu_features 203 StringRef DependentFeatures; // FMV enabled features string, 204 // e.g. "+dotprod,+fp-armv8,+neon" 205 unsigned FmvPriority; // FMV feature priority 206 static constexpr unsigned MaxFMVPriority = 207 1000; // Maximum priority for FMV feature 208 }; 209 210 // NOTE: If adding a new extension here, consider adding it to ExtensionMap 211 // in AArch64AsmParser too, if supported as an extension name by binutils. 212 // clang-format off 213 inline constexpr ExtensionInfo Extensions[] = { 214 {"aes", AArch64::AEK_AES, "+aes", "-aes", FEAT_AES, "+fp-armv8,+neon", 150}, 215 {"b16b16", AArch64::AEK_B16B16, "+b16b16", "-b16b16", FEAT_INIT, "", 0}, 216 {"bf16", AArch64::AEK_BF16, "+bf16", "-bf16", FEAT_BF16, "+bf16", 280}, 217 {"brbe", AArch64::AEK_BRBE, "+brbe", "-brbe", FEAT_INIT, "", 0}, 218 {"bti", AArch64::AEK_NONE, {}, {}, FEAT_BTI, "+bti", 510}, 219 {"crc", AArch64::AEK_CRC, "+crc", "-crc", FEAT_CRC, "+crc", 110}, 220 {"crypto", AArch64::AEK_CRYPTO, "+crypto", "-crypto", FEAT_INIT, "+aes,+sha2", 0}, 221 {"cssc", AArch64::AEK_CSSC, "+cssc", "-cssc", FEAT_INIT, "", 0}, 222 {"d128", AArch64::AEK_D128, "+d128", "-d128", FEAT_INIT, "", 0}, 223 {"dgh", AArch64::AEK_NONE, {}, {}, FEAT_DGH, "", 260}, 224 {"dit", AArch64::AEK_NONE, {}, {}, FEAT_DIT, "+dit", 180}, 225 {"dotprod", AArch64::AEK_DOTPROD, "+dotprod", "-dotprod", FEAT_DOTPROD, "+dotprod,+fp-armv8,+neon", 104}, 226 {"dpb", AArch64::AEK_NONE, {}, {}, FEAT_DPB, "+ccpp", 190}, 227 {"dpb2", AArch64::AEK_NONE, {}, {}, FEAT_DPB2, "+ccpp,+ccdp", 200}, 228 {"ebf16", AArch64::AEK_NONE, {}, {}, FEAT_EBF16, "+bf16", 290}, 229 {"f32mm", AArch64::AEK_F32MM, "+f32mm", "-f32mm", FEAT_SVE_F32MM, "+sve,+f32mm,+fullfp16,+fp-armv8,+neon", 350}, 230 {"f64mm", AArch64::AEK_F64MM, "+f64mm", "-f64mm", FEAT_SVE_F64MM, "+sve,+f64mm,+fullfp16,+fp-armv8,+neon", 360}, 231 {"fcma", AArch64::AEK_FCMA, "+complxnum", "-complxnum", FEAT_FCMA, "+fp-armv8,+neon,+complxnum", 220}, 232 {"flagm", AArch64::AEK_FLAGM, "+flagm", "-flagm", FEAT_FLAGM, "+flagm", 20}, 233 {"flagm2", AArch64::AEK_NONE, {}, {}, FEAT_FLAGM2, "+flagm,+altnzcv", 30}, 234 {"fp", AArch64::AEK_FP, "+fp-armv8", "-fp-armv8", FEAT_FP, "+fp-armv8,+neon", 90}, 235 {"fp16", AArch64::AEK_FP16, "+fullfp16", "-fullfp16", FEAT_FP16, "+fullfp16,+fp-armv8,+neon", 170}, 236 {"fp16fml", AArch64::AEK_FP16FML, "+fp16fml", "-fp16fml", FEAT_FP16FML, "+fp16fml,+fullfp16,+fp-armv8,+neon", 175}, 237 {"frintts", AArch64::AEK_NONE, {}, {}, FEAT_FRINTTS, "+fptoint", 250}, 238 {"hbc", AArch64::AEK_HBC, "+hbc", "-hbc", FEAT_INIT, "", 0}, 239 {"i8mm", AArch64::AEK_I8MM, "+i8mm", "-i8mm", FEAT_I8MM, "+i8mm", 270}, 240 {"ite", AArch64::AEK_ITE, "+ite", "-ite", FEAT_INIT, "", 0}, 241 {"jscvt", AArch64::AEK_JSCVT, "+jsconv", "-jsconv", FEAT_JSCVT, "+fp-armv8,+neon,+jsconv", 210}, 242 {"ls64_accdata", AArch64::AEK_NONE, {}, {}, FEAT_LS64_ACCDATA, "+ls64", 540}, 243 {"ls64_v", AArch64::AEK_NONE, {}, {}, FEAT_LS64_V, "", 530}, 244 {"ls64", AArch64::AEK_LS64, "+ls64", "-ls64", FEAT_LS64, "", 520}, 245 {"lse", AArch64::AEK_LSE, "+lse", "-lse", FEAT_LSE, "+lse", 80}, 246 {"lse128", AArch64::AEK_LSE128, "+lse128", "-lse128", FEAT_INIT, "", 0}, 247 {"memtag", AArch64::AEK_MTE, "+mte", "-mte", FEAT_MEMTAG, "", 440}, 248 {"memtag2", AArch64::AEK_NONE, {}, {}, FEAT_MEMTAG2, "+mte", 450}, 249 {"memtag3", AArch64::AEK_NONE, {}, {}, FEAT_MEMTAG3, "+mte", 460}, 250 {"mops", AArch64::AEK_MOPS, "+mops", "-mops", FEAT_MOPS, "+mops", 650}, 251 {"pauth", AArch64::AEK_PAUTH, "+pauth", "-pauth", FEAT_INIT, "", 0}, 252 {"pmull", AArch64::AEK_NONE, {}, {}, FEAT_PMULL, "+aes,+fp-armv8,+neon", 160}, 253 {"pmuv3", AArch64::AEK_PERFMON, "+perfmon", "-perfmon", FEAT_INIT, "", 0}, 254 {"predres", AArch64::AEK_PREDRES, "+predres", "-predres", FEAT_PREDRES, "+predres", 480}, 255 {"predres2", AArch64::AEK_SPECRES2, "+specres2", "-specres2", FEAT_INIT, "", 0}, 256 {"profile", AArch64::AEK_PROFILE, "+spe", "-spe", FEAT_INIT, "", 0}, 257 {"ras", AArch64::AEK_RAS, "+ras", "-ras", FEAT_INIT, "", 0}, 258 {"rasv2", AArch64::AEK_RASv2, "+rasv2", "-rasv2", FEAT_INIT, "", 0}, 259 {"rcpc", AArch64::AEK_RCPC, "+rcpc", "-rcpc", FEAT_RCPC, "+rcpc", 230}, 260 {"rcpc2", AArch64::AEK_NONE, {}, {}, FEAT_RCPC2, "+rcpc", 240}, 261 {"rcpc3", AArch64::AEK_RCPC3, "+rcpc3", "-rcpc3", FEAT_RCPC3, "+rcpc,+rcpc3", 241}, 262 {"rdm", AArch64::AEK_RDM, "+rdm", "-rdm", FEAT_RDM, "+rdm,+fp-armv8,+neon", 108}, 263 {"rng", AArch64::AEK_RAND, "+rand", "-rand", FEAT_RNG, "+rand", 10}, 264 {"rpres", AArch64::AEK_NONE, {}, {}, FEAT_RPRES, "", 300}, 265 {"sb", AArch64::AEK_SB, "+sb", "-sb", FEAT_SB, "+sb", 470}, 266 {"sha1", AArch64::AEK_NONE, {}, {}, FEAT_SHA1, "+fp-armv8,+neon", 120}, 267 {"sha2", AArch64::AEK_SHA2, "+sha2", "-sha2", FEAT_SHA2, "+sha2,+fp-armv8,+neon", 130}, 268 {"sha3", AArch64::AEK_SHA3, "+sha3", "-sha3", FEAT_SHA3, "+sha3,+sha2,+fp-armv8,+neon", 140}, 269 {"simd", AArch64::AEK_SIMD, "+neon", "-neon", FEAT_SIMD, "+fp-armv8,+neon", 100}, 270 {"sm4", AArch64::AEK_SM4, "+sm4", "-sm4", FEAT_SM4, "+sm4,+fp-armv8,+neon", 106}, 271 {"sme-f16f16", AArch64::AEK_SMEF16F16, "+sme-f16f16", "-sme-f16f16", FEAT_INIT, "", 0}, 272 {"sme-f64f64", AArch64::AEK_SMEF64F64, "+sme-f64f64", "-sme-f64f64", FEAT_SME_F64, "+sme,+sme-f64f64,+bf16", 560}, 273 {"sme-i16i64", AArch64::AEK_SMEI16I64, "+sme-i16i64", "-sme-i16i64", FEAT_SME_I64, "+sme,+sme-i16i64,+bf16", 570}, 274 {"sme", AArch64::AEK_SME, "+sme", "-sme", FEAT_SME, "+sme,+bf16", 430}, 275 {"sme2", AArch64::AEK_SME2, "+sme2", "-sme2", FEAT_SME2, "+sme2,+sme,+bf16", 580}, 276 {"sme2p1", AArch64::AEK_SME2p1, "+sme2p1", "-sme2p1", FEAT_INIT, "+sme2p1,+sme2,+sme,+bf16", 0}, 277 {"ssbs", AArch64::AEK_SSBS, "+ssbs", "-ssbs", FEAT_SSBS, "", 490}, 278 {"ssbs2", AArch64::AEK_NONE, {}, {}, FEAT_SSBS2, "+ssbs", 500}, 279 {"sve-bf16", AArch64::AEK_NONE, {}, {}, FEAT_SVE_BF16, "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 320}, 280 {"sve-ebf16", AArch64::AEK_NONE, {}, {}, FEAT_SVE_EBF16, "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 330}, 281 {"sve-i8mm", AArch64::AEK_NONE, {}, {}, FEAT_SVE_I8MM, "+sve,+i8mm,+fullfp16,+fp-armv8,+neon", 340}, 282 {"sve", AArch64::AEK_SVE, "+sve", "-sve", FEAT_SVE, "+sve,+fullfp16,+fp-armv8,+neon", 310}, 283 {"sve2-aes", AArch64::AEK_SVE2AES, "+sve2-aes", "-sve2-aes", FEAT_SVE_AES, "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 380}, 284 {"sve2-bitperm", AArch64::AEK_SVE2BITPERM, "+sve2-bitperm", "-sve2-bitperm", FEAT_SVE_BITPERM, "+sve2,+sve,+sve2-bitperm,+fullfp16,+fp-armv8,+neon", 400}, 285 {"sve2-pmull128", AArch64::AEK_NONE, {}, {}, FEAT_SVE_PMULL128, "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 390}, 286 {"sve2-sha3", AArch64::AEK_SVE2SHA3, "+sve2-sha3", "-sve2-sha3", FEAT_SVE_SHA3, "+sve2,+sve,+sve2-sha3,+fullfp16,+fp-armv8,+neon", 410}, 287 {"sve2-sm4", AArch64::AEK_SVE2SM4, "+sve2-sm4", "-sve2-sm4", FEAT_SVE_SM4, "+sve2,+sve,+sve2-sm4,+fullfp16,+fp-armv8,+neon", 420}, 288 {"sve2", AArch64::AEK_SVE2, "+sve2", "-sve2", FEAT_SVE2, "+sve2,+sve,+fullfp16,+fp-armv8,+neon", 370}, 289 {"sve2p1", AArch64::AEK_SVE2p1, "+sve2p1", "-sve2p1", FEAT_INIT, "+sve2p1,+sve2,+sve,+fullfp16,+fp-armv8,+neon", 0}, 290 {"the", AArch64::AEK_THE, "+the", "-the", FEAT_INIT, "", 0}, 291 {"tme", AArch64::AEK_TME, "+tme", "-tme", FEAT_INIT, "", 0}, 292 {"wfxt", AArch64::AEK_NONE, {}, {}, FEAT_WFXT, "+wfxt", 550}, 293 {"gcs", AArch64::AEK_GCS, "+gcs", "-gcs", FEAT_INIT, "", 0}, 294 {"fpmr", AArch64::AEK_FPMR, "+fpmr", "-fpmr", FEAT_INIT, "", 0}, 295 {"fp8", AArch64::AEK_FP8, "+fp8", "-fp8", FEAT_INIT, "+fpmr", 0}, 296 {"faminmax", AArch64::AEK_FAMINMAX, "+faminmax", "-faminmax", FEAT_INIT, "", 0}, 297 {"fp8fma", AArch64::AEK_FP8FMA, "+fp8fma", "-fp8fma", FEAT_INIT, "+fpmr", 0}, 298 {"ssve-fp8fma", AArch64::AEK_SSVE_FP8FMA, "+ssve-fp8fma", "-ssve-fp8fma", FEAT_INIT, "+sme2", 0}, 299 {"fp8dot2", AArch64::AEK_FP8DOT2, "+fp8dot2", "-fp8dot2", FEAT_INIT, "", 0}, 300 {"ssve-fp8dot2", AArch64::AEK_SSVE_FP8DOT2, "+ssve-fp8dot2", "-ssve-fp8dot2", FEAT_INIT, "+sme2", 0}, 301 {"fp8dot4", AArch64::AEK_FP8DOT4, "+fp8dot4", "-fp8dot4", FEAT_INIT, "", 0}, 302 {"ssve-fp8dot4", AArch64::AEK_SSVE_FP8DOT4, "+ssve-fp8dot4", "-ssve-fp8dot4", FEAT_INIT, "+sme2", 0}, 303 {"lut", AArch64::AEK_LUT, "+lut", "-lut", FEAT_INIT, "", 0}, 304 {"sme-lutv2", AArch64::AEK_SME_LUTv2, "+sme-lutv2", "-sme-lutv2", FEAT_INIT, "", 0}, 305 {"sme-f8f16", AArch64::AEK_SMEF8F16, "+sme-f8f16", "-sme-f8f16", FEAT_INIT, "+sme2,+fp8", 0}, 306 {"sme-f8f32", AArch64::AEK_SMEF8F32, "+sme-f8f32", "-sme-f8f32", FEAT_INIT, "+sme2,+fp8", 0}, 307 {"sme-fa64", AArch64::AEK_SMEFA64, "+sme-fa64", "-sme-fa64", FEAT_INIT, "", 0}, 308 {"cpa", AArch64::AEK_CPA, "+cpa", "-cpa", FEAT_INIT, "", 0}, 309 {"pauth-lr", AArch64::AEK_PAUTHLR, "+pauth-lr", "-pauth-lr", FEAT_INIT, "", 0}, 310 {"tlbiw", AArch64::AEK_TLBIW, "+tlbiw", "-tlbiw", FEAT_INIT, "", 0}, 311 // Special cases 312 {"none", AArch64::AEK_NONE, {}, {}, FEAT_INIT, "", ExtensionInfo::MaxFMVPriority}, 313 }; 314 // clang-format on 315 316 struct ExtensionSet { 317 // Set of extensions which are currently enabled. 318 ExtensionBitset Enabled; 319 // Set of extensions which have been enabled or disabled at any point. Used 320 // to avoid cluttering the cc1 command-line with lots of unneeded features. 321 ExtensionBitset Touched; 322 // Base architecture version, which we need to know because some feature 323 // dependencies change depending on this. 324 const ArchInfo *BaseArch; 325 ExtensionSetExtensionSet326 ExtensionSet() : Enabled(), Touched(), BaseArch(nullptr) {} 327 328 // Enable the given architecture extension, and any other extensions it 329 // depends on. Does not change the base architecture, or follow dependencies 330 // between features which are only related by required arcitecture versions. 331 void enable(ArchExtKind E); 332 333 // Disable the given architecture extension, and any other extensions which 334 // depend on it. Does not change the base architecture, or follow 335 // dependencies between features which are only related by required 336 // arcitecture versions. 337 void disable(ArchExtKind E); 338 339 // Add default extensions for the given CPU. Records the base architecture, 340 // to later resolve dependencies which depend on it. 341 void addCPUDefaults(const CpuInfo &CPU); 342 343 // Add default extensions for the given architecture version. Records the 344 // base architecture, to later resolve dependencies which depend on it. 345 void addArchDefaults(const ArchInfo &Arch); 346 347 // Add or remove a feature based on a modifier string. The string must be of 348 // the form "<name>" to enable a feature or "no<name>" to disable it. This 349 // will also enable or disable any features as required by the dependencies 350 // between them. 351 bool parseModifier(StringRef Modifier); 352 353 // Convert the set of enabled extension to an LLVM feature list, appending 354 // them to Features. 355 void toLLVMFeatureList(std::vector<StringRef> &Features) const; 356 }; 357 358 // Represents a dependency between two architecture extensions. Later is the 359 // feature which was added to the architecture after Earlier, and expands the 360 // functionality provided by it. If Later is enabled, then Earlier will also be 361 // enabled. If Earlier is disabled, then Later will also be disabled. 362 struct ExtensionDependency { 363 ArchExtKind Earlier; 364 ArchExtKind Later; 365 }; 366 367 // clang-format off 368 // Each entry here is a link in the dependency chain starting from the 369 // extension that was added to the architecture first. 370 inline constexpr ExtensionDependency ExtensionDependencies[] = { 371 {AEK_FP, AEK_FP16}, 372 {AEK_FP, AEK_SIMD}, 373 {AEK_FP, AEK_JSCVT}, 374 {AEK_FP, AEK_FP8}, 375 {AEK_SIMD, AEK_CRYPTO}, 376 {AEK_SIMD, AEK_AES}, 377 {AEK_SIMD, AEK_SHA2}, 378 {AEK_SIMD, AEK_SHA3}, 379 {AEK_SIMD, AEK_SM4}, 380 {AEK_SIMD, AEK_RDM}, 381 {AEK_SIMD, AEK_DOTPROD}, 382 {AEK_SIMD, AEK_FCMA}, 383 {AEK_FP16, AEK_FP16FML}, 384 {AEK_FP16, AEK_SVE}, 385 {AEK_BF16, AEK_SME}, 386 {AEK_BF16, AEK_B16B16}, 387 {AEK_SVE, AEK_SVE2}, 388 {AEK_SVE, AEK_F32MM}, 389 {AEK_SVE, AEK_F64MM}, 390 {AEK_SVE2, AEK_SVE2p1}, 391 {AEK_SVE2, AEK_SVE2BITPERM}, 392 {AEK_SVE2, AEK_SVE2AES}, 393 {AEK_SVE2, AEK_SVE2SHA3}, 394 {AEK_SVE2, AEK_SVE2SM4}, 395 {AEK_SVE2, AEK_SMEFA64}, 396 {AEK_SVE2, AEK_SMEFA64}, 397 {AEK_SME, AEK_SME2}, 398 {AEK_SME, AEK_SMEF16F16}, 399 {AEK_SME, AEK_SMEF64F64}, 400 {AEK_SME, AEK_SMEI16I64}, 401 {AEK_SME, AEK_SMEFA64}, 402 {AEK_SME2, AEK_SME2p1}, 403 {AEK_SME2, AEK_SSVE_FP8FMA}, 404 {AEK_SME2, AEK_SSVE_FP8DOT2}, 405 {AEK_SME2, AEK_SSVE_FP8DOT4}, 406 {AEK_SME2, AEK_SMEF8F16}, 407 {AEK_SME2, AEK_SMEF8F32}, 408 {AEK_FP8, AEK_SMEF8F16}, 409 {AEK_FP8, AEK_SMEF8F32}, 410 {AEK_LSE, AEK_LSE128}, 411 {AEK_PREDRES, AEK_SPECRES2}, 412 {AEK_RAS, AEK_RASv2}, 413 {AEK_RCPC, AEK_RCPC3}, 414 }; 415 // clang-format on 416 417 enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' }; 418 419 // Information about a specific architecture, e.g. V8.1-A 420 struct ArchInfo { 421 VersionTuple Version; // Architecture version, major + minor. 422 ArchProfile Profile; // Architecuture profile 423 StringRef Name; // Human readable name, e.g. "armv8.1-a" 424 StringRef ArchFeature; // Command line feature flag, e.g. +v8a 425 AArch64::ExtensionBitset 426 DefaultExts; // bitfield of default extensions ArchExtKind 427 428 bool operator==(const ArchInfo &Other) const { 429 return this->Name == Other.Name; 430 } 431 bool operator!=(const ArchInfo &Other) const { 432 return this->Name != Other.Name; 433 } 434 435 // Defines the following partial order, indicating when an architecture is 436 // a superset of another: 437 // 438 // v9.5a > v9.4a > v9.3a > v9.2a > v9.1a > v9a; 439 // v v v v v 440 // v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > v8.4a > ... > v8a; 441 // 442 // v8r has no relation to anything. This is used to determine which 443 // features to enable for a given architecture. See 444 // AArch64TargetInfo::setFeatureEnabled. impliesArchInfo445 bool implies(const ArchInfo &Other) const { 446 if (this->Profile != Other.Profile) 447 return false; // ARMV8R 448 if (this->Version.getMajor() == Other.Version.getMajor()) { 449 return this->Version > Other.Version; 450 } 451 if (this->Version.getMajor() == 9 && Other.Version.getMajor() == 8) { 452 assert(this->Version.getMinor() && Other.Version.getMinor() && 453 "AArch64::ArchInfo should have a minor version."); 454 return this->Version.getMinor().value_or(0) + 5 >= 455 Other.Version.getMinor().value_or(0); 456 } 457 return false; 458 } 459 460 // True if this architecture is a superset of Other (including being equal to 461 // it). is_supersetArchInfo462 bool is_superset(const ArchInfo &Other) const { 463 return (*this == Other) || implies(Other); 464 } 465 466 // Return ArchFeature without the leading "+". getSubArchArchInfo467 StringRef getSubArch() const { return ArchFeature.substr(1); } 468 469 // Search for ArchInfo by SubArch name 470 static std::optional<ArchInfo> findBySubArch(StringRef SubArch); 471 }; 472 473 // clang-format off 474 inline constexpr ArchInfo ARMV8A = { VersionTuple{8, 0}, AProfile, "armv8-a", "+v8a", ( 475 AArch64::ExtensionBitset({AArch64::AEK_FP, AArch64::AEK_SIMD})), }; 476 inline constexpr ArchInfo ARMV8_1A = { VersionTuple{8, 1}, AProfile, "armv8.1-a", "+v8.1a", (ARMV8A.DefaultExts | 477 AArch64::ExtensionBitset({AArch64::AEK_CRC, AArch64::AEK_LSE, AArch64::AEK_RDM}))}; 478 inline constexpr ArchInfo ARMV8_2A = { VersionTuple{8, 2}, AProfile, "armv8.2-a", "+v8.2a", (ARMV8_1A.DefaultExts | 479 AArch64::ExtensionBitset({AArch64::AEK_RAS}))}; 480 inline constexpr ArchInfo ARMV8_3A = { VersionTuple{8, 3}, AProfile, "armv8.3-a", "+v8.3a", (ARMV8_2A.DefaultExts | 481 AArch64::ExtensionBitset({AArch64::AEK_FCMA, AArch64::AEK_JSCVT, AArch64::AEK_PAUTH, AArch64::AEK_RCPC}))}; 482 inline constexpr ArchInfo ARMV8_4A = { VersionTuple{8, 4}, AProfile, "armv8.4-a", "+v8.4a", (ARMV8_3A.DefaultExts | 483 AArch64::ExtensionBitset({AArch64::AEK_DOTPROD}))}; 484 inline constexpr ArchInfo ARMV8_5A = { VersionTuple{8, 5}, AProfile, "armv8.5-a", "+v8.5a", (ARMV8_4A.DefaultExts)}; 485 inline constexpr ArchInfo ARMV8_6A = { VersionTuple{8, 6}, AProfile, "armv8.6-a", "+v8.6a", (ARMV8_5A.DefaultExts | 486 AArch64::ExtensionBitset({AArch64::AEK_BF16, AArch64::AEK_I8MM}))}; 487 inline constexpr ArchInfo ARMV8_7A = { VersionTuple{8, 7}, AProfile, "armv8.7-a", "+v8.7a", (ARMV8_6A.DefaultExts)}; 488 inline constexpr ArchInfo ARMV8_8A = { VersionTuple{8, 8}, AProfile, "armv8.8-a", "+v8.8a", (ARMV8_7A.DefaultExts | 489 AArch64::ExtensionBitset({AArch64::AEK_MOPS, AArch64::AEK_HBC}))}; 490 inline constexpr ArchInfo ARMV8_9A = { VersionTuple{8, 9}, AProfile, "armv8.9-a", "+v8.9a", (ARMV8_8A.DefaultExts | 491 AArch64::ExtensionBitset({AArch64::AEK_SPECRES2, AArch64::AEK_CSSC, AArch64::AEK_RASv2}))}; 492 inline constexpr ArchInfo ARMV9A = { VersionTuple{9, 0}, AProfile, "armv9-a", "+v9a", (ARMV8_5A.DefaultExts | 493 AArch64::ExtensionBitset({AArch64::AEK_FP16, AArch64::AEK_SVE, AArch64::AEK_SVE2}))}; 494 inline constexpr ArchInfo ARMV9_1A = { VersionTuple{9, 1}, AProfile, "armv9.1-a", "+v9.1a", (ARMV9A.DefaultExts | 495 AArch64::ExtensionBitset({AArch64::AEK_BF16, AArch64::AEK_I8MM}))}; 496 inline constexpr ArchInfo ARMV9_2A = { VersionTuple{9, 2}, AProfile, "armv9.2-a", "+v9.2a", (ARMV9_1A.DefaultExts)}; 497 inline constexpr ArchInfo ARMV9_3A = { VersionTuple{9, 3}, AProfile, "armv9.3-a", "+v9.3a", (ARMV9_2A.DefaultExts | 498 AArch64::ExtensionBitset({AArch64::AEK_MOPS, AArch64::AEK_HBC}))}; 499 inline constexpr ArchInfo ARMV9_4A = { VersionTuple{9, 4}, AProfile, "armv9.4-a", "+v9.4a", (ARMV9_3A.DefaultExts | 500 AArch64::ExtensionBitset({AArch64::AEK_SPECRES2, AArch64::AEK_CSSC, AArch64::AEK_RASv2}))}; 501 inline constexpr ArchInfo ARMV9_5A = { VersionTuple{9, 5}, AProfile, "armv9.5-a", "+v9.5a", (ARMV9_4A.DefaultExts | 502 AArch64::ExtensionBitset({AArch64::AEK_CPA}))}; 503 // For v8-R, we do not enable crypto and align with GCC that enables a more minimal set of optional architecture extensions. 504 inline constexpr ArchInfo ARMV8R = { VersionTuple{8, 0}, RProfile, "armv8-r", "+v8r", (ARMV8_5A.DefaultExts | 505 AArch64::ExtensionBitset({AArch64::AEK_SSBS, 506 AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_SB}).flip(AArch64::AEK_LSE))}; 507 // clang-format on 508 509 // The set of all architectures 510 static constexpr std::array<const ArchInfo *, 17> ArchInfos = { 511 &ARMV8A, &ARMV8_1A, &ARMV8_2A, &ARMV8_3A, &ARMV8_4A, &ARMV8_5A, 512 &ARMV8_6A, &ARMV8_7A, &ARMV8_8A, &ARMV8_9A, &ARMV9A, &ARMV9_1A, 513 &ARMV9_2A, &ARMV9_3A, &ARMV9_4A, &ARMV9_5A, &ARMV8R, 514 }; 515 516 // Details of a specific CPU. 517 struct CpuInfo { 518 StringRef Name; // Name, as written for -mcpu. 519 const ArchInfo &Arch; 520 AArch64::ExtensionBitset 521 DefaultExtensions; // Default extensions for this CPU. These will be 522 // ORd with the architecture defaults. 523 getImpliedExtensionsCpuInfo524 AArch64::ExtensionBitset getImpliedExtensions() const { 525 AArch64::ExtensionBitset ImpliedExts; 526 ImpliedExts |= DefaultExtensions; 527 ImpliedExts |= Arch.DefaultExts; 528 return ImpliedExts; 529 } 530 }; 531 532 inline constexpr CpuInfo CpuInfos[] = { 533 {"cortex-a34", ARMV8A, 534 AArch64::ExtensionBitset( 535 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 536 {"cortex-a35", ARMV8A, 537 AArch64::ExtensionBitset( 538 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 539 {"cortex-a53", ARMV8A, 540 AArch64::ExtensionBitset( 541 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 542 {"cortex-a55", ARMV8_2A, 543 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 544 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 545 AArch64::AEK_RCPC})}, 546 {"cortex-a510", ARMV9A, 547 AArch64::ExtensionBitset( 548 {AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_SB, 549 AArch64::AEK_PAUTH, AArch64::AEK_MTE, AArch64::AEK_SSBS, 550 AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM, 551 AArch64::AEK_FP16FML})}, 552 {"cortex-a520", ARMV9_2A, 553 AArch64::ExtensionBitset( 554 {AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_MTE, 555 AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, 556 AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, AArch64::AEK_PREDRES})}, 557 {"cortex-a57", ARMV8A, 558 AArch64::ExtensionBitset( 559 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 560 {"cortex-a65", ARMV8_2A, 561 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 562 AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 563 AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, 564 {"cortex-a65ae", ARMV8_2A, 565 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 566 AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 567 AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, 568 {"cortex-a72", ARMV8A, 569 AArch64::ExtensionBitset( 570 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 571 {"cortex-a73", ARMV8A, 572 AArch64::ExtensionBitset( 573 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 574 {"cortex-a75", ARMV8_2A, 575 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 576 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 577 AArch64::AEK_RCPC})}, 578 {"cortex-a76", ARMV8_2A, 579 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 580 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 581 AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, 582 {"cortex-a76ae", ARMV8_2A, 583 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 584 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 585 AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, 586 {"cortex-a77", ARMV8_2A, 587 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 588 AArch64::AEK_FP16, AArch64::AEK_RCPC, 589 AArch64::AEK_DOTPROD, AArch64::AEK_SSBS})}, 590 {"cortex-a78", ARMV8_2A, 591 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 592 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 593 AArch64::AEK_RCPC, AArch64::AEK_SSBS, 594 AArch64::AEK_PROFILE})}, 595 {"cortex-a78ae", ARMV8_2A, 596 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 597 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 598 AArch64::AEK_RCPC, AArch64::AEK_SSBS, 599 AArch64::AEK_PROFILE})}, 600 {"cortex-a78c", ARMV8_2A, 601 AArch64::ExtensionBitset( 602 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, 603 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS, 604 AArch64::AEK_PROFILE, AArch64::AEK_FLAGM, AArch64::AEK_PAUTH})}, 605 {"cortex-a710", ARMV9A, 606 AArch64::ExtensionBitset({AArch64::AEK_MTE, AArch64::AEK_PAUTH, 607 AArch64::AEK_FLAGM, AArch64::AEK_SB, 608 AArch64::AEK_I8MM, AArch64::AEK_FP16FML, 609 AArch64::AEK_SVE, AArch64::AEK_SVE2, 610 AArch64::AEK_SVE2BITPERM, AArch64::AEK_BF16})}, 611 {"cortex-a715", ARMV9A, 612 AArch64::ExtensionBitset( 613 {AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_MTE, 614 AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, 615 AArch64::AEK_I8MM, AArch64::AEK_PREDRES, AArch64::AEK_PERFMON, 616 AArch64::AEK_PROFILE, AArch64::AEK_SVE, AArch64::AEK_SVE2BITPERM, 617 AArch64::AEK_BF16, AArch64::AEK_FLAGM})}, 618 {"cortex-a720", ARMV9_2A, 619 AArch64::ExtensionBitset({AArch64::AEK_SB, AArch64::AEK_SSBS, 620 AArch64::AEK_MTE, AArch64::AEK_FP16FML, 621 AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, 622 AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, 623 AArch64::AEK_PREDRES, AArch64::AEK_PROFILE})}, 624 {"cortex-r82", ARMV8R, AArch64::ExtensionBitset({AArch64::AEK_LSE})}, 625 {"cortex-x1", ARMV8_2A, 626 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 627 AArch64::AEK_FP16, AArch64::AEK_DOTPROD, 628 AArch64::AEK_RCPC, AArch64::AEK_SSBS, 629 AArch64::AEK_PROFILE})}, 630 {"cortex-x1c", ARMV8_2A, 631 AArch64::ExtensionBitset( 632 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, 633 AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS, 634 AArch64::AEK_PAUTH, AArch64::AEK_PROFILE, AArch64::AEK_FLAGM})}, 635 {"cortex-x2", ARMV9A, 636 AArch64::ExtensionBitset( 637 {AArch64::AEK_MTE, AArch64::AEK_BF16, AArch64::AEK_I8MM, 638 AArch64::AEK_PAUTH, AArch64::AEK_SSBS, AArch64::AEK_SB, 639 AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM, 640 AArch64::AEK_FP16FML, AArch64::AEK_FLAGM})}, 641 {"cortex-x3", ARMV9A, 642 AArch64::ExtensionBitset( 643 {AArch64::AEK_SVE, AArch64::AEK_PERFMON, AArch64::AEK_PROFILE, 644 AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_MTE, 645 AArch64::AEK_SVE2BITPERM, AArch64::AEK_SB, AArch64::AEK_PAUTH, 646 AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_PREDRES, 647 AArch64::AEK_FLAGM, AArch64::AEK_SSBS})}, 648 {"cortex-x4", ARMV9_2A, 649 AArch64::ExtensionBitset({AArch64::AEK_SB, AArch64::AEK_SSBS, 650 AArch64::AEK_MTE, AArch64::AEK_FP16FML, 651 AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, 652 AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, 653 AArch64::AEK_PREDRES, AArch64::AEK_PROFILE})}, 654 {"neoverse-e1", ARMV8_2A, 655 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 656 AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 657 AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, 658 {"neoverse-n1", ARMV8_2A, 659 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 660 AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 661 AArch64::AEK_PROFILE, AArch64::AEK_RCPC, 662 AArch64::AEK_SSBS})}, 663 {"neoverse-n2", ARMV9A, 664 AArch64::ExtensionBitset( 665 {AArch64::AEK_BF16, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 666 AArch64::AEK_FP16FML, AArch64::AEK_I8MM, AArch64::AEK_MTE, 667 AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_SVE, 668 AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM})}, 669 {"neoverse-512tvb", ARMV8_4A, 670 AArch64::ExtensionBitset( 671 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, 672 AArch64::AEK_SM4, AArch64::AEK_SVE, AArch64::AEK_SSBS, 673 AArch64::AEK_FP16, AArch64::AEK_BF16, AArch64::AEK_DOTPROD, 674 AArch64::AEK_PROFILE, AArch64::AEK_RAND, AArch64::AEK_FP16FML, 675 AArch64::AEK_I8MM})}, 676 {"neoverse-v1", ARMV8_4A, 677 AArch64::ExtensionBitset( 678 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, 679 AArch64::AEK_SM4, AArch64::AEK_SVE, AArch64::AEK_SSBS, 680 AArch64::AEK_FP16, AArch64::AEK_BF16, AArch64::AEK_DOTPROD, 681 AArch64::AEK_PROFILE, AArch64::AEK_RAND, AArch64::AEK_FP16FML, 682 AArch64::AEK_I8MM})}, 683 {"neoverse-v2", ARMV9A, 684 AArch64::ExtensionBitset( 685 {AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SSBS, 686 AArch64::AEK_FP16, AArch64::AEK_BF16, AArch64::AEK_RAND, 687 AArch64::AEK_DOTPROD, AArch64::AEK_PROFILE, AArch64::AEK_SVE2BITPERM, 688 AArch64::AEK_FP16FML, AArch64::AEK_I8MM, AArch64::AEK_MTE})}, 689 {"cyclone", ARMV8A, 690 AArch64::ExtensionBitset( 691 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE})}, 692 {"apple-a7", ARMV8A, 693 AArch64::ExtensionBitset( 694 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE})}, 695 {"apple-a8", ARMV8A, 696 AArch64::ExtensionBitset( 697 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE})}, 698 {"apple-a9", ARMV8A, 699 AArch64::ExtensionBitset( 700 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE})}, 701 {"apple-a10", ARMV8A, 702 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 703 AArch64::AEK_CRC, AArch64::AEK_RDM})}, 704 {"apple-a11", ARMV8_2A, 705 AArch64::ExtensionBitset( 706 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, 707 {"apple-a12", ARMV8_3A, 708 AArch64::ExtensionBitset( 709 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, 710 {"apple-a13", ARMV8_4A, 711 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 712 AArch64::AEK_SHA3, AArch64::AEK_FP16, 713 AArch64::AEK_FP16FML})}, 714 {"apple-a14", ARMV8_5A, 715 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 716 AArch64::AEK_SHA3, AArch64::AEK_FP16, 717 AArch64::AEK_FP16FML})}, 718 {"apple-a15", ARMV8_6A, 719 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 720 AArch64::AEK_SHA3, AArch64::AEK_FP16, 721 AArch64::AEK_FP16FML})}, 722 {"apple-a16", ARMV8_6A, 723 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 724 AArch64::AEK_SHA3, AArch64::AEK_FP16, 725 AArch64::AEK_FP16FML})}, 726 {"apple-a17", ARMV8_6A, 727 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 728 AArch64::AEK_SHA3, AArch64::AEK_FP16, 729 AArch64::AEK_FP16FML})}, 730 731 {"apple-m1", ARMV8_5A, 732 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 733 AArch64::AEK_SHA3, AArch64::AEK_FP16, 734 AArch64::AEK_FP16FML})}, 735 {"apple-m2", ARMV8_6A, 736 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 737 AArch64::AEK_SHA3, AArch64::AEK_FP16, 738 AArch64::AEK_FP16FML})}, 739 {"apple-m3", ARMV8_6A, 740 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 741 AArch64::AEK_SHA3, AArch64::AEK_FP16, 742 AArch64::AEK_FP16FML})}, 743 744 {"apple-s4", ARMV8_3A, 745 AArch64::ExtensionBitset( 746 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, 747 {"apple-s5", ARMV8_3A, 748 AArch64::ExtensionBitset( 749 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, 750 {"exynos-m3", ARMV8A, 751 AArch64::ExtensionBitset( 752 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 753 {"exynos-m4", ARMV8_2A, 754 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 755 AArch64::AEK_DOTPROD, AArch64::AEK_FP16})}, 756 {"exynos-m5", ARMV8_2A, 757 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 758 AArch64::AEK_DOTPROD, AArch64::AEK_FP16})}, 759 {"falkor", ARMV8A, 760 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 761 AArch64::AEK_CRC, AArch64::AEK_RDM})}, 762 {"saphira", ARMV8_3A, 763 AArch64::ExtensionBitset( 764 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_PROFILE})}, 765 {"kryo", ARMV8A, 766 AArch64::ExtensionBitset( 767 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 768 {"thunderx2t99", ARMV8_1A, 769 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2})}, 770 {"thunderx3t110", ARMV8_3A, 771 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2})}, 772 {"thunderx", ARMV8A, 773 AArch64::ExtensionBitset( 774 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 775 {"thunderxt88", ARMV8A, 776 AArch64::ExtensionBitset( 777 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 778 {"thunderxt81", ARMV8A, 779 AArch64::ExtensionBitset( 780 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 781 {"thunderxt83", ARMV8A, 782 AArch64::ExtensionBitset( 783 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, 784 {"tsv110", ARMV8_2A, 785 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 786 AArch64::AEK_DOTPROD, AArch64::AEK_FP16, 787 AArch64::AEK_FP16FML, AArch64::AEK_PROFILE, 788 AArch64::AEK_JSCVT, AArch64::AEK_FCMA})}, 789 {"a64fx", ARMV8_2A, 790 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 791 AArch64::AEK_FP16, AArch64::AEK_SVE})}, 792 {"carmel", ARMV8_2A, 793 AArch64::ExtensionBitset( 794 {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, 795 {"ampere1", ARMV8_6A, 796 AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, 797 AArch64::AEK_SHA3, AArch64::AEK_FP16, 798 AArch64::AEK_SB, AArch64::AEK_SSBS, 799 AArch64::AEK_RAND})}, 800 {"ampere1a", ARMV8_6A, 801 AArch64::ExtensionBitset( 802 {AArch64::AEK_FP16, AArch64::AEK_RAND, AArch64::AEK_SM4, 803 AArch64::AEK_SHA3, AArch64::AEK_SHA2, AArch64::AEK_AES, 804 AArch64::AEK_MTE, AArch64::AEK_SB, AArch64::AEK_SSBS})}, 805 {"ampere1b", ARMV8_7A, 806 AArch64::ExtensionBitset({AArch64::AEK_FP16, AArch64::AEK_RAND, 807 AArch64::AEK_SM4, AArch64::AEK_SHA3, 808 AArch64::AEK_SHA2, AArch64::AEK_AES, 809 AArch64::AEK_MTE, AArch64::AEK_SB, 810 AArch64::AEK_SSBS, AArch64::AEK_CSSC})}, 811 }; 812 813 // Name alias. 814 struct Alias { 815 StringRef AltName; 816 StringRef Name; 817 }; 818 819 inline constexpr Alias CpuAliases[] = {{"cobalt-100", "neoverse-n2"}, 820 {"grace", "neoverse-v2"}}; 821 822 inline constexpr Alias ExtAliases[] = {{"rdma", "rdm"}}; 823 824 bool getExtensionFeatures( 825 const AArch64::ExtensionBitset &Extensions, 826 std::vector<StringRef> &Features); 827 828 StringRef getArchExtFeature(StringRef ArchExt); 829 StringRef resolveCPUAlias(StringRef CPU); 830 StringRef resolveExtAlias(StringRef ArchExt); 831 832 // Information by Name 833 const ArchInfo *getArchForCpu(StringRef CPU); 834 835 // Parser 836 const ArchInfo *parseArch(StringRef Arch); 837 std::optional<ExtensionInfo> parseArchExtension(StringRef Extension); 838 // Given the name of a CPU or alias, return the correponding CpuInfo. 839 std::optional<CpuInfo> parseCpu(StringRef Name); 840 // Used by target parser tests 841 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values); 842 843 bool isX18ReservedByDefault(const Triple &TT); 844 845 // For given feature names, return a bitmask corresponding to the entries of 846 // AArch64::CPUFeatures. The values in CPUFeatures are not bitmasks 847 // themselves, they are sequential (0, 1, 2, 3, ...). 848 uint64_t getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs); 849 850 void PrintSupportedExtensions(StringMap<StringRef> DescMap); 851 852 } // namespace AArch64 853 } // namespace llvm 854 855 #endif 856