aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Carlotti <andrew.carlotti@arm.com>2024-06-21 19:31:06 +0100
committerRichard Earnshaw <rearnsha@arm.com>2024-06-24 16:49:52 +0100
commit05f15256d0274b8321eec4cad4273340e1a8521f (patch)
tree45bd97b8599086fa059ff2ee7e6bf79e97a7b4ff
parent92d37320d5f75804006abfb28e006ccbc24f8f52 (diff)
downloadbinutils-05f15256d0274b8321eec4cad4273340e1a8521f.zip
binutils-05f15256d0274b8321eec4cad4273340e1a8521f.tar.gz
binutils-05f15256d0274b8321eec4cad4273340e1a8521f.tar.bz2
aarch64: Add support for virtual features
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.
-rw-r--r--gas/config/tc-aarch64.c64
1 files changed, 45 insertions, 19 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 1717ca7..2bd87d1 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -10684,6 +10684,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)
@@ -10722,16 +10748,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)
{
@@ -10811,6 +10844,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;
}
@@ -10836,10 +10870,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);
@@ -10868,10 +10899,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);
@@ -11057,9 +11085,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;
@@ -11102,9 +11129,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;