{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)
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)
{
str = ext;
};
+ *ext_set = aarch64_update_virtual_dependencies (*ext_set);
return 1;
}
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);
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);
&& 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;
&& 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;