[PATCH v2 2/6] aarch64: Add support for virtual features
Andrew Carlotti
andrew.carlotti@arm.com
Fri Jun 21 18:31:06 GMT 2024
These features will be used to gate instructions that can be enabled by
either of two (or more) different sets of command line feature flags.
This patch add a postprocessing step to the feature parsing code to
set the value of the virtual bits.
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index d1ed3c930dc8902c4a4e0f9f86e837d50d971a3c..473097d701f249f4f27df017f0481b858555b5f3 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -10600,6 +10600,32 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = {
{NULL, AARCH64_NO_FEATURES, AARCH64_NO_FEATURES},
};
+/* If all features in the TEST feature set are present, then every virtual
+ feature in the ENABLES feature set should also be enabled. */
+struct aarch64_virtual_dependency_table
+{
+ const aarch64_feature_set test;
+ const aarch64_feature_set enables;
+};
+
+static const struct aarch64_virtual_dependency_table aarch64_dependencies[] = {
+ {AARCH64_NO_FEATURES, AARCH64_NO_FEATURES}
+};
+
+static aarch64_feature_set
+aarch64_update_virtual_dependencies (aarch64_feature_set set)
+{
+ unsigned int i;
+ for (i = 0; i < ARRAY_SIZE (aarch64_dependencies); i++)
+ AARCH64_CLEAR_FEATURES (set, set, aarch64_dependencies[i].enables);
+
+ for (i = 0; i < ARRAY_SIZE (aarch64_dependencies); i++)
+ if (AARCH64_CPU_HAS_ALL_FEATURES (set, aarch64_dependencies[i].test))
+ AARCH64_MERGE_FEATURE_SETS (set, set, aarch64_dependencies[i].enables);
+
+ return set;
+}
+
/* Transitive closure of features depending on set. */
static aarch64_feature_set
aarch64_feature_disable_set (aarch64_feature_set set)
@@ -10638,16 +10664,23 @@ static int
aarch64_parse_features (const char *str, const aarch64_feature_set **opt_p,
bool ext_only)
{
+ /* Copy the feature set, so that we can modify it. */
+ aarch64_feature_set *ext_set = XNEW (aarch64_feature_set);
+ *ext_set = **opt_p;
+ *opt_p = ext_set;
+
+ if (str == NULL)
+ {
+ /* No extensions, so just set the virtual feature bits and return. */
+ *ext_set = aarch64_update_virtual_dependencies (*ext_set);
+ return 1;
+ }
+
/* We insist on extensions being added before being removed. We achieve
this by using the ADDING_VALUE variable to indicate whether we are
adding an extension (1) or removing it (0) and only allowing it to
change in the order -1 -> 1 -> 0. */
int adding_value = -1;
- aarch64_feature_set *ext_set = XNEW (aarch64_feature_set);
-
- /* Copy the feature set, so that we can modify it. */
- *ext_set = **opt_p;
- *opt_p = ext_set;
while (str != NULL && *str != 0)
{
@@ -10727,6 +10760,7 @@ aarch64_parse_features (const char *str, const aarch64_feature_set **opt_p,
str = ext;
};
+ *ext_set = aarch64_update_virtual_dependencies (*ext_set);
return 1;
}
@@ -10752,10 +10786,7 @@ aarch64_parse_cpu (const char *str)
if (strlen (opt->name) == optlen && strncmp (str, opt->name, optlen) == 0)
{
mcpu_cpu_opt = &opt->value;
- if (ext != NULL)
- return aarch64_parse_features (ext, &mcpu_cpu_opt, false);
-
- return 1;
+ return aarch64_parse_features (ext, &mcpu_cpu_opt, false);
}
as_bad (_("unknown cpu `%s'"), str);
@@ -10784,10 +10815,7 @@ aarch64_parse_arch (const char *str)
if (strlen (opt->name) == optlen && strncmp (str, opt->name, optlen) == 0)
{
march_cpu_opt = &opt->value;
- if (ext != NULL)
- return aarch64_parse_features (ext, &march_cpu_opt, false);
-
- return 1;
+ return aarch64_parse_features (ext, &march_cpu_opt, false);
}
as_bad (_("unknown architecture `%s'\n"), str);
@@ -10973,9 +11001,8 @@ s_aarch64_cpu (int ignored ATTRIBUTE_UNUSED)
&& strncmp (name, opt->name, optlen) == 0)
{
mcpu_cpu_opt = &opt->value;
- if (ext != NULL)
- if (!aarch64_parse_features (ext, &mcpu_cpu_opt, false))
- return;
+ if (!aarch64_parse_features (ext, &mcpu_cpu_opt, false))
+ return;
cpu_variant = *mcpu_cpu_opt;
@@ -11018,9 +11045,8 @@ s_aarch64_arch (int ignored ATTRIBUTE_UNUSED)
&& strncmp (name, opt->name, optlen) == 0)
{
mcpu_cpu_opt = &opt->value;
- if (ext != NULL)
- if (!aarch64_parse_features (ext, &mcpu_cpu_opt, false))
- return;
+ if (!aarch64_parse_features (ext, &mcpu_cpu_opt, false))
+ return;
cpu_variant = *mcpu_cpu_opt;
More information about the Binutils
mailing list