//===-- AArch64TargetParser - Parser for AArch64 features -------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements a target parser to recognise AArch64 hardware features // such as FPU/CPU/ARCH and extension names. // //===----------------------------------------------------------------------===// #ifndef LLVM_TARGETPARSER_AARCH64TARGETPARSER_H #define LLVM_TARGETPARSER_AARCH64TARGETPARSER_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Bitset.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/VersionTuple.h" #include #include namespace llvm { class Triple; namespace AArch64 { struct ArchInfo; struct CpuInfo; // Function Multi Versioning CPU features. They must be kept in sync with // compiler-rt enum CPUFeatures in lib/builtins/cpu_model/aarch64.c with // FEAT_MAX as sentinel. enum CPUFeatures { FEAT_RNG, FEAT_FLAGM, FEAT_FLAGM2, FEAT_FP16FML, FEAT_DOTPROD, FEAT_SM4, FEAT_RDM, FEAT_LSE, FEAT_FP, FEAT_SIMD, FEAT_CRC, FEAT_SHA1, FEAT_SHA2, FEAT_SHA3, FEAT_AES, FEAT_PMULL, FEAT_FP16, FEAT_DIT, FEAT_DPB, FEAT_DPB2, FEAT_JSCVT, FEAT_FCMA, FEAT_RCPC, FEAT_RCPC2, FEAT_FRINTTS, FEAT_DGH, FEAT_I8MM, FEAT_BF16, FEAT_EBF16, FEAT_RPRES, FEAT_SVE, FEAT_SVE_BF16, FEAT_SVE_EBF16, FEAT_SVE_I8MM, FEAT_SVE_F32MM, FEAT_SVE_F64MM, FEAT_SVE2, FEAT_SVE_AES, FEAT_SVE_PMULL128, FEAT_SVE_BITPERM, FEAT_SVE_SHA3, FEAT_SVE_SM4, FEAT_SME, FEAT_MEMTAG, FEAT_MEMTAG2, FEAT_MEMTAG3, FEAT_SB, FEAT_PREDRES, FEAT_SSBS, FEAT_SSBS2, FEAT_BTI, FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA, FEAT_WFXT, FEAT_SME_F64, FEAT_SME_I64, FEAT_SME2, FEAT_RCPC3, FEAT_MOPS, FEAT_MAX, FEAT_EXT = 62, FEAT_INIT }; static_assert(FEAT_MAX < 62, "Number of features in CPUFeatures are limited to 62 entries"); // Arch extension modifiers for CPUs. These are labelled with their Arm ARM // feature name (though the canonical reference for those is AArch64.td) // clang-format off enum ArchExtKind : unsigned { AEK_NONE = 1, AEK_CRC = 2, // FEAT_CRC32 AEK_CRYPTO = 3, AEK_FP = 4, // FEAT_FP AEK_SIMD = 5, // FEAT_AdvSIMD AEK_FP16 = 6, // FEAT_FP16 AEK_PROFILE = 7, // FEAT_SPE AEK_RAS = 8, // FEAT_RAS, FEAT_RASv1p1 AEK_LSE = 9, // FEAT_LSE AEK_SVE = 10, // FEAT_SVE AEK_DOTPROD = 11, // FEAT_DotProd AEK_RCPC = 12, // FEAT_LRCPC AEK_RDM = 13, // FEAT_RDM AEK_SM4 = 14, // FEAT_SM4, FEAT_SM3 AEK_SHA3 = 15, // FEAT_SHA3, FEAT_SHA512 AEK_SHA2 = 16, // FEAT_SHA1, FEAT_SHA256 AEK_AES = 17, // FEAT_AES, FEAT_PMULL AEK_FP16FML = 18, // FEAT_FHM AEK_RAND = 19, // FEAT_RNG AEK_MTE = 20, // FEAT_MTE, FEAT_MTE2 AEK_SSBS = 21, // FEAT_SSBS, FEAT_SSBS2 AEK_SB = 22, // FEAT_SB AEK_PREDRES = 23, // FEAT_SPECRES AEK_SVE2 = 24, // FEAT_SVE2 AEK_SVE2AES = 25, // FEAT_SVE_AES, FEAT_SVE_PMULL128 AEK_SVE2SM4 = 26, // FEAT_SVE_SM4 AEK_SVE2SHA3 = 27, // FEAT_SVE_SHA3 AEK_SVE2BITPERM = 28, // FEAT_SVE_BitPerm AEK_TME = 29, // FEAT_TME AEK_BF16 = 30, // FEAT_BF16 AEK_I8MM = 31, // FEAT_I8MM AEK_F32MM = 32, // FEAT_F32MM AEK_F64MM = 33, // FEAT_F64MM AEK_LS64 = 34, // FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA AEK_BRBE = 35, // FEAT_BRBE AEK_PAUTH = 36, // FEAT_PAuth AEK_FLAGM = 37, // FEAT_FlagM AEK_SME = 38, // FEAT_SME AEK_SMEF64F64 = 39, // FEAT_SME_F64F64 AEK_SMEI16I64 = 40, // FEAT_SME_I16I64 AEK_HBC = 41, // FEAT_HBC AEK_MOPS = 42, // FEAT_MOPS AEK_PERFMON = 43, // FEAT_PMUv3 AEK_SME2 = 44, // FEAT_SME2 AEK_SVE2p1 = 45, // FEAT_SVE2p1 AEK_SME2p1 = 46, // FEAT_SME2p1 AEK_B16B16 = 47, // FEAT_B16B16 AEK_SMEF16F16 = 48, // FEAT_SMEF16F16 AEK_CSSC = 49, // FEAT_CSSC AEK_RCPC3 = 50, // FEAT_LRCPC3 AEK_THE = 51, // FEAT_THE AEK_D128 = 52, // FEAT_D128 AEK_LSE128 = 53, // FEAT_LSE128 AEK_SPECRES2 = 54, // FEAT_SPECRES2 AEK_RASv2 = 55, // FEAT_RASv2 AEK_ITE = 56, // FEAT_ITE AEK_GCS = 57, // FEAT_GCS AEK_FPMR = 58, // FEAT_FPMR AEK_FP8 = 59, // FEAT_FP8 AEK_FAMINMAX = 60, // FEAT_FAMINMAX AEK_FP8FMA = 61, // FEAT_FP8FMA AEK_SSVE_FP8FMA = 62, // FEAT_SSVE_FP8FMA AEK_FP8DOT2 = 63, // FEAT_FP8DOT2 AEK_SSVE_FP8DOT2 = 64, // FEAT_SSVE_FP8DOT2 AEK_FP8DOT4 = 65, // FEAT_FP8DOT4 AEK_SSVE_FP8DOT4 = 66, // FEAT_SSVE_FP8DOT4 AEK_LUT = 67, // FEAT_LUT AEK_SME_LUTv2 = 68, // FEAT_SME_LUTv2 AEK_SMEF8F16 = 69, // FEAT_SME_F8F16 AEK_SMEF8F32 = 70, // FEAT_SME_F8F32 AEK_SMEFA64 = 71, // FEAT_SME_FA64 AEK_CPA = 72, // FEAT_CPA AEK_PAUTHLR = 73, // FEAT_PAuth_LR AEK_TLBIW = 74, // FEAT_TLBIW AEK_JSCVT = 75, // FEAT_JSCVT AEK_FCMA = 76, // FEAT_FCMA AEK_NUM_EXTENSIONS }; using ExtensionBitset = Bitset; // clang-format on // Represents an extension that can be enabled with -march=+. // Typically these correspond to Arm Architecture extensions, unlike // SubtargetFeature which may represent either an actual extension or some // internal LLVM property. struct ExtensionInfo { StringRef Name; // Human readable name, e.g. "profile". ArchExtKind ID; // Corresponding to the ArchExtKind, this // extensions representation in the bitfield. StringRef Feature; // -mattr enable string, e.g. "+spe" StringRef NegFeature; // -mattr disable string, e.g. "-spe" CPUFeatures CPUFeature; // Function Multi Versioning (FMV) bitfield value // set in __aarch64_cpu_features StringRef DependentFeatures; // FMV enabled features string, // e.g. "+dotprod,+fp-armv8,+neon" unsigned FmvPriority; // FMV feature priority static constexpr unsigned MaxFMVPriority = 1000; // Maximum priority for FMV feature }; // NOTE: If adding a new extension here, consider adding it to ExtensionMap // in AArch64AsmParser too, if supported as an extension name by binutils. // clang-format off inline constexpr ExtensionInfo Extensions[] = { {"aes", AArch64::AEK_AES, "+aes", "-aes", FEAT_AES, "+fp-armv8,+neon", 150}, {"b16b16", AArch64::AEK_B16B16, "+b16b16", "-b16b16", FEAT_INIT, "", 0}, {"bf16", AArch64::AEK_BF16, "+bf16", "-bf16", FEAT_BF16, "+bf16", 280}, {"brbe", AArch64::AEK_BRBE, "+brbe", "-brbe", FEAT_INIT, "", 0}, {"bti", AArch64::AEK_NONE, {}, {}, FEAT_BTI, "+bti", 510}, {"crc", AArch64::AEK_CRC, "+crc", "-crc", FEAT_CRC, "+crc", 110}, {"crypto", AArch64::AEK_CRYPTO, "+crypto", "-crypto", FEAT_INIT, "+aes,+sha2", 0}, {"cssc", AArch64::AEK_CSSC, "+cssc", "-cssc", FEAT_INIT, "", 0}, {"d128", AArch64::AEK_D128, "+d128", "-d128", FEAT_INIT, "", 0}, {"dgh", AArch64::AEK_NONE, {}, {}, FEAT_DGH, "", 260}, {"dit", AArch64::AEK_NONE, {}, {}, FEAT_DIT, "+dit", 180}, {"dotprod", AArch64::AEK_DOTPROD, "+dotprod", "-dotprod", FEAT_DOTPROD, "+dotprod,+fp-armv8,+neon", 104}, {"dpb", AArch64::AEK_NONE, {}, {}, FEAT_DPB, "+ccpp", 190}, {"dpb2", AArch64::AEK_NONE, {}, {}, FEAT_DPB2, "+ccpp,+ccdp", 200}, {"ebf16", AArch64::AEK_NONE, {}, {}, FEAT_EBF16, "+bf16", 290}, {"f32mm", AArch64::AEK_F32MM, "+f32mm", "-f32mm", FEAT_SVE_F32MM, "+sve,+f32mm,+fullfp16,+fp-armv8,+neon", 350}, {"f64mm", AArch64::AEK_F64MM, "+f64mm", "-f64mm", FEAT_SVE_F64MM, "+sve,+f64mm,+fullfp16,+fp-armv8,+neon", 360}, {"fcma", AArch64::AEK_FCMA, "+complxnum", "-complxnum", FEAT_FCMA, "+fp-armv8,+neon,+complxnum", 220}, {"flagm", AArch64::AEK_FLAGM, "+flagm", "-flagm", FEAT_FLAGM, "+flagm", 20}, {"flagm2", AArch64::AEK_NONE, {}, {}, FEAT_FLAGM2, "+flagm,+altnzcv", 30}, {"fp", AArch64::AEK_FP, "+fp-armv8", "-fp-armv8", FEAT_FP, "+fp-armv8,+neon", 90}, {"fp16", AArch64::AEK_FP16, "+fullfp16", "-fullfp16", FEAT_FP16, "+fullfp16,+fp-armv8,+neon", 170}, {"fp16fml", AArch64::AEK_FP16FML, "+fp16fml", "-fp16fml", FEAT_FP16FML, "+fp16fml,+fullfp16,+fp-armv8,+neon", 175}, {"frintts", AArch64::AEK_NONE, {}, {}, FEAT_FRINTTS, "+fptoint", 250}, {"hbc", AArch64::AEK_HBC, "+hbc", "-hbc", FEAT_INIT, "", 0}, {"i8mm", AArch64::AEK_I8MM, "+i8mm", "-i8mm", FEAT_I8MM, "+i8mm", 270}, {"ite", AArch64::AEK_ITE, "+ite", "-ite", FEAT_INIT, "", 0}, {"jscvt", AArch64::AEK_JSCVT, "+jsconv", "-jsconv", FEAT_JSCVT, "+fp-armv8,+neon,+jsconv", 210}, {"ls64_accdata", AArch64::AEK_NONE, {}, {}, FEAT_LS64_ACCDATA, "+ls64", 540}, {"ls64_v", AArch64::AEK_NONE, {}, {}, FEAT_LS64_V, "", 530}, {"ls64", AArch64::AEK_LS64, "+ls64", "-ls64", FEAT_LS64, "", 520}, {"lse", AArch64::AEK_LSE, "+lse", "-lse", FEAT_LSE, "+lse", 80}, {"lse128", AArch64::AEK_LSE128, "+lse128", "-lse128", FEAT_INIT, "", 0}, {"memtag", AArch64::AEK_MTE, "+mte", "-mte", FEAT_MEMTAG, "", 440}, {"memtag2", AArch64::AEK_NONE, {}, {}, FEAT_MEMTAG2, "+mte", 450}, {"memtag3", AArch64::AEK_NONE, {}, {}, FEAT_MEMTAG3, "+mte", 460}, {"mops", AArch64::AEK_MOPS, "+mops", "-mops", FEAT_MOPS, "+mops", 650}, {"pauth", AArch64::AEK_PAUTH, "+pauth", "-pauth", FEAT_INIT, "", 0}, {"pmull", AArch64::AEK_NONE, {}, {}, FEAT_PMULL, "+aes,+fp-armv8,+neon", 160}, {"pmuv3", AArch64::AEK_PERFMON, "+perfmon", "-perfmon", FEAT_INIT, "", 0}, {"predres", AArch64::AEK_PREDRES, "+predres", "-predres", FEAT_PREDRES, "+predres", 480}, {"predres2", AArch64::AEK_SPECRES2, "+specres2", "-specres2", FEAT_INIT, "", 0}, {"profile", AArch64::AEK_PROFILE, "+spe", "-spe", FEAT_INIT, "", 0}, {"ras", AArch64::AEK_RAS, "+ras", "-ras", FEAT_INIT, "", 0}, {"rasv2", AArch64::AEK_RASv2, "+rasv2", "-rasv2", FEAT_INIT, "", 0}, {"rcpc", AArch64::AEK_RCPC, "+rcpc", "-rcpc", FEAT_RCPC, "+rcpc", 230}, {"rcpc2", AArch64::AEK_NONE, {}, {}, FEAT_RCPC2, "+rcpc", 240}, {"rcpc3", AArch64::AEK_RCPC3, "+rcpc3", "-rcpc3", FEAT_RCPC3, "+rcpc,+rcpc3", 241}, {"rdm", AArch64::AEK_RDM, "+rdm", "-rdm", FEAT_RDM, "+rdm,+fp-armv8,+neon", 108}, {"rng", AArch64::AEK_RAND, "+rand", "-rand", FEAT_RNG, "+rand", 10}, {"rpres", AArch64::AEK_NONE, {}, {}, FEAT_RPRES, "", 300}, {"sb", AArch64::AEK_SB, "+sb", "-sb", FEAT_SB, "+sb", 470}, {"sha1", AArch64::AEK_NONE, {}, {}, FEAT_SHA1, "+fp-armv8,+neon", 120}, {"sha2", AArch64::AEK_SHA2, "+sha2", "-sha2", FEAT_SHA2, "+sha2,+fp-armv8,+neon", 130}, {"sha3", AArch64::AEK_SHA3, "+sha3", "-sha3", FEAT_SHA3, "+sha3,+sha2,+fp-armv8,+neon", 140}, {"simd", AArch64::AEK_SIMD, "+neon", "-neon", FEAT_SIMD, "+fp-armv8,+neon", 100}, {"sm4", AArch64::AEK_SM4, "+sm4", "-sm4", FEAT_SM4, "+sm4,+fp-armv8,+neon", 106}, {"sme-f16f16", AArch64::AEK_SMEF16F16, "+sme-f16f16", "-sme-f16f16", FEAT_INIT, "", 0}, {"sme-f64f64", AArch64::AEK_SMEF64F64, "+sme-f64f64", "-sme-f64f64", FEAT_SME_F64, "+sme,+sme-f64f64,+bf16", 560}, {"sme-i16i64", AArch64::AEK_SMEI16I64, "+sme-i16i64", "-sme-i16i64", FEAT_SME_I64, "+sme,+sme-i16i64,+bf16", 570}, {"sme", AArch64::AEK_SME, "+sme", "-sme", FEAT_SME, "+sme,+bf16", 430}, {"sme2", AArch64::AEK_SME2, "+sme2", "-sme2", FEAT_SME2, "+sme2,+sme,+bf16", 580}, {"sme2p1", AArch64::AEK_SME2p1, "+sme2p1", "-sme2p1", FEAT_INIT, "+sme2p1,+sme2,+sme,+bf16", 0}, {"ssbs", AArch64::AEK_SSBS, "+ssbs", "-ssbs", FEAT_SSBS, "", 490}, {"ssbs2", AArch64::AEK_NONE, {}, {}, FEAT_SSBS2, "+ssbs", 500}, {"sve-bf16", AArch64::AEK_NONE, {}, {}, FEAT_SVE_BF16, "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 320}, {"sve-ebf16", AArch64::AEK_NONE, {}, {}, FEAT_SVE_EBF16, "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 330}, {"sve-i8mm", AArch64::AEK_NONE, {}, {}, FEAT_SVE_I8MM, "+sve,+i8mm,+fullfp16,+fp-armv8,+neon", 340}, {"sve", AArch64::AEK_SVE, "+sve", "-sve", FEAT_SVE, "+sve,+fullfp16,+fp-armv8,+neon", 310}, {"sve2-aes", AArch64::AEK_SVE2AES, "+sve2-aes", "-sve2-aes", FEAT_SVE_AES, "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 380}, {"sve2-bitperm", AArch64::AEK_SVE2BITPERM, "+sve2-bitperm", "-sve2-bitperm", FEAT_SVE_BITPERM, "+sve2,+sve,+sve2-bitperm,+fullfp16,+fp-armv8,+neon", 400}, {"sve2-pmull128", AArch64::AEK_NONE, {}, {}, FEAT_SVE_PMULL128, "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 390}, {"sve2-sha3", AArch64::AEK_SVE2SHA3, "+sve2-sha3", "-sve2-sha3", FEAT_SVE_SHA3, "+sve2,+sve,+sve2-sha3,+fullfp16,+fp-armv8,+neon", 410}, {"sve2-sm4", AArch64::AEK_SVE2SM4, "+sve2-sm4", "-sve2-sm4", FEAT_SVE_SM4, "+sve2,+sve,+sve2-sm4,+fullfp16,+fp-armv8,+neon", 420}, {"sve2", AArch64::AEK_SVE2, "+sve2", "-sve2", FEAT_SVE2, "+sve2,+sve,+fullfp16,+fp-armv8,+neon", 370}, {"sve2p1", AArch64::AEK_SVE2p1, "+sve2p1", "-sve2p1", FEAT_INIT, "+sve2p1,+sve2,+sve,+fullfp16,+fp-armv8,+neon", 0}, {"the", AArch64::AEK_THE, "+the", "-the", FEAT_INIT, "", 0}, {"tme", AArch64::AEK_TME, "+tme", "-tme", FEAT_INIT, "", 0}, {"wfxt", AArch64::AEK_NONE, {}, {}, FEAT_WFXT, "+wfxt", 550}, {"gcs", AArch64::AEK_GCS, "+gcs", "-gcs", FEAT_INIT, "", 0}, {"fpmr", AArch64::AEK_FPMR, "+fpmr", "-fpmr", FEAT_INIT, "", 0}, {"fp8", AArch64::AEK_FP8, "+fp8", "-fp8", FEAT_INIT, "+fpmr", 0}, {"faminmax", AArch64::AEK_FAMINMAX, "+faminmax", "-faminmax", FEAT_INIT, "", 0}, {"fp8fma", AArch64::AEK_FP8FMA, "+fp8fma", "-fp8fma", FEAT_INIT, "+fpmr", 0}, {"ssve-fp8fma", AArch64::AEK_SSVE_FP8FMA, "+ssve-fp8fma", "-ssve-fp8fma", FEAT_INIT, "+sme2", 0}, {"fp8dot2", AArch64::AEK_FP8DOT2, "+fp8dot2", "-fp8dot2", FEAT_INIT, "", 0}, {"ssve-fp8dot2", AArch64::AEK_SSVE_FP8DOT2, "+ssve-fp8dot2", "-ssve-fp8dot2", FEAT_INIT, "+sme2", 0}, {"fp8dot4", AArch64::AEK_FP8DOT4, "+fp8dot4", "-fp8dot4", FEAT_INIT, "", 0}, {"ssve-fp8dot4", AArch64::AEK_SSVE_FP8DOT4, "+ssve-fp8dot4", "-ssve-fp8dot4", FEAT_INIT, "+sme2", 0}, {"lut", AArch64::AEK_LUT, "+lut", "-lut", FEAT_INIT, "", 0}, {"sme-lutv2", AArch64::AEK_SME_LUTv2, "+sme-lutv2", "-sme-lutv2", FEAT_INIT, "", 0}, {"sme-f8f16", AArch64::AEK_SMEF8F16, "+sme-f8f16", "-sme-f8f16", FEAT_INIT, "+sme2,+fp8", 0}, {"sme-f8f32", AArch64::AEK_SMEF8F32, "+sme-f8f32", "-sme-f8f32", FEAT_INIT, "+sme2,+fp8", 0}, {"sme-fa64", AArch64::AEK_SMEFA64, "+sme-fa64", "-sme-fa64", FEAT_INIT, "", 0}, {"cpa", AArch64::AEK_CPA, "+cpa", "-cpa", FEAT_INIT, "", 0}, {"pauth-lr", AArch64::AEK_PAUTHLR, "+pauth-lr", "-pauth-lr", FEAT_INIT, "", 0}, {"tlbiw", AArch64::AEK_TLBIW, "+tlbiw", "-tlbiw", FEAT_INIT, "", 0}, // Special cases {"none", AArch64::AEK_NONE, {}, {}, FEAT_INIT, "", ExtensionInfo::MaxFMVPriority}, }; // clang-format on struct ExtensionSet { // Set of extensions which are currently enabled. ExtensionBitset Enabled; // Set of extensions which have been enabled or disabled at any point. Used // to avoid cluttering the cc1 command-line with lots of unneeded features. ExtensionBitset Touched; // Base architecture version, which we need to know because some feature // dependencies change depending on this. const ArchInfo *BaseArch; ExtensionSet() : Enabled(), Touched(), BaseArch(nullptr) {} // Enable the given architecture extension, and any other extensions it // depends on. Does not change the base architecture, or follow dependencies // between features which are only related by required arcitecture versions. void enable(ArchExtKind E); // Disable the given architecture extension, and any other extensions which // depend on it. Does not change the base architecture, or follow // dependencies between features which are only related by required // arcitecture versions. void disable(ArchExtKind E); // Add default extensions for the given CPU. Records the base architecture, // to later resolve dependencies which depend on it. void addCPUDefaults(const CpuInfo &CPU); // Add default extensions for the given architecture version. Records the // base architecture, to later resolve dependencies which depend on it. void addArchDefaults(const ArchInfo &Arch); // Add or remove a feature based on a modifier string. The string must be of // the form "" to enable a feature or "no" to disable it. This // will also enable or disable any features as required by the dependencies // between them. bool parseModifier(StringRef Modifier); // Convert the set of enabled extension to an LLVM feature list, appending // them to Features. void toLLVMFeatureList(std::vector &Features) const; }; // Represents a dependency between two architecture extensions. Later is the // feature which was added to the architecture after Earlier, and expands the // functionality provided by it. If Later is enabled, then Earlier will also be // enabled. If Earlier is disabled, then Later will also be disabled. struct ExtensionDependency { ArchExtKind Earlier; ArchExtKind Later; }; // clang-format off // Each entry here is a link in the dependency chain starting from the // extension that was added to the architecture first. inline constexpr ExtensionDependency ExtensionDependencies[] = { {AEK_FP, AEK_FP16}, {AEK_FP, AEK_SIMD}, {AEK_FP, AEK_JSCVT}, {AEK_FP, AEK_FP8}, {AEK_SIMD, AEK_CRYPTO}, {AEK_SIMD, AEK_AES}, {AEK_SIMD, AEK_SHA2}, {AEK_SIMD, AEK_SHA3}, {AEK_SIMD, AEK_SM4}, {AEK_SIMD, AEK_RDM}, {AEK_SIMD, AEK_DOTPROD}, {AEK_SIMD, AEK_FCMA}, {AEK_FP16, AEK_FP16FML}, {AEK_FP16, AEK_SVE}, {AEK_BF16, AEK_SME}, {AEK_BF16, AEK_B16B16}, {AEK_SVE, AEK_SVE2}, {AEK_SVE, AEK_F32MM}, {AEK_SVE, AEK_F64MM}, {AEK_SVE2, AEK_SVE2p1}, {AEK_SVE2, AEK_SVE2BITPERM}, {AEK_SVE2, AEK_SVE2AES}, {AEK_SVE2, AEK_SVE2SHA3}, {AEK_SVE2, AEK_SVE2SM4}, {AEK_SVE2, AEK_SMEFA64}, {AEK_SVE2, AEK_SMEFA64}, {AEK_SME, AEK_SME2}, {AEK_SME, AEK_SMEF16F16}, {AEK_SME, AEK_SMEF64F64}, {AEK_SME, AEK_SMEI16I64}, {AEK_SME, AEK_SMEFA64}, {AEK_SME2, AEK_SME2p1}, {AEK_SME2, AEK_SSVE_FP8FMA}, {AEK_SME2, AEK_SSVE_FP8DOT2}, {AEK_SME2, AEK_SSVE_FP8DOT4}, {AEK_SME2, AEK_SMEF8F16}, {AEK_SME2, AEK_SMEF8F32}, {AEK_FP8, AEK_SMEF8F16}, {AEK_FP8, AEK_SMEF8F32}, {AEK_LSE, AEK_LSE128}, {AEK_PREDRES, AEK_SPECRES2}, {AEK_RAS, AEK_RASv2}, {AEK_RCPC, AEK_RCPC3}, }; // clang-format on enum ArchProfile { AProfile = 'A', RProfile = 'R', InvalidProfile = '?' }; // Information about a specific architecture, e.g. V8.1-A struct ArchInfo { VersionTuple Version; // Architecture version, major + minor. ArchProfile Profile; // Architecuture profile StringRef Name; // Human readable name, e.g. "armv8.1-a" StringRef ArchFeature; // Command line feature flag, e.g. +v8a AArch64::ExtensionBitset DefaultExts; // bitfield of default extensions ArchExtKind bool operator==(const ArchInfo &Other) const { return this->Name == Other.Name; } bool operator!=(const ArchInfo &Other) const { return this->Name != Other.Name; } // Defines the following partial order, indicating when an architecture is // a superset of another: // // v9.5a > v9.4a > v9.3a > v9.2a > v9.1a > v9a; // v v v v v // v8.9a > v8.8a > v8.7a > v8.6a > v8.5a > v8.4a > ... > v8a; // // v8r has no relation to anything. This is used to determine which // features to enable for a given architecture. See // AArch64TargetInfo::setFeatureEnabled. bool implies(const ArchInfo &Other) const { if (this->Profile != Other.Profile) return false; // ARMV8R if (this->Version.getMajor() == Other.Version.getMajor()) { return this->Version > Other.Version; } if (this->Version.getMajor() == 9 && Other.Version.getMajor() == 8) { assert(this->Version.getMinor() && Other.Version.getMinor() && "AArch64::ArchInfo should have a minor version."); return this->Version.getMinor().value_or(0) + 5 >= Other.Version.getMinor().value_or(0); } return false; } // True if this architecture is a superset of Other (including being equal to // it). bool is_superset(const ArchInfo &Other) const { return (*this == Other) || implies(Other); } // Return ArchFeature without the leading "+". StringRef getSubArch() const { return ArchFeature.substr(1); } // Search for ArchInfo by SubArch name static std::optional findBySubArch(StringRef SubArch); }; // clang-format off inline constexpr ArchInfo ARMV8A = { VersionTuple{8, 0}, AProfile, "armv8-a", "+v8a", ( AArch64::ExtensionBitset({AArch64::AEK_FP, AArch64::AEK_SIMD})), }; inline constexpr ArchInfo ARMV8_1A = { VersionTuple{8, 1}, AProfile, "armv8.1-a", "+v8.1a", (ARMV8A.DefaultExts | AArch64::ExtensionBitset({AArch64::AEK_CRC, AArch64::AEK_LSE, AArch64::AEK_RDM}))}; inline constexpr ArchInfo ARMV8_2A = { VersionTuple{8, 2}, AProfile, "armv8.2-a", "+v8.2a", (ARMV8_1A.DefaultExts | AArch64::ExtensionBitset({AArch64::AEK_RAS}))}; inline constexpr ArchInfo ARMV8_3A = { VersionTuple{8, 3}, AProfile, "armv8.3-a", "+v8.3a", (ARMV8_2A.DefaultExts | AArch64::ExtensionBitset({AArch64::AEK_FCMA, AArch64::AEK_JSCVT, AArch64::AEK_PAUTH, AArch64::AEK_RCPC}))}; inline constexpr ArchInfo ARMV8_4A = { VersionTuple{8, 4}, AProfile, "armv8.4-a", "+v8.4a", (ARMV8_3A.DefaultExts | AArch64::ExtensionBitset({AArch64::AEK_DOTPROD}))}; inline constexpr ArchInfo ARMV8_5A = { VersionTuple{8, 5}, AProfile, "armv8.5-a", "+v8.5a", (ARMV8_4A.DefaultExts)}; inline constexpr ArchInfo ARMV8_6A = { VersionTuple{8, 6}, AProfile, "armv8.6-a", "+v8.6a", (ARMV8_5A.DefaultExts | AArch64::ExtensionBitset({AArch64::AEK_BF16, AArch64::AEK_I8MM}))}; inline constexpr ArchInfo ARMV8_7A = { VersionTuple{8, 7}, AProfile, "armv8.7-a", "+v8.7a", (ARMV8_6A.DefaultExts)}; inline constexpr ArchInfo ARMV8_8A = { VersionTuple{8, 8}, AProfile, "armv8.8-a", "+v8.8a", (ARMV8_7A.DefaultExts | AArch64::ExtensionBitset({AArch64::AEK_MOPS, AArch64::AEK_HBC}))}; inline constexpr ArchInfo ARMV8_9A = { VersionTuple{8, 9}, AProfile, "armv8.9-a", "+v8.9a", (ARMV8_8A.DefaultExts | AArch64::ExtensionBitset({AArch64::AEK_SPECRES2, AArch64::AEK_CSSC, AArch64::AEK_RASv2}))}; inline constexpr ArchInfo ARMV9A = { VersionTuple{9, 0}, AProfile, "armv9-a", "+v9a", (ARMV8_5A.DefaultExts | AArch64::ExtensionBitset({AArch64::AEK_FP16, AArch64::AEK_SVE, AArch64::AEK_SVE2}))}; inline constexpr ArchInfo ARMV9_1A = { VersionTuple{9, 1}, AProfile, "armv9.1-a", "+v9.1a", (ARMV9A.DefaultExts | AArch64::ExtensionBitset({AArch64::AEK_BF16, AArch64::AEK_I8MM}))}; inline constexpr ArchInfo ARMV9_2A = { VersionTuple{9, 2}, AProfile, "armv9.2-a", "+v9.2a", (ARMV9_1A.DefaultExts)}; inline constexpr ArchInfo ARMV9_3A = { VersionTuple{9, 3}, AProfile, "armv9.3-a", "+v9.3a", (ARMV9_2A.DefaultExts | AArch64::ExtensionBitset({AArch64::AEK_MOPS, AArch64::AEK_HBC}))}; inline constexpr ArchInfo ARMV9_4A = { VersionTuple{9, 4}, AProfile, "armv9.4-a", "+v9.4a", (ARMV9_3A.DefaultExts | AArch64::ExtensionBitset({AArch64::AEK_SPECRES2, AArch64::AEK_CSSC, AArch64::AEK_RASv2}))}; inline constexpr ArchInfo ARMV9_5A = { VersionTuple{9, 5}, AProfile, "armv9.5-a", "+v9.5a", (ARMV9_4A.DefaultExts | AArch64::ExtensionBitset({AArch64::AEK_CPA}))}; // For v8-R, we do not enable crypto and align with GCC that enables a more minimal set of optional architecture extensions. inline constexpr ArchInfo ARMV8R = { VersionTuple{8, 0}, RProfile, "armv8-r", "+v8r", (ARMV8_5A.DefaultExts | AArch64::ExtensionBitset({AArch64::AEK_SSBS, AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_SB}).flip(AArch64::AEK_LSE))}; // clang-format on // The set of all architectures static constexpr std::array ArchInfos = { &ARMV8A, &ARMV8_1A, &ARMV8_2A, &ARMV8_3A, &ARMV8_4A, &ARMV8_5A, &ARMV8_6A, &ARMV8_7A, &ARMV8_8A, &ARMV8_9A, &ARMV9A, &ARMV9_1A, &ARMV9_2A, &ARMV9_3A, &ARMV9_4A, &ARMV9_5A, &ARMV8R, }; // Details of a specific CPU. struct CpuInfo { StringRef Name; // Name, as written for -mcpu. const ArchInfo &Arch; AArch64::ExtensionBitset DefaultExtensions; // Default extensions for this CPU. These will be // ORd with the architecture defaults. AArch64::ExtensionBitset getImpliedExtensions() const { AArch64::ExtensionBitset ImpliedExts; ImpliedExts |= DefaultExtensions; ImpliedExts |= Arch.DefaultExts; return ImpliedExts; } }; inline constexpr CpuInfo CpuInfos[] = { {"cortex-a34", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, {"cortex-a35", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, {"cortex-a53", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, {"cortex-a55", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC})}, {"cortex-a510", ARMV9A, AArch64::ExtensionBitset( {AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_SB, AArch64::AEK_PAUTH, AArch64::AEK_MTE, AArch64::AEK_SSBS, AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM, AArch64::AEK_FP16FML})}, {"cortex-a520", ARMV9_2A, AArch64::ExtensionBitset( {AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_MTE, AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, AArch64::AEK_PREDRES})}, {"cortex-a57", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, {"cortex-a65", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, {"cortex-a65ae", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, {"cortex-a72", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, {"cortex-a73", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, {"cortex-a75", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC})}, {"cortex-a76", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, {"cortex-a76ae", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, {"cortex-a77", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, AArch64::AEK_RCPC, AArch64::AEK_DOTPROD, AArch64::AEK_SSBS})}, {"cortex-a78", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS, AArch64::AEK_PROFILE})}, {"cortex-a78ae", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS, AArch64::AEK_PROFILE})}, {"cortex-a78c", ARMV8_2A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS, AArch64::AEK_PROFILE, AArch64::AEK_FLAGM, AArch64::AEK_PAUTH})}, {"cortex-a710", ARMV9A, AArch64::ExtensionBitset({AArch64::AEK_MTE, AArch64::AEK_PAUTH, AArch64::AEK_FLAGM, AArch64::AEK_SB, AArch64::AEK_I8MM, AArch64::AEK_FP16FML, AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM, AArch64::AEK_BF16})}, {"cortex-a715", ARMV9A, AArch64::ExtensionBitset( {AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_MTE, AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, AArch64::AEK_I8MM, AArch64::AEK_PREDRES, AArch64::AEK_PERFMON, AArch64::AEK_PROFILE, AArch64::AEK_SVE, AArch64::AEK_SVE2BITPERM, AArch64::AEK_BF16, AArch64::AEK_FLAGM})}, {"cortex-a720", ARMV9_2A, AArch64::ExtensionBitset({AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_MTE, AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, AArch64::AEK_PREDRES, AArch64::AEK_PROFILE})}, {"cortex-r82", ARMV8R, AArch64::ExtensionBitset({AArch64::AEK_LSE})}, {"cortex-x1", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS, AArch64::AEK_PROFILE})}, {"cortex-x1c", ARMV8_2A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, AArch64::AEK_DOTPROD, AArch64::AEK_RCPC, AArch64::AEK_SSBS, AArch64::AEK_PAUTH, AArch64::AEK_PROFILE, AArch64::AEK_FLAGM})}, {"cortex-x2", ARMV9A, AArch64::ExtensionBitset( {AArch64::AEK_MTE, AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_PAUTH, AArch64::AEK_SSBS, AArch64::AEK_SB, AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM, AArch64::AEK_FP16FML, AArch64::AEK_FLAGM})}, {"cortex-x3", ARMV9A, AArch64::ExtensionBitset( {AArch64::AEK_SVE, AArch64::AEK_PERFMON, AArch64::AEK_PROFILE, AArch64::AEK_BF16, AArch64::AEK_I8MM, AArch64::AEK_MTE, AArch64::AEK_SVE2BITPERM, AArch64::AEK_SB, AArch64::AEK_PAUTH, AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_PREDRES, AArch64::AEK_FLAGM, AArch64::AEK_SSBS})}, {"cortex-x4", ARMV9_2A, AArch64::ExtensionBitset({AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_MTE, AArch64::AEK_FP16FML, AArch64::AEK_PAUTH, AArch64::AEK_SVE2BITPERM, AArch64::AEK_FLAGM, AArch64::AEK_PERFMON, AArch64::AEK_PREDRES, AArch64::AEK_PROFILE})}, {"neoverse-e1", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, {"neoverse-n1", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, AArch64::AEK_PROFILE, AArch64::AEK_RCPC, AArch64::AEK_SSBS})}, {"neoverse-n2", ARMV9A, AArch64::ExtensionBitset( {AArch64::AEK_BF16, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_I8MM, AArch64::AEK_MTE, AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SVE2BITPERM})}, {"neoverse-512tvb", ARMV8_4A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, AArch64::AEK_SM4, AArch64::AEK_SVE, AArch64::AEK_SSBS, AArch64::AEK_FP16, AArch64::AEK_BF16, AArch64::AEK_DOTPROD, AArch64::AEK_PROFILE, AArch64::AEK_RAND, AArch64::AEK_FP16FML, AArch64::AEK_I8MM})}, {"neoverse-v1", ARMV8_4A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, AArch64::AEK_SM4, AArch64::AEK_SVE, AArch64::AEK_SSBS, AArch64::AEK_FP16, AArch64::AEK_BF16, AArch64::AEK_DOTPROD, AArch64::AEK_PROFILE, AArch64::AEK_RAND, AArch64::AEK_FP16FML, AArch64::AEK_I8MM})}, {"neoverse-v2", ARMV9A, AArch64::ExtensionBitset( {AArch64::AEK_SVE, AArch64::AEK_SVE2, AArch64::AEK_SSBS, AArch64::AEK_FP16, AArch64::AEK_BF16, AArch64::AEK_RAND, AArch64::AEK_DOTPROD, AArch64::AEK_PROFILE, AArch64::AEK_SVE2BITPERM, AArch64::AEK_FP16FML, AArch64::AEK_I8MM, AArch64::AEK_MTE})}, {"cyclone", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE})}, {"apple-a7", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE})}, {"apple-a8", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE})}, {"apple-a9", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_NONE})}, {"apple-a10", ARMV8A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC, AArch64::AEK_RDM})}, {"apple-a11", ARMV8_2A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, {"apple-a12", ARMV8_3A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, {"apple-a13", ARMV8_4A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, AArch64::AEK_FP16, AArch64::AEK_FP16FML})}, {"apple-a14", ARMV8_5A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, AArch64::AEK_FP16, AArch64::AEK_FP16FML})}, {"apple-a15", ARMV8_6A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, AArch64::AEK_FP16, AArch64::AEK_FP16FML})}, {"apple-a16", ARMV8_6A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, AArch64::AEK_FP16, AArch64::AEK_FP16FML})}, {"apple-a17", ARMV8_6A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, AArch64::AEK_FP16, AArch64::AEK_FP16FML})}, {"apple-m1", ARMV8_5A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, AArch64::AEK_FP16, AArch64::AEK_FP16FML})}, {"apple-m2", ARMV8_6A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, AArch64::AEK_FP16, AArch64::AEK_FP16FML})}, {"apple-m3", ARMV8_6A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, AArch64::AEK_FP16, AArch64::AEK_FP16FML})}, {"apple-s4", ARMV8_3A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, {"apple-s5", ARMV8_3A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, {"exynos-m3", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, {"exynos-m4", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD, AArch64::AEK_FP16})}, {"exynos-m5", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD, AArch64::AEK_FP16})}, {"falkor", ARMV8A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC, AArch64::AEK_RDM})}, {"saphira", ARMV8_3A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_PROFILE})}, {"kryo", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, {"thunderx2t99", ARMV8_1A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2})}, {"thunderx3t110", ARMV8_3A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2})}, {"thunderx", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, {"thunderxt88", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, {"thunderxt81", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, {"thunderxt83", ARMV8A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_CRC})}, {"tsv110", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_DOTPROD, AArch64::AEK_FP16, AArch64::AEK_FP16FML, AArch64::AEK_PROFILE, AArch64::AEK_JSCVT, AArch64::AEK_FCMA})}, {"a64fx", ARMV8_2A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16, AArch64::AEK_SVE})}, {"carmel", ARMV8_2A, AArch64::ExtensionBitset( {AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_FP16})}, {"ampere1", ARMV8_6A, AArch64::ExtensionBitset({AArch64::AEK_AES, AArch64::AEK_SHA2, AArch64::AEK_SHA3, AArch64::AEK_FP16, AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_RAND})}, {"ampere1a", ARMV8_6A, AArch64::ExtensionBitset( {AArch64::AEK_FP16, AArch64::AEK_RAND, AArch64::AEK_SM4, AArch64::AEK_SHA3, AArch64::AEK_SHA2, AArch64::AEK_AES, AArch64::AEK_MTE, AArch64::AEK_SB, AArch64::AEK_SSBS})}, {"ampere1b", ARMV8_7A, AArch64::ExtensionBitset({AArch64::AEK_FP16, AArch64::AEK_RAND, AArch64::AEK_SM4, AArch64::AEK_SHA3, AArch64::AEK_SHA2, AArch64::AEK_AES, AArch64::AEK_MTE, AArch64::AEK_SB, AArch64::AEK_SSBS, AArch64::AEK_CSSC})}, }; // Name alias. struct Alias { StringRef AltName; StringRef Name; }; inline constexpr Alias CpuAliases[] = {{"cobalt-100", "neoverse-n2"}, {"grace", "neoverse-v2"}}; inline constexpr Alias ExtAliases[] = {{"rdma", "rdm"}}; bool getExtensionFeatures( const AArch64::ExtensionBitset &Extensions, std::vector &Features); StringRef getArchExtFeature(StringRef ArchExt); StringRef resolveCPUAlias(StringRef CPU); StringRef resolveExtAlias(StringRef ArchExt); // Information by Name const ArchInfo *getArchForCpu(StringRef CPU); // Parser const ArchInfo *parseArch(StringRef Arch); std::optional parseArchExtension(StringRef Extension); // Given the name of a CPU or alias, return the correponding CpuInfo. std::optional parseCpu(StringRef Name); // Used by target parser tests void fillValidCPUArchList(SmallVectorImpl &Values); bool isX18ReservedByDefault(const Triple &TT); // For given feature names, return a bitmask corresponding to the entries of // AArch64::CPUFeatures. The values in CPUFeatures are not bitmasks // themselves, they are sequential (0, 1, 2, 3, ...). uint64_t getCpuSupportsMask(ArrayRef FeatureStrs); void PrintSupportedExtensions(StringMap DescMap); } // namespace AArch64 } // namespace llvm #endif