From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1130) id 8392C3858C53; Thu, 29 Sep 2022 10:34:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8392C3858C53 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1664447678; bh=dLtOiQp+tqLI8+7BWAIj2Sur82myF0f4cksCnxGnsGk=; h=From:To:Subject:Date:From; b=Bzr3Kqmqu0gZwK/cen2FpwlfXTYajvJihaNBUCgcoH1yTq2yMNMg6N2nvh2HbNaVD VU+SnJZ6LknUzSoNb6zZGjbgHO0PMRPGRAOKN5GBFMM+fYnctldUnzUkMhjVLuQJKP zXc3CGSaz6H+geRVAuW7Ix8jqUqcBJYm2KB131wg= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Richard Sandiford To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-2943] aarch64: Simplify feature definitions X-Act-Checkin: gcc X-Git-Author: Richard Sandiford X-Git-Refname: refs/heads/trunk X-Git-Oldrev: c067c474f85b1e9c56fb34dd51ef0eec9221b766 X-Git-Newrev: 11a113d501ff64fa4843e28d0a21b3f4e9d0d3de Message-Id: <20220929103438.8392C3858C53@sourceware.org> Date: Thu, 29 Sep 2022 10:34:38 +0000 (GMT) List-Id: https://gcc.gnu.org/g:11a113d501ff64fa4843e28d0a21b3f4e9d0d3de commit r13-2943-g11a113d501ff64fa4843e28d0a21b3f4e9d0d3de Author: Richard Sandiford Date: Thu Sep 29 11:32:54 2022 +0100 aarch64: Simplify feature definitions Currently the aarch64-option-extensions.def entries, the aarch64-cores.def entries, and the AARCH64_FL_FOR_* macros have a transitive closure of dependencies that is maintained by hand. This is a bit error-prone and is becoming less tenable as more features are added. The main point of this patch is to maintain the closure automatically instead. For example, the +sve2-aes extension requires sve2 and aes. This is now described using: AARCH64_OPT_EXTENSION("sve2-aes", SVE2_AES, (SVE2, AES), ...) If life was simple, we could just give the name of the feature and the list of features that it requires/depends on. But sadly things are more complicated. For example: - the legacy +crypto option enables aes and sha2 only, but +nocrypto disables all crypto-related extensions, including sm4. - +fp16fml enables fp16, but armv8.4-a enables fp16fml without fp16. fp16fml only has an effect when fp16 is also present; see the comments for more details. - +bf16 enables simd, but +bf16+nosimd is valid and enables just the scalar bf16 instructions. rdma behaves similarly. To handle cases like these, the option entries have extra fields to specify what an explicit +foo enables and what an explicit +nofoo disables, in addition to the absolute dependencies. The other main changes are: - AARCH64_FL_* are now defined automatically. - the feature list for each architecture level moves from aarch64.h to aarch64-arches.def. As a consequence, we now have a (redundant) V8A feature flag. While there, the patch uses a new typedef, aarch64_feature_flags, for the set of feature flags. This should make it easier to switch to a class if we run out of bits in the uint64_t. For now the patch hardcodes the fact that crypto is the only synthetic option. A later patch will remove this field. To test for things that might not be covered by the testsuite, I made the driver print out the all_extensions, all_cores and all_archs arrays before and after the patch, with the following tweaks: - renumber the old AARCH64_FL_* bit assignments to match the .def order - remove the new V8A flag when printing the new tables - treat CRYPTO and CRYPTO | AES | SHA2 the same way when printing the core tables (On the last point: some cores enabled just CRYPTO while others enabled CRYPTO, AES and SHA2. This doesn't cause a difference in behaviour because of how the dependent macros are defined. With the new scheme, all entries with CRYPTO automatically get AES and SHA2 too.) The only difference is that +nofp now turns off dotprod. This was another instance of an incomplete transitive closure, but unlike the instances fixed in a previous patch, it had no observable effect. gcc/ * config/aarch64/aarch64-option-extensions.def: Switch to a new format. * config/aarch64/aarch64-cores.def: Use the same format to specify lists of features. * config/aarch64/aarch64-arches.def: Likewise, moving that information from aarch64.h. * config/aarch64/aarch64-opts.h (aarch64_feature_flags): New typedef. * config/aarch64/aarch64.h (aarch64_feature): New class enum. Turn AARCH64_FL_* macros into constexprs, getting the definitions from aarch64-option-extensions.def. Remove AARCH64_FL_FOR_* macros. * common/config/aarch64/aarch64-common.cc: Include aarch64-feature-deps.h. (all_extensions): Update for new .def format. (all_extensions_by_on, all_cores, all_architectures): Likewise. * config/aarch64/driver-aarch64.cc: Include aarch64-feature-deps.h. (aarch64_extensions): Update for new .def format. (aarch64_cpu_data, aarch64_arches): Likewise. * config/aarch64/aarch64.cc: Include aarch64-feature-deps.h. (all_architectures, all_cores): Update for new .def format. * config/aarch64/aarch64-sve-builtins.cc (check_required_extensions): Likewise. Diff: --- gcc/common/config/aarch64/aarch64-common.cc | 29 +- gcc/config/aarch64/aarch64-arches.def | 28 +- gcc/config/aarch64/aarch64-cores.def | 130 ++++----- gcc/config/aarch64/aarch64-feature-deps.h | 121 +++++++++ gcc/config/aarch64/aarch64-option-extensions.def | 323 ++++++++--------------- gcc/config/aarch64/aarch64-opts.h | 4 + gcc/config/aarch64/aarch64-sve-builtins.cc | 5 +- gcc/config/aarch64/aarch64.cc | 14 +- gcc/config/aarch64/aarch64.h | 164 ++---------- gcc/config/aarch64/driver-aarch64.cc | 10 +- 10 files changed, 374 insertions(+), 454 deletions(-) diff --git a/gcc/common/config/aarch64/aarch64-common.cc b/gcc/common/config/aarch64/aarch64-common.cc index 0c6d25eb233..e5c83547bb2 100644 --- a/gcc/common/config/aarch64/aarch64-common.cc +++ b/gcc/common/config/aarch64/aarch64-common.cc @@ -30,6 +30,7 @@ #include "opts.h" #include "flags.h" #include "diagnostic.h" +#include "config/aarch64/aarch64-feature-deps.h" #ifdef TARGET_BIG_ENDIAN_DEFAULT #undef TARGET_DEFAULT_TARGET_FLAGS @@ -138,9 +139,12 @@ struct aarch64_option_extension /* ISA extensions in AArch64. */ static const struct aarch64_option_extension all_extensions[] = { -#define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ - SYNTHETIC, Z) \ - {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, SYNTHETIC}, +#define AARCH64_OPT_EXTENSION(NAME, IDENT, C, D, E, F) \ + {NAME, AARCH64_FL_##IDENT, \ + feature_deps::IDENT ().explicit_on & ~AARCH64_FL_##IDENT, \ + feature_deps::get_flags_off (feature_deps::root_off_##IDENT) \ + & ~AARCH64_FL_##IDENT, \ + AARCH64_FL_##IDENT == AARCH64_FL_CRYPTO}, #include "config/aarch64/aarch64-option-extensions.def" {NULL, 0, 0, 0, false} }; @@ -149,9 +153,12 @@ static const struct aarch64_option_extension all_extensions[] = bits and extension turned on. Cached for efficiency. */ static struct aarch64_option_extension all_extensions_by_on[] = { -#define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ - SYNTHETIC, Z) \ - {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, SYNTHETIC}, +#define AARCH64_OPT_EXTENSION(NAME, IDENT, C, D, E, F) \ + {NAME, AARCH64_FL_##IDENT, \ + feature_deps::IDENT ().explicit_on & ~AARCH64_FL_##IDENT, \ + feature_deps::get_flags_off (feature_deps::root_off_##IDENT) \ + & ~AARCH64_FL_##IDENT, \ + AARCH64_FL_##IDENT == AARCH64_FL_CRYPTO}, #include "config/aarch64/aarch64-option-extensions.def" {NULL, 0, 0, 0, false} }; @@ -174,18 +181,18 @@ struct arch_to_arch_name the default set of architectural feature flags they support. */ static const struct processor_name_to_arch all_cores[] = { -#define AARCH64_CORE(NAME, X, IDENT, ARCH_IDENT, FLAGS, COSTS, IMP, PART, VARIANT) \ - {NAME, AARCH64_ARCH_##ARCH_IDENT, AARCH64_FL_FOR_##ARCH_IDENT | FLAGS}, +#define AARCH64_CORE(NAME, CORE_IDENT, C, ARCH_IDENT, E, F, G, H, I) \ + {NAME, AARCH64_ARCH_##ARCH_IDENT, feature_deps::cpu_##CORE_IDENT}, #include "config/aarch64/aarch64-cores.def" - {"generic", AARCH64_ARCH_V8A, AARCH64_FL_FOR_V8A}, + {"generic", AARCH64_ARCH_V8A, feature_deps::V8A ().enable}, {"", aarch64_no_arch, 0} }; /* Map architecture revisions to their string representation. */ static const struct arch_to_arch_name all_architectures[] = { -#define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, ARCH, FLAGS) \ - {AARCH64_ARCH_##ARCH_IDENT, NAME, FLAGS}, +#define AARCH64_ARCH(NAME, B, ARCH_IDENT, D, E) \ + {AARCH64_ARCH_##ARCH_IDENT, NAME, feature_deps::ARCH_IDENT ().enable}, #include "config/aarch64/aarch64-arches.def" {aarch64_no_arch, "", 0} }; diff --git a/gcc/config/aarch64/aarch64-arches.def b/gcc/config/aarch64/aarch64-arches.def index ece96e22a70..9f82466181d 100644 --- a/gcc/config/aarch64/aarch64-arches.def +++ b/gcc/config/aarch64/aarch64-arches.def @@ -30,19 +30,19 @@ Due to the assumptions about the positions of these fields in config.gcc, NAME should be kept as the first argument. */ -AARCH64_ARCH("armv8-a", generic, V8A, 8, AARCH64_FL_FOR_V8A) -AARCH64_ARCH("armv8.1-a", generic, V8_1A, 8, AARCH64_FL_FOR_V8_1A) -AARCH64_ARCH("armv8.2-a", generic, V8_2A, 8, AARCH64_FL_FOR_V8_2A) -AARCH64_ARCH("armv8.3-a", generic, V8_3A, 8, AARCH64_FL_FOR_V8_3A) -AARCH64_ARCH("armv8.4-a", generic, V8_4A, 8, AARCH64_FL_FOR_V8_4A) -AARCH64_ARCH("armv8.5-a", generic, V8_5A, 8, AARCH64_FL_FOR_V8_5A) -AARCH64_ARCH("armv8.6-a", generic, V8_6A, 8, AARCH64_FL_FOR_V8_6A) -AARCH64_ARCH("armv8.7-a", generic, V8_7A, 8, AARCH64_FL_FOR_V8_7A) -AARCH64_ARCH("armv8.8-a", generic, V8_8A, 8, AARCH64_FL_FOR_V8_8A) -AARCH64_ARCH("armv8-r", generic, V8R , 8, AARCH64_FL_FOR_V8R) -AARCH64_ARCH("armv9-a", generic, V9A , 9, AARCH64_FL_FOR_V9A) -AARCH64_ARCH("armv9.1-a", generic, V9_1A, 9, AARCH64_FL_FOR_V9_1A) -AARCH64_ARCH("armv9.2-a", generic, V9_2A, 9, AARCH64_FL_FOR_V9_2A) -AARCH64_ARCH("armv9.3-a", generic, V9_3A, 9, AARCH64_FL_FOR_V9_3A) +AARCH64_ARCH("armv8-a", generic, V8A, 8, (SIMD)) +AARCH64_ARCH("armv8.1-a", generic, V8_1A, 8, (V8A, LSE, CRC, RDMA)) +AARCH64_ARCH("armv8.2-a", generic, V8_2A, 8, (V8_1A)) +AARCH64_ARCH("armv8.3-a", generic, V8_3A, 8, (V8_2A, PAUTH)) +AARCH64_ARCH("armv8.4-a", generic, V8_4A, 8, (V8_3A, F16FML, DOTPROD, FLAGM)) +AARCH64_ARCH("armv8.5-a", generic, V8_5A, 8, (V8_4A, SB, SSBS, PREDRES)) +AARCH64_ARCH("armv8.6-a", generic, V8_6A, 8, (V8_5A, I8MM, BF16)) +AARCH64_ARCH("armv8.7-a", generic, V8_7A, 8, (V8_6A, LS64)) +AARCH64_ARCH("armv8.8-a", generic, V8_8A, 8, (V8_7A, MOPS)) +AARCH64_ARCH("armv8-r", generic, V8R , 8, (V8_4A)) +AARCH64_ARCH("armv9-a", generic, V9A , 9, (V8_5A, SVE2)) +AARCH64_ARCH("armv9.1-a", generic, V9_1A, 9, (V8_6A, V9A)) +AARCH64_ARCH("armv9.2-a", generic, V9_2A, 9, (V8_7A, V9_1A)) +AARCH64_ARCH("armv9.3-a", generic, V9_3A, 9, (V8_8A, V9_2A)) #undef AARCH64_ARCH diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def index cf500d0a981..60299160bb6 100644 --- a/gcc/config/aarch64/aarch64-cores.def +++ b/gcc/config/aarch64/aarch64-cores.def @@ -46,132 +46,132 @@ /* ARMv8-A Architecture Processors. */ /* ARM ('A') cores. */ -AARCH64_CORE("cortex-a34", cortexa34, cortexa53, V8A, AARCH64_FL_CRC, cortexa35, 0x41, 0xd02, -1) -AARCH64_CORE("cortex-a35", cortexa35, cortexa53, V8A, AARCH64_FL_CRC, cortexa35, 0x41, 0xd04, -1) -AARCH64_CORE("cortex-a53", cortexa53, cortexa53, V8A, AARCH64_FL_CRC, cortexa53, 0x41, 0xd03, -1) -AARCH64_CORE("cortex-a57", cortexa57, cortexa57, V8A, AARCH64_FL_CRC, cortexa57, 0x41, 0xd07, -1) -AARCH64_CORE("cortex-a72", cortexa72, cortexa57, V8A, AARCH64_FL_CRC, cortexa72, 0x41, 0xd08, -1) -AARCH64_CORE("cortex-a73", cortexa73, cortexa57, V8A, AARCH64_FL_CRC, cortexa73, 0x41, 0xd09, -1) +AARCH64_CORE("cortex-a34", cortexa34, cortexa53, V8A, (CRC), cortexa35, 0x41, 0xd02, -1) +AARCH64_CORE("cortex-a35", cortexa35, cortexa53, V8A, (CRC), cortexa35, 0x41, 0xd04, -1) +AARCH64_CORE("cortex-a53", cortexa53, cortexa53, V8A, (CRC), cortexa53, 0x41, 0xd03, -1) +AARCH64_CORE("cortex-a57", cortexa57, cortexa57, V8A, (CRC), cortexa57, 0x41, 0xd07, -1) +AARCH64_CORE("cortex-a72", cortexa72, cortexa57, V8A, (CRC), cortexa72, 0x41, 0xd08, -1) +AARCH64_CORE("cortex-a73", cortexa73, cortexa57, V8A, (CRC), cortexa73, 0x41, 0xd09, -1) /* Cavium ('C') cores. */ -AARCH64_CORE("thunderx", thunderx, thunderx, V8A, AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderx, 0x43, 0x0a0, -1) +AARCH64_CORE("thunderx", thunderx, thunderx, V8A, (CRC, CRYPTO), thunderx, 0x43, 0x0a0, -1) /* Do not swap around "thunderxt88p1" and "thunderxt88", this order is required to handle variant correctly. */ -AARCH64_CORE("thunderxt88p1", thunderxt88p1, thunderx, V8A, AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderxt88, 0x43, 0x0a1, 0) -AARCH64_CORE("thunderxt88", thunderxt88, thunderx, V8A, AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderxt88, 0x43, 0x0a1, -1) +AARCH64_CORE("thunderxt88p1", thunderxt88p1, thunderx, V8A, (CRC, CRYPTO), thunderxt88, 0x43, 0x0a1, 0) +AARCH64_CORE("thunderxt88", thunderxt88, thunderx, V8A, (CRC, CRYPTO), thunderxt88, 0x43, 0x0a1, -1) /* OcteonTX is the official name for T81/T83. */ -AARCH64_CORE("octeontx", octeontx, thunderx, V8A, AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderx, 0x43, 0x0a0, -1) -AARCH64_CORE("octeontx81", octeontxt81, thunderx, V8A, AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderx, 0x43, 0x0a2, -1) -AARCH64_CORE("octeontx83", octeontxt83, thunderx, V8A, AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderx, 0x43, 0x0a3, -1) +AARCH64_CORE("octeontx", octeontx, thunderx, V8A, (CRC, CRYPTO), thunderx, 0x43, 0x0a0, -1) +AARCH64_CORE("octeontx81", octeontxt81, thunderx, V8A, (CRC, CRYPTO), thunderx, 0x43, 0x0a2, -1) +AARCH64_CORE("octeontx83", octeontxt83, thunderx, V8A, (CRC, CRYPTO), thunderx, 0x43, 0x0a3, -1) -AARCH64_CORE("thunderxt81", thunderxt81, thunderx, V8A, AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderx, 0x43, 0x0a2, -1) -AARCH64_CORE("thunderxt83", thunderxt83, thunderx, V8A, AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderx, 0x43, 0x0a3, -1) +AARCH64_CORE("thunderxt81", thunderxt81, thunderx, V8A, (CRC, CRYPTO), thunderx, 0x43, 0x0a2, -1) +AARCH64_CORE("thunderxt83", thunderxt83, thunderx, V8A, (CRC, CRYPTO), thunderx, 0x43, 0x0a3, -1) /* Ampere Computing ('\xC0') cores. */ -AARCH64_CORE("ampere1", ampere1, cortexa57, V8_6A, 0, ampere1, 0xC0, 0xac3, -1) +AARCH64_CORE("ampere1", ampere1, cortexa57, V8_6A, (), ampere1, 0xC0, 0xac3, -1) /* Do not swap around "emag" and "xgene1", this order is required to handle variant correctly. */ -AARCH64_CORE("emag", emag, xgene1, V8A, AARCH64_FL_CRC | AARCH64_FL_CRYPTO, emag, 0x50, 0x000, 3) +AARCH64_CORE("emag", emag, xgene1, V8A, (CRC, CRYPTO), emag, 0x50, 0x000, 3) /* APM ('P') cores. */ -AARCH64_CORE("xgene1", xgene1, xgene1, V8A, 0, xgene1, 0x50, 0x000, -1) +AARCH64_CORE("xgene1", xgene1, xgene1, V8A, (), xgene1, 0x50, 0x000, -1) /* Qualcomm ('Q') cores. */ -AARCH64_CORE("falkor", falkor, falkor, V8A, AARCH64_FL_CRC | AARCH64_FL_CRYPTO | AARCH64_FL_RDMA, qdf24xx, 0x51, 0xC00, -1) -AARCH64_CORE("qdf24xx", qdf24xx, falkor, V8A, AARCH64_FL_CRC | AARCH64_FL_CRYPTO | AARCH64_FL_RDMA, qdf24xx, 0x51, 0xC00, -1) +AARCH64_CORE("falkor", falkor, falkor, V8A, (CRC, CRYPTO, RDMA), qdf24xx, 0x51, 0xC00, -1) +AARCH64_CORE("qdf24xx", qdf24xx, falkor, V8A, (CRC, CRYPTO, RDMA), qdf24xx, 0x51, 0xC00, -1) /* Samsung ('S') cores. */ -AARCH64_CORE("exynos-m1", exynosm1, exynosm1, V8A, AARCH64_FL_CRC | AARCH64_FL_CRYPTO, exynosm1, 0x53, 0x001, -1) +AARCH64_CORE("exynos-m1", exynosm1, exynosm1, V8A, (CRC, CRYPTO), exynosm1, 0x53, 0x001, -1) /* HXT ('h') cores. */ -AARCH64_CORE("phecda", phecda, falkor, V8A, AARCH64_FL_CRC | AARCH64_FL_CRYPTO, qdf24xx, 0x68, 0x000, -1) +AARCH64_CORE("phecda", phecda, falkor, V8A, (CRC, CRYPTO), qdf24xx, 0x68, 0x000, -1) /* ARMv8.1-A Architecture Processors. */ /* Broadcom ('B') cores. */ -AARCH64_CORE("thunderx2t99p1", thunderx2t99p1, thunderx2t99, V8_1A, AARCH64_FL_CRYPTO, thunderx2t99, 0x42, 0x516, -1) -AARCH64_CORE("vulcan", vulcan, thunderx2t99, V8_1A, AARCH64_FL_CRYPTO, thunderx2t99, 0x42, 0x516, -1) +AARCH64_CORE("thunderx2t99p1", thunderx2t99p1, thunderx2t99, V8_1A, (CRYPTO), thunderx2t99, 0x42, 0x516, -1) +AARCH64_CORE("vulcan", vulcan, thunderx2t99, V8_1A, (CRYPTO), thunderx2t99, 0x42, 0x516, -1) /* Cavium ('C') cores. */ -AARCH64_CORE("thunderx2t99", thunderx2t99, thunderx2t99, V8_1A, AARCH64_FL_CRYPTO, thunderx2t99, 0x43, 0x0af, -1) +AARCH64_CORE("thunderx2t99", thunderx2t99, thunderx2t99, V8_1A, (CRYPTO), thunderx2t99, 0x43, 0x0af, -1) /* ARMv8.2-A Architecture Processors. */ /* ARM ('A') cores. */ -AARCH64_CORE("cortex-a55", cortexa55, cortexa53, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, cortexa53, 0x41, 0xd05, -1) -AARCH64_CORE("cortex-a75", cortexa75, cortexa57, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, cortexa73, 0x41, 0xd0a, -1) -AARCH64_CORE("cortex-a76", cortexa76, cortexa57, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, neoversen1, 0x41, 0xd0b, -1) -AARCH64_CORE("cortex-a76ae", cortexa76ae, cortexa57, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, neoversen1, 0x41, 0xd0e, -1) -AARCH64_CORE("cortex-a77", cortexa77, cortexa57, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, neoversen1, 0x41, 0xd0d, -1) -AARCH64_CORE("cortex-a78", cortexa78, cortexa57, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd41, -1) -AARCH64_CORE("cortex-a78ae", cortexa78ae, cortexa57, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd42, -1) -AARCH64_CORE("cortex-a78c", cortexa78c, cortexa57, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS | AARCH64_FL_PROFILE | AARCH64_FL_FLAGM | AARCH64_FL_PAUTH, neoversen1, 0x41, 0xd4b, -1) -AARCH64_CORE("cortex-a65", cortexa65, cortexa53, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, cortexa73, 0x41, 0xd06, -1) -AARCH64_CORE("cortex-a65ae", cortexa65ae, cortexa53, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, cortexa73, 0x41, 0xd43, -1) -AARCH64_CORE("cortex-x1", cortexx1, cortexa57, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd44, -1) -AARCH64_CORE("ares", ares, cortexa57, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd0c, -1) -AARCH64_CORE("neoverse-n1", neoversen1, cortexa57, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd0c, -1) -AARCH64_CORE("neoverse-e1", neoversee1, cortexa53, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, cortexa73, 0x41, 0xd4a, -1) +AARCH64_CORE("cortex-a55", cortexa55, cortexa53, V8_2A, (F16, RCPC, DOTPROD), cortexa53, 0x41, 0xd05, -1) +AARCH64_CORE("cortex-a75", cortexa75, cortexa57, V8_2A, (F16, RCPC, DOTPROD), cortexa73, 0x41, 0xd0a, -1) +AARCH64_CORE("cortex-a76", cortexa76, cortexa57, V8_2A, (F16, RCPC, DOTPROD), neoversen1, 0x41, 0xd0b, -1) +AARCH64_CORE("cortex-a76ae", cortexa76ae, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS), neoversen1, 0x41, 0xd0e, -1) +AARCH64_CORE("cortex-a77", cortexa77, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS), neoversen1, 0x41, 0xd0d, -1) +AARCH64_CORE("cortex-a78", cortexa78, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS, PROFILE), neoversen1, 0x41, 0xd41, -1) +AARCH64_CORE("cortex-a78ae", cortexa78ae, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS, PROFILE), neoversen1, 0x41, 0xd42, -1) +AARCH64_CORE("cortex-a78c", cortexa78c, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS, PROFILE, FLAGM, PAUTH), neoversen1, 0x41, 0xd4b, -1) +AARCH64_CORE("cortex-a65", cortexa65, cortexa53, V8_2A, (F16, RCPC, DOTPROD, SSBS), cortexa73, 0x41, 0xd06, -1) +AARCH64_CORE("cortex-a65ae", cortexa65ae, cortexa53, V8_2A, (F16, RCPC, DOTPROD, SSBS), cortexa73, 0x41, 0xd43, -1) +AARCH64_CORE("cortex-x1", cortexx1, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS, PROFILE), neoversen1, 0x41, 0xd44, -1) +AARCH64_CORE("ares", ares, cortexa57, V8_2A, (F16, RCPC, DOTPROD, PROFILE), neoversen1, 0x41, 0xd0c, -1) +AARCH64_CORE("neoverse-n1", neoversen1, cortexa57, V8_2A, (F16, RCPC, DOTPROD, PROFILE), neoversen1, 0x41, 0xd0c, -1) +AARCH64_CORE("neoverse-e1", neoversee1, cortexa53, V8_2A, (F16, RCPC, DOTPROD, SSBS), cortexa73, 0x41, 0xd4a, -1) /* Cavium ('C') cores. */ -AARCH64_CORE("octeontx2", octeontx2, cortexa57, V8_2A, AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b0, -1) -AARCH64_CORE("octeontx2t98", octeontx2t98, cortexa57, V8_2A, AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b1, -1) -AARCH64_CORE("octeontx2t96", octeontx2t96, cortexa57, V8_2A, AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b2, -1) +AARCH64_CORE("octeontx2", octeontx2, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b0, -1) +AARCH64_CORE("octeontx2t98", octeontx2t98, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b1, -1) +AARCH64_CORE("octeontx2t96", octeontx2t96, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b2, -1) /* Note OcteonTX2 T93 is an alias to OcteonTX2 T96. */ -AARCH64_CORE("octeontx2t93", octeontx2t93, cortexa57, V8_2A, AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b2, -1) -AARCH64_CORE("octeontx2f95", octeontx2f95, cortexa57, V8_2A, AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b3, -1) -AARCH64_CORE("octeontx2f95n", octeontx2f95n, cortexa57, V8_2A, AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b4, -1) -AARCH64_CORE("octeontx2f95mm", octeontx2f95mm, cortexa57, V8_2A, AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b5, -1) +AARCH64_CORE("octeontx2t93", octeontx2t93, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b2, -1) +AARCH64_CORE("octeontx2f95", octeontx2f95, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b3, -1) +AARCH64_CORE("octeontx2f95n", octeontx2f95n, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b4, -1) +AARCH64_CORE("octeontx2f95mm", octeontx2f95mm, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b5, -1) /* Fujitsu ('F') cores. */ -AARCH64_CORE("a64fx", a64fx, a64fx, V8_2A, AARCH64_FL_F16 | AARCH64_FL_SVE, a64fx, 0x46, 0x001, -1) +AARCH64_CORE("a64fx", a64fx, a64fx, V8_2A, (F16, SVE), a64fx, 0x46, 0x001, -1) /* HiSilicon ('H') cores. */ -AARCH64_CORE("tsv110", tsv110, tsv110, V8_2A, AARCH64_FL_CRYPTO | AARCH64_FL_F16 | AARCH64_FL_AES | AARCH64_FL_SHA2, tsv110, 0x48, 0xd01, -1) +AARCH64_CORE("tsv110", tsv110, tsv110, V8_2A, (CRYPTO, F16), tsv110, 0x48, 0xd01, -1) /* ARMv8.3-A Architecture Processors. */ /* Marvell cores (TX3). */ -AARCH64_CORE("thunderx3t110", thunderx3t110, thunderx3t110, V8_3A, AARCH64_FL_CRYPTO | AARCH64_FL_RCPC | AARCH64_FL_SM4 | AARCH64_FL_SHA3 | AARCH64_FL_F16FML, thunderx3t110, 0x43, 0x0b8, 0x0a) +AARCH64_CORE("thunderx3t110", thunderx3t110, thunderx3t110, V8_3A, (CRYPTO, RCPC, SM4, SHA3, F16FML), thunderx3t110, 0x43, 0x0b8, 0x0a) /* ARMv8.4-A Architecture Processors. */ /* Arm ('A') cores. */ -AARCH64_CORE("zeus", zeus, cortexa57, V8_4A, AARCH64_FL_SVE | AARCH64_FL_RCPC | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_F16 | AARCH64_FL_PROFILE | AARCH64_FL_SSBS | AARCH64_FL_RNG, neoversev1, 0x41, 0xd40, -1) -AARCH64_CORE("neoverse-v1", neoversev1, cortexa57, V8_4A, AARCH64_FL_SVE | AARCH64_FL_RCPC | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_F16 | AARCH64_FL_PROFILE | AARCH64_FL_SSBS | AARCH64_FL_RNG, neoversev1, 0x41, 0xd40, -1) -AARCH64_CORE("neoverse-512tvb", neoverse512tvb, cortexa57, V8_4A, AARCH64_FL_SVE | AARCH64_FL_RCPC | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_F16 | AARCH64_FL_PROFILE | AARCH64_FL_SSBS | AARCH64_FL_RNG, neoverse512tvb, INVALID_IMP, INVALID_CORE, -1) +AARCH64_CORE("zeus", zeus, cortexa57, V8_4A, (SVE, RCPC, I8MM, BF16, PROFILE, SSBS, RNG), neoversev1, 0x41, 0xd40, -1) +AARCH64_CORE("neoverse-v1", neoversev1, cortexa57, V8_4A, (SVE, RCPC, I8MM, BF16, PROFILE, SSBS, RNG), neoversev1, 0x41, 0xd40, -1) +AARCH64_CORE("neoverse-512tvb", neoverse512tvb, cortexa57, V8_4A, (SVE, RCPC, I8MM, BF16, PROFILE, SSBS, RNG), neoverse512tvb, INVALID_IMP, INVALID_CORE, -1) /* Qualcomm ('Q') cores. */ -AARCH64_CORE("saphira", saphira, saphira, V8_4A, AARCH64_FL_CRYPTO | AARCH64_FL_RCPC, saphira, 0x51, 0xC01, -1) +AARCH64_CORE("saphira", saphira, saphira, V8_4A, (CRYPTO, RCPC), saphira, 0x51, 0xC01, -1) /* ARMv8-A big.LITTLE implementations. */ -AARCH64_CORE("cortex-a57.cortex-a53", cortexa57cortexa53, cortexa53, V8A, AARCH64_FL_CRC, cortexa57, 0x41, AARCH64_BIG_LITTLE (0xd07, 0xd03), -1) -AARCH64_CORE("cortex-a72.cortex-a53", cortexa72cortexa53, cortexa53, V8A, AARCH64_FL_CRC, cortexa72, 0x41, AARCH64_BIG_LITTLE (0xd08, 0xd03), -1) -AARCH64_CORE("cortex-a73.cortex-a35", cortexa73cortexa35, cortexa53, V8A, AARCH64_FL_CRC, cortexa73, 0x41, AARCH64_BIG_LITTLE (0xd09, 0xd04), -1) -AARCH64_CORE("cortex-a73.cortex-a53", cortexa73cortexa53, cortexa53, V8A, AARCH64_FL_CRC, cortexa73, 0x41, AARCH64_BIG_LITTLE (0xd09, 0xd03), -1) +AARCH64_CORE("cortex-a57.cortex-a53", cortexa57cortexa53, cortexa53, V8A, (CRC), cortexa57, 0x41, AARCH64_BIG_LITTLE (0xd07, 0xd03), -1) +AARCH64_CORE("cortex-a72.cortex-a53", cortexa72cortexa53, cortexa53, V8A, (CRC), cortexa72, 0x41, AARCH64_BIG_LITTLE (0xd08, 0xd03), -1) +AARCH64_CORE("cortex-a73.cortex-a35", cortexa73cortexa35, cortexa53, V8A, (CRC), cortexa73, 0x41, AARCH64_BIG_LITTLE (0xd09, 0xd04), -1) +AARCH64_CORE("cortex-a73.cortex-a53", cortexa73cortexa53, cortexa53, V8A, (CRC), cortexa73, 0x41, AARCH64_BIG_LITTLE (0xd09, 0xd03), -1) /* ARM DynamIQ big.LITTLE configurations. */ -AARCH64_CORE("cortex-a75.cortex-a55", cortexa75cortexa55, cortexa53, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, cortexa73, 0x41, AARCH64_BIG_LITTLE (0xd0a, 0xd05), -1) -AARCH64_CORE("cortex-a76.cortex-a55", cortexa76cortexa55, cortexa53, V8_2A, AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, neoversen1, 0x41, AARCH64_BIG_LITTLE (0xd0b, 0xd05), -1) +AARCH64_CORE("cortex-a75.cortex-a55", cortexa75cortexa55, cortexa53, V8_2A, (F16, RCPC, DOTPROD), cortexa73, 0x41, AARCH64_BIG_LITTLE (0xd0a, 0xd05), -1) +AARCH64_CORE("cortex-a76.cortex-a55", cortexa76cortexa55, cortexa53, V8_2A, (F16, RCPC, DOTPROD), neoversen1, 0x41, AARCH64_BIG_LITTLE (0xd0b, 0xd05), -1) /* Armv8-R Architecture Processors. */ -AARCH64_CORE("cortex-r82", cortexr82, cortexa53, V8R, 0, cortexa53, 0x41, 0xd15, -1) +AARCH64_CORE("cortex-r82", cortexr82, cortexa53, V8R, (), cortexa53, 0x41, 0xd15, -1) /* Armv9.0-A Architecture Processors. */ /* Arm ('A') cores. */ -AARCH64_CORE("cortex-a510", cortexa510, cortexa55, V9A, AARCH64_FL_SVE2_BITPERM | AARCH64_FL_MEMTAG | AARCH64_FL_I8MM | AARCH64_FL_BF16, cortexa53, 0x41, 0xd46, -1) +AARCH64_CORE("cortex-a510", cortexa510, cortexa55, V9A, (SVE2_BITPERM, MEMTAG, I8MM, BF16), cortexa53, 0x41, 0xd46, -1) -AARCH64_CORE("cortex-a710", cortexa710, cortexa57, V9A, AARCH64_FL_SVE2_BITPERM | AARCH64_FL_MEMTAG | AARCH64_FL_I8MM | AARCH64_FL_BF16, neoversen2, 0x41, 0xd47, -1) +AARCH64_CORE("cortex-a710", cortexa710, cortexa57, V9A, (SVE2_BITPERM, MEMTAG, I8MM, BF16), neoversen2, 0x41, 0xd47, -1) -AARCH64_CORE("cortex-x2", cortexx2, cortexa57, V9A, AARCH64_FL_SVE2_BITPERM | AARCH64_FL_MEMTAG | AARCH64_FL_I8MM | AARCH64_FL_BF16, neoversen2, 0x41, 0xd48, -1) +AARCH64_CORE("cortex-x2", cortexx2, cortexa57, V9A, (SVE2_BITPERM, MEMTAG, I8MM, BF16), neoversen2, 0x41, 0xd48, -1) -AARCH64_CORE("neoverse-n2", neoversen2, cortexa57, V9A, AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversen2, 0x41, 0xd49, -1) +AARCH64_CORE("neoverse-n2", neoversen2, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversen2, 0x41, 0xd49, -1) -AARCH64_CORE("demeter", demeter, cortexa57, V9A, AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversev2, 0x41, 0xd4f, -1) -AARCH64_CORE("neoverse-v2", neoversev2, cortexa57, V9A, AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversev2, 0x41, 0xd4f, -1) +AARCH64_CORE("demeter", demeter, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1) +AARCH64_CORE("neoverse-v2", neoversev2, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1) #undef AARCH64_CORE diff --git a/gcc/config/aarch64/aarch64-feature-deps.h b/gcc/config/aarch64/aarch64-feature-deps.h new file mode 100644 index 00000000000..3e33cb2ce84 --- /dev/null +++ b/gcc/config/aarch64/aarch64-feature-deps.h @@ -0,0 +1,121 @@ +/* Feature dependency helpers for AArch64. + Copyright (C) 2022 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#ifndef AARCH64_FEATURE_DEPS_H +#define AARCH64_FEATURE_DEPS_H 1 + +namespace { +namespace feature_deps { + +/* Together, these definitions of get_flags take a list of + feature names (representing functions that are defined below) + and return the set of associated flags. */ +constexpr aarch64_feature_flags get_flags () { return 0; } + +template +constexpr aarch64_feature_flags +get_flags (T1 i, Ts... args) +{ + return i ().flag | get_flags (args...); +} + +/* Like get_flags, but return the transitive closure of those features + and the ones that they rely on. */ +constexpr aarch64_feature_flags get_enable () { return 0; } + +template +constexpr aarch64_feature_flags +get_enable (T1 i, Ts... args) +{ + return i ().enable | get_enable (args...); +} + +/* Define info such that it has the following static constant + variables: + + - flag: the aarch64_feature_flags bit associated with FEATURE + + - enable: the transitive closure of the features that FEATURE requires, + plus FLAG itself + + - explicit_on: the transitive closure of the features that an + explicit +FEATURE enables, including FLAG itself. This is + always a superset of ENABLE + + Also define a function FEATURE () that returns an info + (which is an empty structure, since all members are static). + + Building up the list feature-by-feature ensures that the definition + files are in topological order. */ +template struct info; + +#define HANDLE(IDENT, REQUIRES, EXPLICIT_ON) \ + template<> struct info { \ + static constexpr auto flag = AARCH64_FL_##IDENT; \ + static constexpr auto enable = flag | get_enable REQUIRES; \ + static constexpr auto explicit_on = enable | get_enable EXPLICIT_ON; \ + }; \ + constexpr info IDENT () \ + { \ + return info (); \ + } +#define AARCH64_OPT_EXTENSION(A, IDENT, REQUIRES, EXPLICIT_ON, E, F) \ + HANDLE (IDENT, REQUIRES, EXPLICIT_ON) +#define AARCH64_ARCH(A, B, IDENT, D, REQUIRES) HANDLE (IDENT, REQUIRES, ()) +#include "config/aarch64/aarch64-option-extensions.def" +#include "config/aarch64/aarch64-arches.def" +#undef HANDLE + +/* Return the set of all features that would need to be disabled if + the features in MASK are disabled. + + Note that the size of the expression varies linearly with the number + of features, which means that invoking this function once per feature + is quadratic in the number of features. However, collecting the same + information at compiler start-up is likely to be quadratic too, so + we're better off paying the cost once per compiler build rather than + once per compiler run. */ +constexpr aarch64_feature_flags +get_flags_off (aarch64_feature_flags mask) +{ + return (0 +#define AARCH64_OPT_EXTENSION(A, IDENT, C, D, E, F) \ + | (feature_deps::IDENT ().enable & mask ? AARCH64_FL_##IDENT : 0) +#include "config/aarch64/aarch64-option-extensions.def" + ); +} + +/* Define root_off_ variables for each feature, giving the set of + features that must be turned off by +noIDENT. This set is not transitively + closed; use get_flags_off to complete the closure. */ +#define AARCH64_OPT_EXTENSION(A, IDENT, C, D, EXPLICIT_OFF, F) \ + constexpr auto root_off_##IDENT \ + = AARCH64_FL_##IDENT | get_flags EXPLICIT_OFF; +#include "config/aarch64/aarch64-option-extensions.def" + +/* Define cpu_ variables for each CPU, giving the transitive + closure of all the features that the CPU supports. */ +#define AARCH64_CORE(A, CORE_IDENT, C, ARCH_IDENT, FEATURES, F, G, H, I) \ + constexpr auto cpu_##CORE_IDENT = ARCH_IDENT ().enable | get_enable FEATURES; +#include "config/aarch64/aarch64-cores.def" + +} +} + +#endif diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def index df2c8d19b8d..bdf4baf309c 100644 --- a/gcc/config/aarch64/aarch64-option-extensions.def +++ b/gcc/config/aarch64/aarch64-option-extensions.def @@ -21,23 +21,34 @@ Before using #include to read this file, define a macro: - AARCH64_OPT_EXTENSION(EXT_NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, - SYNTHETIC, FEATURE_STRING) - - - EXT_NAME is the name of the extension, represented as a string constant. - - FLAGS_CANONICAL is the canonical internal name for this flag. - - FLAGS_ON are the bitwise-or of the features that enabling the extension - adds, or zero if enabling this extension has no effect on other features. - - FLAGS_OFF are the bitwise-or of the features that disabling the extension - removes, or zero if disabling this extension has no effect on other - features. - - SYNTHETIC is a boolean to indicate whether the option is a purely synthetic - grouping of options and that the option itself has no feature bit (e.g. - crypto). This is used to determine when sum of the individual options in - FLAGS_ON can be replaced by FLAG_CANONICAL in options minimization. If the - group is synthetic then they can be replaced when all options in FLAGS_ON - are enabled, otherwise they can only be replaced when - FLAGS_ON | FLAG_CANONICAL are enabled. + AARCH64_OPT_EXTENSION(NAME, IDENT, REQUIRES, EXPLICIT_ON, + EXPLICIT_OFF, FEATURE_STRING) + + - NAME is the name of the extension, represented as a string constant. + + - IDENT is the canonical internal name for this flag. + + - REQUIRES is a list of features that must be enabled whenever this + feature is enabled. The relationship is implicitly transitive: + if A appears in B's REQUIRES and B appears in C's REQUIRES then + A and B must be enabled whenever C is. Thus, turning on C also + turns on A and B, while turning off A or B also turns off C. + + - EXPLICIT_ON is a list of features that are enabled by an explicit + +NAME specification, in addition to those listed in REQUIRES. + Usually this is an empty list; comments below explain the exceptions. + The list is implicitly transitively closed wrt REQUIRES (but *not* + to EXPLICIT_ON, since NAME is the only thing explicit in +NAME). + Thus if A is in B's REQUIRES and B is in C's EXPLICIT_ON, +C will + enable both B and A. B's EXPLICIT_ON has no effect on +C. + + - EXPLICIT_OFF is a list of features that are disabled by an explicit + +noNAME specification, in addition to the features that are transitively + dependent on NAME (according to REQUIRES). As with EXPLICIT_ON, + this is usually an empty list; comments below explain the exceptions. + If a feature A appears in this list then the list implicitly includes + any features that are transitively dependent on A (according to REQUIRES). + - FEAT_STRING is a string containing the entries in the 'Features' field of /proc/cpuinfo on a GNU/Linux system that correspond to this architecture extension being available. Sometimes multiple entries are needed to enable @@ -47,197 +58,95 @@ that are required. Their order is not important. An empty string means do not detect this feature during auto detection. - NOTE: Any changes to the AARCH64_OPT_EXTENSION macro need to be mirrored in - config.gcc. */ - -/* Enabling "fp" just enables "fp". - Disabling "fp" also disables "simd", "crypto", "fp16", "aes", "sha2", - "sha3", sm3/sm4, "sve", "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4", - "sve2-bitperm", "i8mm", "f32mm", "f64mm", and "bf16". */ -AARCH64_OPT_EXTENSION("fp", AARCH64_FL_FP, 0, AARCH64_FL_SIMD | \ - AARCH64_FL_CRYPTO | AARCH64_FL_F16 | AARCH64_FL_AES | \ - AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | AARCH64_FL_SM4 | \ - AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | \ - AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | \ - AARCH64_FL_SVE2_BITPERM | AARCH64_FL_I8MM | \ - AARCH64_FL_F32MM | AARCH64_FL_F64MM | AARCH64_FL_BF16, - false, "fp") - -/* Enabling "simd" also enables "fp". - Disabling "simd" also disables "crypto", "dotprod", "aes", "sha2", "sha3", - "sm3/sm4", "sve", "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4", - "sve2-bitperm", "i8mm", "f32mm" and "f64mm". */ -AARCH64_OPT_EXTENSION("simd", AARCH64_FL_SIMD, AARCH64_FL_FP, \ - AARCH64_FL_CRYPTO | AARCH64_FL_DOTPROD | \ - AARCH64_FL_AES | AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | \ - AARCH64_FL_SM4 | AARCH64_FL_SVE | AARCH64_FL_SVE2 | \ - AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | \ - AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM | \ - AARCH64_FL_I8MM | AARCH64_FL_F32MM | AARCH64_FL_F64MM, \ - false, "asimd") - -/* Enabling or disabling "crc" only changes "crc". */ -AARCH64_OPT_EXTENSION("crc", AARCH64_FL_CRC, 0, 0, false, "crc32") - -/* Enabling or disabling "lse" only changes "lse". */ -AARCH64_OPT_EXTENSION("lse", AARCH64_FL_LSE, 0, 0, false, "atomics") - -/* Enabling "fp16" also enables "fp". - Disabling "fp16" disables "fp16", "fp16fml", "sve", "sve2", - "sve2-aes", "sve2-sha3", "sve2-sm4", "sve2-bitperm", "f32mm" and - "f64mm". */ -AARCH64_OPT_EXTENSION("fp16", AARCH64_FL_F16, AARCH64_FL_FP, \ - AARCH64_FL_F16FML | AARCH64_FL_SVE | AARCH64_FL_F32MM | \ - AARCH64_FL_F64MM | AARCH64_FL_SVE2 | \ - AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | \ - AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, \ - "fphp asimdhp") - -/* Enabling or disabling "rcpc" only changes "rcpc". */ -AARCH64_OPT_EXTENSION("rcpc", AARCH64_FL_RCPC, 0, 0, false, "lrcpc") - -/* Enabling "rdma" also enables "fp", "simd". - Disabling "rdma" just disables "rdma". */ -AARCH64_OPT_EXTENSION("rdma", AARCH64_FL_RDMA, \ - AARCH64_FL_FP | AARCH64_FL_SIMD, 0, false, "asimdrdm") - -/* Enabling "dotprod" also enables "simd". - Disabling "dotprod" only disables "dotprod". */ -AARCH64_OPT_EXTENSION("dotprod", AARCH64_FL_DOTPROD, AARCH64_FL_FPSIMD, 0, \ - false, "asimddp") - -/* Enabling "aes" also enables "simd". - Disabling "aes" disables "aes" and "sve2-aes'. */ -AARCH64_OPT_EXTENSION("aes", AARCH64_FL_AES, AARCH64_FL_FPSIMD, \ - AARCH64_FL_SVE2_AES | AARCH64_FL_CRYPTO, false, "aes") - -/* Enabling "sha2" also enables "simd". - Disabling "sha2" just disables "sha2". */ -AARCH64_OPT_EXTENSION("sha2", AARCH64_FL_SHA2, AARCH64_FL_FPSIMD, \ - AARCH64_FL_CRYPTO | AARCH64_FL_SHA3 | \ - AARCH64_FL_SVE2_SHA3, false, "sha1 sha2") - -/* Enabling "crypto" also enables "fp", "simd", "aes" and "sha2". - Disabling "crypto" disables "crypto", "aes", "sha2", "sha3" and "sm3/sm4", - "sve2-aes", "sve2-sha3", "sve2-sm4". */ -AARCH64_OPT_EXTENSION("crypto", AARCH64_FL_CRYPTO, AARCH64_FL_FP | \ - AARCH64_FL_SIMD | AARCH64_FL_AES | AARCH64_FL_SHA2, \ - AARCH64_FL_AES | AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | \ - AARCH64_FL_SM4 | AARCH64_FL_SVE2_AES | \ - AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4, true, \ + The list of features must follow topological order wrt REQUIRES + and EXPLICIT_ON. For example, if A is in B's REQUIRES list, A must + come before B. This is enforced by aarch64-feature-deps.h. + + NOTE: Any changes to the AARCH64_OPT_EXTENSION macro need to be mirrored in + config.gcc. */ + +AARCH64_OPT_EXTENSION("fp", FP, (), (), (), "fp") + +AARCH64_OPT_EXTENSION("simd", SIMD, (FP), (), (), "asimd") + +AARCH64_OPT_EXTENSION("crc", CRC, (), (), (), "crc32") + +AARCH64_OPT_EXTENSION("lse", LSE, (), (), (), "atomics") + +/* +nofp16 disables an implicit F16FML, even though an implicit F16FML + does not imply F16. See F16FML for more details. */ +AARCH64_OPT_EXTENSION("fp16", F16, (FP), (), (F16FML), "fphp asimdhp") + +AARCH64_OPT_EXTENSION("rcpc", RCPC, (), (), (), "lrcpc") + +/* An explicit +rdma implies +simd, but +rdma+nosimd still enables scalar + RDMA instructions. */ +AARCH64_OPT_EXTENSION("rdma", RDMA, (), (SIMD), (), "asimdrdm") + +AARCH64_OPT_EXTENSION("dotprod", DOTPROD, (SIMD), (), (), "asimddp") + +AARCH64_OPT_EXTENSION("aes", AES, (SIMD), (), (), "aes") + +AARCH64_OPT_EXTENSION("sha2", SHA2, (SIMD), (), (), "sha1 sha2") + +/* +nocrypto disables AES, SHA2 and SM4, and anything that depends on them + (such as SHA3 and the SVE2 crypto extensions). */ +AARCH64_OPT_EXTENSION("crypto", CRYPTO, (AES, SHA2), (), (AES, SHA2, SM4), "aes pmull sha1 sha2") -/* Enabling "sha3" enables "simd" and "sha2". - Disabling "sha3" disables "sha3" and "sve2-sha3". */ -AARCH64_OPT_EXTENSION("sha3", AARCH64_FL_SHA3, AARCH64_FL_FPSIMD | \ - AARCH64_FL_SHA2, AARCH64_FL_SVE2_SHA3, false, \ - "sha3 sha512") - -/* Enabling "sm4" also enables "simd". - Disabling "sm4" disables "sm4" and "sve2-sm4". */ -AARCH64_OPT_EXTENSION("sm4", AARCH64_FL_SM4, AARCH64_FL_FPSIMD, \ - AARCH64_FL_SVE2_SM4, false, "sm3 sm4") - -/* Enabling "fp16fml" also enables "fp" and "fp16". - Disabling "fp16fml" just disables "fp16fml". */ -AARCH64_OPT_EXTENSION("fp16fml", AARCH64_FL_F16FML, \ - AARCH64_FL_FP | AARCH64_FL_F16, 0, false, "asimdfhm") - -/* Enabling "sve" also enables "fp16", "fp" and "simd". - Disabling "sve" disables "sve", "f32mm", "f64mm", "sve2", "sve2-aes", - "sve2-sha3", "sve2-sm4" and "sve2-bitperm". */ -AARCH64_OPT_EXTENSION("sve", AARCH64_FL_SVE, AARCH64_FL_FP | AARCH64_FL_SIMD | \ - AARCH64_FL_F16, AARCH64_FL_F32MM | AARCH64_FL_F64MM | \ - AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | \ - AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | \ - AARCH64_FL_SVE2_BITPERM, false, "sve") - -/* Enabling/Disabling "profile" does not enable/disable any other feature. */ -AARCH64_OPT_EXTENSION("profile", AARCH64_FL_PROFILE, 0, 0, false, "") - -/* Enabling/Disabling "rng" only changes "rng". */ -AARCH64_OPT_EXTENSION("rng", AARCH64_FL_RNG, 0, 0, false, "rng") - -/* Enabling/Disabling "memtag" only changes "memtag". */ -AARCH64_OPT_EXTENSION("memtag", AARCH64_FL_MEMTAG, 0, 0, false, "") - -/* Enabling/Disabling "sb" only changes "sb". */ -AARCH64_OPT_EXTENSION("sb", AARCH64_FL_SB, 0, 0, false, "sb") - -/* Enabling/Disabling "ssbs" only changes "ssbs". */ -AARCH64_OPT_EXTENSION("ssbs", AARCH64_FL_SSBS, 0, 0, false, "ssbs") - -/* Enabling/Disabling "predres" only changes "predres". */ -AARCH64_OPT_EXTENSION("predres", AARCH64_FL_PREDRES, 0, 0, false, "") - -/* Enabling "sve2" also enables "sve", "fp16", "fp", and "simd". - Disabling "sve2" disables "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4", and - "sve2-bitperm". */ -AARCH64_OPT_EXTENSION("sve2", AARCH64_FL_SVE2, AARCH64_FL_SVE | \ - AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_F16, \ - AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | \ - AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "sve2") - -/* Enabling "sve2-sm4" also enables "sm4", "simd", "fp16", "fp", "sve", and - "sve2". Disabling "sve2-sm4" just disables "sve2-sm4". */ -AARCH64_OPT_EXTENSION("sve2-sm4", AARCH64_FL_SVE2_SM4, AARCH64_FL_SM4 | \ - AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | \ - AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "svesm4") - -/* Enabling "sve2-aes" also enables "aes", "simd", "fp16", "fp", "sve", and - "sve2". Disabling "sve2-aes" just disables "sve2-aes". */ -AARCH64_OPT_EXTENSION("sve2-aes", AARCH64_FL_SVE2_AES, AARCH64_FL_AES | \ - AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | \ - AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "sveaes") - -/* Enabling "sve2-sha3" also enables "sha3", "simd", "fp16", "fp", "sve", and - "sve2". Disabling "sve2-sha3" just disables "sve2-sha3". */ -AARCH64_OPT_EXTENSION("sve2-sha3", AARCH64_FL_SVE2_SHA3, AARCH64_FL_SHA3 | \ - AARCH64_FL_SHA2 | \ - AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | \ - AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "svesha3") - -/* Enabling "sve2-bitperm" also enables "simd", "fp16", "fp", "sve", and - "sve2". Disabling "sve2-bitperm" just disables "sve2-bitperm". */ -AARCH64_OPT_EXTENSION("sve2-bitperm", AARCH64_FL_SVE2_BITPERM, AARCH64_FL_SIMD | \ - AARCH64_FL_F16 | AARCH64_FL_FP | AARCH64_FL_SVE | \ - AARCH64_FL_SVE2, 0, false, "svebitperm") - -/* Enabling or disabling "tme" only changes "tme". */ -AARCH64_OPT_EXTENSION("tme", AARCH64_FL_TME, 0, 0, false, "") - -/* Enabling "i8mm" also enables "simd" and "fp". - Disabling "i8mm" only disables "i8mm". */ -AARCH64_OPT_EXTENSION("i8mm", AARCH64_FL_I8MM, \ - AARCH64_FL_SIMD | AARCH64_FL_FP, 0, false, "i8mm") - -/* Enabling "f32mm" also enables "sve", "fp16", "fp", and "simd". - Disabling "f32mm" only disables "f32mm". */ -AARCH64_OPT_EXTENSION("f32mm", AARCH64_FL_F32MM, \ - AARCH64_FL_SVE | AARCH64_FL_F16 | AARCH64_FL_FP | \ - AARCH64_FL_SIMD, 0, false, "f32mm") - -/* Enabling "f64mm" also enables "sve", "fp16", "fp", and "simd". - Disabling "f64mm" only disables "f64mm". */ -AARCH64_OPT_EXTENSION("f64mm", AARCH64_FL_F64MM, \ - AARCH64_FL_SVE | AARCH64_FL_F16 | AARCH64_FL_FP | \ - AARCH64_FL_SIMD, 0, false, "f64mm") - -/* Enabling "bf16" also enables "simd" and "fp". - Disabling "bf16" only disables "bf16". */ -AARCH64_OPT_EXTENSION("bf16", AARCH64_FL_BF16, \ - AARCH64_FL_SIMD | AARCH64_FL_FP, 0, false, "bf16") - -/* Enabling/Disabling "flagm" only changes "flagm". */ -AARCH64_OPT_EXTENSION("flagm", AARCH64_FL_FLAGM, 0, 0, false, "flagm") - -/* Enabling/Disabling "pauth" only changes "pauth". */ -AARCH64_OPT_EXTENSION("pauth", AARCH64_FL_PAUTH, 0, 0, false, "paca pacg") - -/* Enabling/Disabling "ls64" only changes "ls64". */ -AARCH64_OPT_EXTENSION("ls64", AARCH64_FL_LS64, 0, 0, false, "") - -/* Enabling/disabling "mops" only changes "mops". */ -AARCH64_OPT_EXTENSION("mops", AARCH64_FL_MOPS, 0, 0, false, "") +AARCH64_OPT_EXTENSION("sha3", SHA3, (SHA2), (), (), "sha3 sha512") + +AARCH64_OPT_EXTENSION("sm4", SM4, (SIMD), (), (), "sm3 sm4") + +/* An explicit +fp16fml implies +fp16, but a dependence on it does not. + Thus -march=armv8.4-a implies F16FML but not F16. -march=armv8.4-a+fp16 + and -march=armv8.4-a+fp16fml are equivalent and enable both F16FML and F16. + -march=armv8.4-a+nofp16+fp16 enables F16 but not F16FML. */ +AARCH64_OPT_EXTENSION("fp16fml", F16FML, (), (F16), (), "asimdfhm") + +AARCH64_OPT_EXTENSION("sve", SVE, (SIMD, F16), (), (), "sve") + +AARCH64_OPT_EXTENSION("profile", PROFILE, (), (), (), "") + +AARCH64_OPT_EXTENSION("rng", RNG, (), (), (), "rng") + +AARCH64_OPT_EXTENSION("memtag", MEMTAG, (), (), (), "") + +AARCH64_OPT_EXTENSION("sb", SB, (), (), (), "sb") + +AARCH64_OPT_EXTENSION("ssbs", SSBS, (), (), (), "ssbs") + +AARCH64_OPT_EXTENSION("predres", PREDRES, (), (), (), "") + +AARCH64_OPT_EXTENSION("sve2", SVE2, (SVE), (), (), "sve2") + +AARCH64_OPT_EXTENSION("sve2-sm4", SVE2_SM4, (SVE2, SM4), (), (), "svesm4") + +AARCH64_OPT_EXTENSION("sve2-aes", SVE2_AES, (SVE2, AES), (), (), "sveaes") + +AARCH64_OPT_EXTENSION("sve2-sha3", SVE2_SHA3, (SVE2, SHA3), (), (), "svesha3") + +AARCH64_OPT_EXTENSION("sve2-bitperm", SVE2_BITPERM, (SVE2), (), (), + "svebitperm") + +AARCH64_OPT_EXTENSION("tme", TME, (), (), (), "") + +AARCH64_OPT_EXTENSION("i8mm", I8MM, (SIMD), (), (), "i8mm") + +AARCH64_OPT_EXTENSION("f32mm", F32MM, (SVE), (), (), "f32mm") + +AARCH64_OPT_EXTENSION("f64mm", F64MM, (SVE), (), (), "f64mm") + +/* An explicit +bf16 implies +simd, but +bf16+nosimd still enables scalar BF16 + instructions. */ +AARCH64_OPT_EXTENSION("bf16", BF16, (FP), (SIMD), (), "bf16") + +AARCH64_OPT_EXTENSION("flagm", FLAGM, (), (), (), "flagm") + +AARCH64_OPT_EXTENSION("pauth", PAUTH, (), (), (), "paca pacg") + +AARCH64_OPT_EXTENSION("ls64", LS64, (), (), (), "") + +AARCH64_OPT_EXTENSION("mops", MOPS, (), (), (), "") #undef AARCH64_OPT_EXTENSION diff --git a/gcc/config/aarch64/aarch64-opts.h b/gcc/config/aarch64/aarch64-opts.h index 421648a156a..ba23c90c411 100644 --- a/gcc/config/aarch64/aarch64-opts.h +++ b/gcc/config/aarch64/aarch64-opts.h @@ -22,6 +22,10 @@ #ifndef GCC_AARCH64_OPTS_H #define GCC_AARCH64_OPTS_H +#ifndef USED_FOR_TARGET +typedef uint64_t aarch64_feature_flags; +#endif + /* The various cores that implement AArch64. */ enum aarch64_processor { diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc index 12d9beee4da..c06e99339e3 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc @@ -701,9 +701,8 @@ check_required_extensions (location_t location, tree fndecl, return check_required_registers (location, fndecl); static const struct { uint64_t flag; const char *name; } extensions[] = { -#define AARCH64_OPT_EXTENSION(EXT_NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ - SYNTHETIC, FEATURE_STRING) \ - { FLAG_CANONICAL, EXT_NAME }, +#define AARCH64_OPT_EXTENSION(EXT_NAME, IDENT, C, D, E, F) \ + { AARCH64_FL_##IDENT, EXT_NAME }, #include "aarch64-option-extensions.def" }; diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index a5c48514adc..398232433ce 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -81,6 +81,7 @@ #include "rtlanal.h" #include "tree-dfa.h" #include "asan.h" +#include "aarch64-feature-deps.h" /* This file should be included last. */ #include "target-def.h" @@ -2681,8 +2682,9 @@ struct processor /* Architectures implementing AArch64. */ static const struct processor all_architectures[] = { -#define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, ARCH_REV, FLAGS) \ - {NAME, CORE, CORE, AARCH64_ARCH_##ARCH_IDENT, FLAGS, NULL}, +#define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, D, E) \ + {NAME, CORE, CORE, AARCH64_ARCH_##ARCH_IDENT, \ + feature_deps::ARCH_IDENT ().enable, NULL}, #include "aarch64-arches.def" {NULL, aarch64_none, aarch64_none, aarch64_no_arch, 0, NULL} }; @@ -2690,12 +2692,12 @@ static const struct processor all_architectures[] = /* Processor cores implementing AArch64. */ static const struct processor all_cores[] = { -#define AARCH64_CORE(NAME, IDENT, SCHED, ARCH, FLAGS, COSTS, IMP, PART, VARIANT) \ - {NAME, IDENT, SCHED, AARCH64_ARCH_##ARCH, \ - AARCH64_FL_FOR_##ARCH | FLAGS, &COSTS##_tunings}, +#define AARCH64_CORE(NAME, IDENT, SCHED, ARCH, E, COSTS, G, H, I) \ + {NAME, IDENT, SCHED, AARCH64_ARCH_##ARCH, \ + feature_deps::cpu_##IDENT, &COSTS##_tunings}, #include "aarch64-cores.def" {"generic", generic, cortexa53, AARCH64_ARCH_V8A, - AARCH64_FL_FOR_V8A, &generic_tunings}, + feature_deps::V8A ().enable, &generic_tunings}, {NULL, aarch64_none, aarch64_none, aarch64_no_arch, 0, NULL} }; diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 8ea8e2a3913..97da721d094 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -144,149 +144,27 @@ #define PCC_BITFIELD_TYPE_MATTERS 1 -/* Instruction tuning/selection flags. */ - -/* Bit values used to identify processor capabilities. */ -#define AARCH64_FL_SIMD (1 << 0) /* Has SIMD instructions. */ -#define AARCH64_FL_FP (1 << 1) /* Has FP. */ -#define AARCH64_FL_CRYPTO (1 << 2) /* Has crypto. */ -#define AARCH64_FL_CRC (1 << 3) /* Has CRC. */ -/* ARMv8.1-A architecture extensions. */ -#define AARCH64_FL_LSE (1 << 4) /* Has Large System Extensions. */ -#define AARCH64_FL_RDMA (1 << 5) /* Has Round Double Multiply Add. */ -#define AARCH64_FL_V8_1A (1 << 6) /* Has ARMv8.1-A extensions. */ -/* Armv8-R. */ -#define AARCH64_FL_V8R (1 << 7) /* Armv8-R AArch64. */ -/* ARMv8.2-A architecture extensions. */ -#define AARCH64_FL_V8_2A (1 << 8) /* Has ARMv8.2-A features. */ -#define AARCH64_FL_F16 (1 << 9) /* Has ARMv8.2-A FP16 extensions. */ -#define AARCH64_FL_SVE (1 << 10) /* Has Scalable Vector Extensions. */ -/* ARMv8.3-A architecture extensions. */ -#define AARCH64_FL_V8_3A (1 << 11) /* Has ARMv8.3-A features. */ -#define AARCH64_FL_RCPC (1 << 12) /* Has support for RCpc model. */ -#define AARCH64_FL_DOTPROD (1 << 13) /* Has ARMv8.2-A Dot Product ins. */ -/* New flags to split crypto into aes and sha2. */ -#define AARCH64_FL_AES (1 << 14) /* Has Crypto AES. */ -#define AARCH64_FL_SHA2 (1 << 15) /* Has Crypto SHA2. */ -/* ARMv8.4-A architecture extensions. */ -#define AARCH64_FL_V8_4A (1 << 16) /* Has ARMv8.4-A features. */ -#define AARCH64_FL_SM4 (1 << 17) /* Has ARMv8.4-A SM3 and SM4. */ -#define AARCH64_FL_SHA3 (1 << 18) /* Has ARMv8.4-a SHA3 and SHA512. */ -#define AARCH64_FL_F16FML (1 << 19) /* Has ARMv8.4-a FP16 extensions. */ - -/* Statistical Profiling extensions. */ -#define AARCH64_FL_PROFILE (1 << 21) - -/* ARMv8.5-A architecture extensions. */ -#define AARCH64_FL_V8_5A (1 << 22) /* Has ARMv8.5-A features. */ -#define AARCH64_FL_RNG (1 << 23) /* ARMv8.5-A Random Number Insns. */ -#define AARCH64_FL_MEMTAG (1 << 24) /* ARMv8.5-A Memory Tagging - Extensions. */ - -/* Speculation Barrier instruction supported. */ -#define AARCH64_FL_SB (1 << 25) - -/* Speculative Store Bypass Safe instruction supported. */ -#define AARCH64_FL_SSBS (1 << 26) - -/* Execution and Data Prediction Restriction instructions supported. */ -#define AARCH64_FL_PREDRES (1 << 27) - -/* SVE2 instruction supported. */ -#define AARCH64_FL_SVE2 (1 << 28) -#define AARCH64_FL_SVE2_AES (1 << 29) -#define AARCH64_FL_SVE2_SM4 (1 << 30) -#define AARCH64_FL_SVE2_SHA3 (1ULL << 31) -#define AARCH64_FL_SVE2_BITPERM (1ULL << 32) - -/* Transactional Memory Extension. */ -#define AARCH64_FL_TME (1ULL << 33) /* Has TME instructions. */ - -/* Armv8.6-A architecture extensions. */ -#define AARCH64_FL_V8_6A (1ULL << 34) - -/* 8-bit Integer Matrix Multiply (I8MM) extensions. */ -#define AARCH64_FL_I8MM (1ULL << 35) - -/* Brain half-precision floating-point (BFloat16) Extension. */ -#define AARCH64_FL_BF16 (1ULL << 36) - -/* 32-bit Floating-point Matrix Multiply (F32MM) extensions. */ -#define AARCH64_FL_F32MM (1ULL << 37) - -/* 64-bit Floating-point Matrix Multiply (F64MM) extensions. */ -#define AARCH64_FL_F64MM (1ULL << 38) - -/* Flag Manipulation Instructions (FLAGM) extension. */ -#define AARCH64_FL_FLAGM (1ULL << 39) - -/* Pointer Authentication (PAUTH) extension. */ -#define AARCH64_FL_PAUTH (1ULL << 40) - -/* Armv9.0-A. */ -#define AARCH64_FL_V9A (1ULL << 41) /* Armv9.0-A Architecture. */ - -/* 64-byte atomic load/store extensions. */ -#define AARCH64_FL_LS64 (1ULL << 42) - -/* Armv8.7-a architecture extensions. */ -#define AARCH64_FL_V8_7A (1ULL << 43) - -/* Hardware memory operation instructions. */ -#define AARCH64_FL_MOPS (1ULL << 44) - -/* Armv8.8-a architecture extensions. */ -#define AARCH64_FL_V8_8A (1ULL << 45) - -/* Armv9.1-A. */ -#define AARCH64_FL_V9_1A (1ULL << 46) - -/* Armv9.2-A. */ -#define AARCH64_FL_V9_2A (1ULL << 47) - -/* Armv9.3-A. */ -#define AARCH64_FL_V9_3A (1ULL << 48) - -/* Has FP and SIMD. */ -#define AARCH64_FL_FPSIMD (AARCH64_FL_FP | AARCH64_FL_SIMD) - -/* Has FP without SIMD. */ -#define AARCH64_FL_FPQ16 (AARCH64_FL_FP & ~AARCH64_FL_SIMD) - -/* Architecture flags that effect instruction selection. */ -#define AARCH64_FL_FOR_V8A (AARCH64_FL_FPSIMD) -#define AARCH64_FL_FOR_V8_1A \ - (AARCH64_FL_FOR_V8A | AARCH64_FL_LSE | AARCH64_FL_CRC \ - | AARCH64_FL_RDMA | AARCH64_FL_V8_1A) -#define AARCH64_FL_FOR_V8_2A \ - (AARCH64_FL_FOR_V8_1A | AARCH64_FL_V8_2A) -#define AARCH64_FL_FOR_V8_3A \ - (AARCH64_FL_FOR_V8_2A | AARCH64_FL_V8_3A | AARCH64_FL_PAUTH) -#define AARCH64_FL_FOR_V8_4A \ - (AARCH64_FL_FOR_V8_3A | AARCH64_FL_V8_4A | AARCH64_FL_F16FML \ - | AARCH64_FL_DOTPROD | AARCH64_FL_FLAGM) -#define AARCH64_FL_FOR_V8_5A \ - (AARCH64_FL_FOR_V8_4A | AARCH64_FL_V8_5A \ - | AARCH64_FL_SB | AARCH64_FL_SSBS | AARCH64_FL_PREDRES) -#define AARCH64_FL_FOR_V8_6A \ - (AARCH64_FL_FOR_V8_5A | AARCH64_FL_V8_6A | AARCH64_FL_FPSIMD \ - | AARCH64_FL_I8MM | AARCH64_FL_BF16) -#define AARCH64_FL_FOR_V8_7A \ - (AARCH64_FL_FOR_V8_6A | AARCH64_FL_V8_7A | AARCH64_FL_LS64) -#define AARCH64_FL_FOR_V8_8A \ - (AARCH64_FL_FOR_V8_7A | AARCH64_FL_V8_8A | AARCH64_FL_MOPS) - -#define AARCH64_FL_FOR_V8R \ - (AARCH64_FL_FOR_V8_4A | AARCH64_FL_V8R) -#define AARCH64_FL_FOR_V9A \ - (AARCH64_FL_FOR_V8_5A | AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_V9A \ - | AARCH64_FL_F16) -#define AARCH64_FL_FOR_V9_1A \ - (AARCH64_FL_FOR_V9A | AARCH64_FL_FOR_V8_6A | AARCH64_FL_V9_1A) -#define AARCH64_FL_FOR_V9_2A \ - (AARCH64_FL_FOR_V9_1A | AARCH64_FL_FOR_V8_7A | AARCH64_FL_V9_2A) -#define AARCH64_FL_FOR_V9_3A \ - (AARCH64_FL_FOR_V9_2A | AARCH64_FL_FOR_V8_8A | AARCH64_FL_V9_3A) +#ifndef USED_FOR_TARGET + +/* Define an enum of all features (architectures and extensions). */ +enum class aarch64_feature : unsigned char { +#define AARCH64_OPT_EXTENSION(A, IDENT, C, D, E, F) IDENT, +#define AARCH64_ARCH(A, B, IDENT, D, E) IDENT, +#include "aarch64-option-extensions.def" +#include "aarch64-arches.def" +}; + +/* Define unique flags for each of the above. */ +#define HANDLE(IDENT) \ + constexpr auto AARCH64_FL_##IDENT \ + = aarch64_feature_flags (1) << int (aarch64_feature::IDENT); +#define AARCH64_OPT_EXTENSION(A, IDENT, C, D, E, F) HANDLE (IDENT) +#define AARCH64_ARCH(A, B, IDENT, D, E) HANDLE (IDENT) +#include "aarch64-option-extensions.def" +#include "aarch64-arches.def" +#undef HANDLE + +#endif /* Macros to test ISA flags. */ diff --git a/gcc/config/aarch64/driver-aarch64.cc b/gcc/config/aarch64/driver-aarch64.cc index 2d74964ea47..1c86d62ef80 100644 --- a/gcc/config/aarch64/driver-aarch64.cc +++ b/gcc/config/aarch64/driver-aarch64.cc @@ -26,6 +26,7 @@ #include "coretypes.h" #include "tm.h" #include "aarch64-protos.h" +#include "aarch64-feature-deps.h" struct aarch64_arch_extension { @@ -34,9 +35,8 @@ struct aarch64_arch_extension const char *feat_string; }; -#define AARCH64_OPT_EXTENSION(EXT_NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ - SYNTHETIC, FEATURE_STRING) \ - { EXT_NAME, FLAG_CANONICAL, FEATURE_STRING }, +#define AARCH64_OPT_EXTENSION(EXT_NAME, IDENT, C, D, E, FEATURE_STRING) \ + { EXT_NAME, AARCH64_FL_##IDENT, FEATURE_STRING }, static struct aarch64_arch_extension aarch64_extensions[] = { #include "aarch64-option-extensions.def" @@ -62,7 +62,7 @@ struct aarch64_core_data #define DEFAULT_ARCH "8A" #define AARCH64_CORE(CORE_NAME, CORE_IDENT, SCHED, ARCH, FLAGS, COSTS, IMP, PART, VARIANT) \ - { CORE_NAME, #ARCH, IMP, PART, VARIANT, AARCH64_FL_FOR_##ARCH | FLAGS }, + { CORE_NAME, #ARCH, IMP, PART, VARIANT, feature_deps::cpu_##CORE_IDENT }, static struct aarch64_core_data aarch64_cpu_data[] = { @@ -80,7 +80,7 @@ struct aarch64_arch_driver_info /* Skip the leading "V" in the architecture name. */ #define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, ARCH_REV, FLAGS) \ - { #ARCH_IDENT + 1, NAME, FLAGS }, + { #ARCH_IDENT + 1, NAME, feature_deps::ARCH_IDENT ().enable }, static struct aarch64_arch_driver_info aarch64_arches[] = {