Adds the AARCH64_OPT_EXTENSION_ALIAS macro to aarch64-option-extensions.def
to define architecture features which gate no features themselves, but
act as aliases for other features.
When getting the extension string for some architecture flags, alias features
should be used over their constituent features, even if some of the constituent
features are enabled transitively by other features.
Changes +crypto option to use this macro.
gcc/ChangeLog:
* common/config/aarch64/aarch64-common.cc
(struct aarch64_extension_info): Add flags_alias_preferred_over.
(AARCH64_OPT_EXTENSION): Add setting flags preferred over to 0.
(AARCH64_OPT_EXTENSION_ALIAS): New macro def.
(aarch64_get_extension_string_for_isa_flags): Update to use alias
extensions over constituent extensions.
* config/aarch64/aarch64-feature-deps.h (alias_flags): New variable
(AARCH64_OPT_EXTENSION): New macro def.
(AARCH64_OPT_EXTENSION_ALIAS): New macro def.
(HANDLE): Update to use alias_flags.
(AARCH64_CORE): Update to use alias_flags.
* config/aarch64/aarch64-option-extensions.def
(AARCH64_OPT_EXTENSION_ALIAS): New macro def to
define alias_prefer_over_flags_X.
(crypto): Update to us AARCH64_OPT_EXTENSION_ALIAS.
* config/aarch64/aarch64.h: Undef macros after use.
---
gcc/common/config/aarch64/aarch64-common.cc | 91 ++++++++++++-------
gcc/config/aarch64/aarch64-feature-deps.h | 30 +++++-
.../aarch64/aarch64-option-extensions.def | 21 ++++-
gcc/config/aarch64/aarch64.h | 2 +
4 files changed, 103 insertions(+), 41 deletions(-)
diff --git a/gcc/common/config/aarch64/aarch64-common.cc
b/gcc/common/config/aarch64/aarch64-common.cc
index 1488697c6ce..b4efd887eae 100644
--- a/gcc/common/config/aarch64/aarch64-common.cc
+++ b/gcc/common/config/aarch64/aarch64-common.cc
@@ -165,6 +165,10 @@ struct aarch64_extension_info
aarch64_feature_flags flags_off;
/* If this feature remains enabled, these bits must also remain enabled. */
aarch64_feature_flags flags_required;
+ /* If this is not an alias extension, then this is zero.
+ Otherwise, this is the set of feature bits this alias is preferred
+ over. */
+ aarch64_feature_flags flags_alias_preferred_over;
};
/* ISA extensions in AArch64. */
@@ -173,9 +177,14 @@ static constexpr aarch64_extension_info all_extensions[] =
#define AARCH64_OPT_EXTENSION(NAME, IDENT, C, D, E, FEATURE_STRING) \
{NAME, AARCH64_FL_##IDENT, feature_deps::IDENT ().explicit_on, \
feature_deps::get_flags_off (feature_deps::root_off_##IDENT), \
- feature_deps::IDENT ().enable},
+ feature_deps::IDENT ().enable, 0},
+#define AARCH64_OPT_EXTENSION_ALIAS(NAME, IDENT, C, D, E, FEATURE_STRING, G) \
+ {NAME, AARCH64_FL_##IDENT, feature_deps::IDENT ().explicit_on, \
+ feature_deps::get_flags_off (feature_deps::root_off_##IDENT), \
+ feature_deps::IDENT ().enable, \
+ feature_deps::alias_prefer_over_flags_##IDENT},
#include "config/aarch64/aarch64-option-extensions.def"
- {NULL, 0, 0, 0, 0}
+ {NULL, 0, 0, 0, 0, 0}
};
struct aarch64_arch_info
@@ -634,10 +643,10 @@ aarch64_get_extension_string_for_isa_flags
{
std::string outstr = "";
- /* The CRYPTO bit should only be used to support the +crypto alias
+ /* The alias bits should only be used to support the aliases
during option processing, and should be cleared at all other times.
Verify this property for the supplied flags bitmask. */
- gcc_assert (!(AARCH64_FL_CRYPTO & aarch64_isa_flags));
+ gcc_assert (!(feature_deps::alias_flags & aarch64_isa_flags));
aarch64_feature_flags current_flags = default_arch_flags;
/* As a special case, do not assume that the assembler will enable CRC
@@ -657,24 +666,30 @@ aarch64_get_extension_string_for_isa_flags
But in order to make the output more readable, it seems better
to add the strings in definition order. */
aarch64_feature_flags added = 0;
- auto flags_crypto = AARCH64_FL_AES | AARCH64_FL_SHA2;
for (unsigned int i = ARRAY_SIZE (all_extensions); i-- > 0; )
{
auto &opt = all_extensions[i];
- /* As a special case, emit +crypto rather than +aes+sha2,
- in order to support assemblers that predate the separate
- per-feature crypto flags. */
- auto flags = opt.flag_canonical;
- if (flags == AARCH64_FL_CRYPTO)
- flags = flags_crypto;
-
- if ((flags & isa_flags & (explicit_flags | ~current_flags)) == flags)
+ if (!opt.flags_alias_preferred_over
+ && (opt.flag_canonical & isa_flags
+ & (explicit_flags | ~current_flags)) == opt.flag_canonical)
{
current_flags |= opt.flags_on;
added |= opt.flag_canonical;
}
}
+
+ /* Replace any aliased extensions. */
+ for (auto alias: all_extensions)
+ if (alias.flags_alias_preferred_over
+ && (added & alias.flags_alias_preferred_over)
+ == alias.flags_alias_preferred_over
+ && (alias.flags_on | isa_flags) == isa_flags)
+ {
+ added &= ~alias.flags_on;
+ added |= alias.flag_canonical;
+ }
+
for (auto &opt : all_extensions)
if (added & opt.flag_canonical)
{
@@ -687,31 +702,43 @@ aarch64_get_extension_string_for_isa_flags
detection because one way or another we can't tell if it's available
or not. */
+ aarch64_feature_flags removed = 0;
for (auto &opt : all_extensions)
+ if (!opt.flags_alias_preferred_over
+ && (opt.flag_canonical & current_flags & ~isa_flags))
+ {
+ current_flags &= ~opt.flags_off;
+ removed |= opt.flag_canonical;
+ }
+
+ /* Replace any aliased extensions. */
+ for (auto alias: all_extensions)
{
- auto flags = opt.flag_canonical;
- /* As a special case, don't emit "+noaes" or "+nosha2" when we could emit
- "+nocrypto" instead, in order to support assemblers that predate the
- separate per-feature crypto flags. Only allow "+nocrypto" when "sm4"
- is not already enabled (to avoid dependending on whether "+nocrypto"
- also disables "sm4"). */
- if (flags & flags_crypto
- && (flags_crypto & current_flags & ~isa_flags) == flags_crypto
- && !(current_flags & AARCH64_FL_SM4))
- continue;
-
- if (flags == AARCH64_FL_CRYPTO)
- /* If either crypto flag needs removing here, then both do. */
- flags = flags_crypto;
-
- if (flags & current_flags & ~isa_flags)
+ /* Only allow "+nocrypto" when "sm4" is not already enabled
+ (to avoid dependending on whether "+nocrypto" also disables "sm4"). */
+ if (alias.flag_canonical == AARCH64_FL_CRYPTO
+ && (current_flags & AARCH64_FL_SM4))
+ continue;
+
+ if (alias.flags_alias_preferred_over /* Check this is an alias. */
+ /* Check we turn off any of the extensions for which we would prefer
+ to use the alias. */
+ && (removed & alias.flags_alias_preferred_over)
+ /* Check this doesn't turn off more flags than we need. */
+ && (alias.flags_off & isa_flags) == 0)
{
- current_flags &= ~opt.flags_off;
- outstr += "+no";
- outstr += opt.name;
+ removed &= ~alias.flags_off;
+ removed |= alias.flag_canonical;
}
}
+ for (auto &opt : all_extensions)
+ if (removed & opt.flag_canonical)
+ {
+ outstr += "+no";
+ outstr += opt.name;
+ }
+
return outstr;
}
diff --git a/gcc/config/aarch64/aarch64-feature-deps.h
b/gcc/config/aarch64/aarch64-feature-deps.h
index 55a0dbfae61..796043087db 100644
--- a/gcc/config/aarch64/aarch64-feature-deps.h
+++ b/gcc/config/aarch64/aarch64-feature-deps.h
@@ -66,12 +66,20 @@ get_enable (T1 i, Ts... args)
files are in topological order. */
template<aarch64_feature> struct info;
+ constexpr auto alias_flags = aarch64_feature_flags (0)
+#define AARCH64_OPT_EXTENSION_ALIAS(A, IDENT, C, D, E, F, G) |
AARCH64_FL_##IDENT
+#define AARCH64_OPT_EXTENSION(A, IDENT, C, D, E, F)
+#include "config/aarch64/aarch64-option-extensions.def"
+;
+#undef AARCH64_OPT_EXTENSION_ALIAS
+#undef AARCH64_OPT_EXTENSION
+
#define HANDLE(IDENT, REQUIRES, EXPLICIT_ON) \
template<> struct info<aarch64_feature::IDENT> { \
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) & ~AARCH64_FL_CRYPTO; \
+ static constexpr auto explicit_on \
+ = (enable | get_enable EXPLICIT_ON) & ~alias_flags; \
}; \
constexpr aarch64_feature_flags info<aarch64_feature::IDENT>::flag; \
constexpr aarch64_feature_flags info<aarch64_feature::IDENT>::enable;
\
@@ -86,6 +94,7 @@ template<aarch64_feature> struct info;
#include "config/aarch64/aarch64-option-extensions.def"
#include "config/aarch64/aarch64-arches.def"
#undef HANDLE
+#undef AARCH64_OPT_EXTENSION
/* Return the set of all features that would need to be disabled if
the features in MASK are disabled.
@@ -106,6 +115,7 @@ get_flags_off (aarch64_feature_flags mask)
#include "config/aarch64/aarch64-option-extensions.def"
);
}
+#undef AARCH64_OPT_EXTENSION
/* Define root_off_<IDENT> variables for each feature, giving the set of
features that must be turned off by +noIDENT. This set is not transitively
@@ -114,13 +124,14 @@ get_flags_off (aarch64_feature_flags mask)
constexpr auto root_off_##IDENT \
= AARCH64_FL_##IDENT | get_flags EXPLICIT_OFF;
#include "config/aarch64/aarch64-option-extensions.def"
+#undef AARCH64_OPT_EXTENSION
/* Define cpu_<NAME> variables for each CPU, giving the transitive
- closure of all the features that the CPU supports. The CRYPTO bit is just
- an alias, so explicitly unset it for consistency. */
+ closure of all the features that the CPU supports. The alias flags are
+ explicitly unset for consistency. */
#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) & ~AARCH64_FL_CRYPTO;
+ = (ARCH_IDENT ().enable | get_enable FEATURES) & ~alias_flags;
#include "config/aarch64/aarch64-cores.def"
/* Define fmv_deps_<NAME> variables for each FMV feature, giving the transitive
@@ -128,8 +139,17 @@ get_flags_off (aarch64_feature_flags mask)
#define AARCH64_FMV_FEATURE(A, FEAT_NAME, OPT_FLAGS) \
constexpr auto fmv_deps_##FEAT_NAME = get_enable OPT_FLAGS;
#include "config/aarch64/aarch64-option-extensions.def"
+#undef AARCH64_FMV_FEATURE
+#define AARCH64_OPT_EXTENSION_ALIAS(A, IDENT, OPT_FLAGS, D, E, \
+ PREFER_FLAGS, G) \
+ constexpr auto alias_prefer_over_flags_##IDENT = get_flags PREFER_FLAGS;
+#define AARCH64_OPT_EXTENSION(A, IDENT, C, D, E, F)
+#include "config/aarch64/aarch64-option-extensions.def"
+;
+#undef AARCH64_OPT_EXTENSION_ALIAS
+#undef AARCH64_OPT_EXTENSION
}
}
diff --git a/gcc/config/aarch64/aarch64-option-extensions.def
b/gcc/config/aarch64/aarch64-option-extensions.def
index 083515d890d..9d1d7166b17 100644
--- a/gcc/config/aarch64/aarch64-option-extensions.def
+++ b/gcc/config/aarch64/aarch64-option-extensions.def
@@ -25,6 +25,9 @@
AARCH64_OPT_EXTENSION(NAME, IDENT, REQUIRES, EXPLICIT_ON,
EXPLICIT_OFF, FEATURE_STRING)
+ AARCH64_OPT_EXTENSION_ALIAS(NAME, IDENT, REQUIRES, EXPLICIT_ON,
+ EXPLICIT_OFF, PREFER_OVER, FEATURE_STRING)
+
AARCH64_FMV_FEATURE(NAME, FEAT_NAME, IDENT)
- NAME is the name of the extension, represented as a string constant.
@@ -66,6 +69,10 @@
- OPT_FLAGS is a list of feature IDENTS that should be enabled (along with
their transitive dependencies) when the specified FMV feature is present.
+ - PREFER_OVER is a list of features that need to be present when emitting
+ the list of architecture feature options for the alias option to be
+ preferred instead.
+
Where a feature is present as both an extension and a function
multiversioning feature, and IDENT matches the FEAT_NAME suffix, then these
can be listed here simultaneously using the macro:
@@ -88,6 +95,13 @@
EXPLICIT_OFF, FEATURE_STRING)
#endif
+#ifndef AARCH64_OPT_EXTENSION_ALIAS
+#define AARCH64_OPT_EXTENSION_ALIAS(NAME, IDENT, REQUIRES, EXPLICIT_ON, \
+ EXPLICIT_OFF, PREFERRED_OVER,
FEATURE_STRING) \
+AARCH64_OPT_EXTENSION(NAME, IDENT, REQUIRES, EXPLICIT_ON, EXPLICIT_OFF, \
+ FEATURE_STRING)
+#endif
+
#ifndef AARCH64_FMV_FEATURE
#define AARCH64_FMV_FEATURE(NAME, FEAT_NAME, OPT_FLAGS)
#endif
@@ -134,11 +148,9 @@ AARCH64_FMV_FEATURE("aes", PMULL, (AES))
/* +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")
+AARCH64_OPT_EXTENSION_ALIAS("crypto", CRYPTO, (AES, SHA2), (), (AES, SHA2,
SM4),
+ (AES, SHA2), "aes pmull sha1 sha2")
-/* Listing sha3 after crypto means we pass "+aes+sha3" to the assembler
- instead of "+sha3+crypto". */
AARCH64_OPT_EXTENSION("sha3", SHA3, (SHA2), (), (), "sha3 sha512")
/* +nofp16 disables an implicit F16FML, even though an implicit F16FML
@@ -291,4 +303,5 @@ AARCH64_OPT_EXTENSION("cpa", CPA, (), (), (), "")
#undef AARCH64_OPT_FMV_EXTENSION
#undef AARCH64_OPT_EXTENSION
+#undef AARCH64_OPT_EXTENSION_ALIAS
#undef AARCH64_FMV_FEATURE
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 5a1d5a94670..8c3cb60d94b 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -179,6 +179,8 @@ enum class aarch64_feature : unsigned char {
#include "aarch64-option-extensions.def"
#include "aarch64-arches.def"
#undef HANDLE
+#undef AARCH64_OPT_EXTENSION
+#undef AARCH64_ARCH
/* Define aarch64_isa_mode masks. */
#define DEF_AARCH64_ISA_MODE(IDENT) \
--
2.34.1