diff options
author | Jan Beulich <jbeulich@novell.com> | 2014-11-18 14:08:28 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2014-11-18 14:08:28 +0100 |
commit | ae527cd876fe35de72d876d3484e194ccc66232f (patch) | |
tree | 506c344ade8b18b6a142c10931eb4644b4a7e3b2 /gas/config/tc-aarch64.c | |
parent | 0a9ce86dafbd889ab3dfc8f61db364a2426be99b (diff) | |
download | gdb-ae527cd876fe35de72d876d3484e194ccc66232f.zip gdb-ae527cd876fe35de72d876d3484e194ccc66232f.tar.gz gdb-ae527cd876fe35de72d876d3484e194ccc66232f.tar.bz2 |
aarch64: allow adding/removing just feature flags via .arch_extension
Rather than requiring to always also set/change the base architecture,
allow just en-/disabling of architecture extensions, matching what ARM
has.
Diffstat (limited to 'gas/config/tc-aarch64.c')
-rw-r--r-- | gas/config/tc-aarch64.c | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 7f22ba4..8cecfd0 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -1917,6 +1917,7 @@ s_tlsdesccall (int ignored ATTRIBUTE_UNUSED) static void s_aarch64_arch (int); static void s_aarch64_cpu (int); +static void s_aarch64_arch_extension (int); /* This table describes all the machine specific pseudo-ops the assembler has to support. The fields are: @@ -1934,6 +1935,7 @@ const pseudo_typeS md_pseudo_table[] = { {"pool", s_ltorg, 0}, {"cpu", s_aarch64_cpu, 0}, {"arch", s_aarch64_arch, 0}, + {"arch_extension", s_aarch64_arch_extension, 0}, {"inst", s_aarch64_inst, 0}, #ifdef OBJ_ELF {"tlsdesccall", s_tlsdesccall, 0}, @@ -7238,7 +7240,8 @@ struct aarch64_long_option_table }; static int -aarch64_parse_features (char *str, const aarch64_feature_set **opt_p) +aarch64_parse_features (char *str, const aarch64_feature_set **opt_p, + bfd_boolean ext_only) { /* We insist on extensions being added before being removed. We achieve this by using the ADDING_VALUE variable to indicate whether we are @@ -7254,17 +7257,19 @@ aarch64_parse_features (char *str, const aarch64_feature_set **opt_p) while (str != NULL && *str != 0) { const struct aarch64_option_cpu_value_table *opt; - char *ext; + char *ext = NULL; int optlen; - if (*str != '+') + if (!ext_only) { - as_bad (_("invalid architectural extension")); - return 0; - } + if (*str != '+') + { + as_bad (_("invalid architectural extension")); + return 0; + } - str++; - ext = strchr (str, '+'); + ext = strchr (++str, '+'); + } if (ext != NULL) optlen = ext - str; @@ -7344,7 +7349,7 @@ aarch64_parse_cpu (char *str) { mcpu_cpu_opt = &opt->value; if (ext != NULL) - return aarch64_parse_features (ext, &mcpu_cpu_opt); + return aarch64_parse_features (ext, &mcpu_cpu_opt, FALSE); return 1; } @@ -7376,7 +7381,7 @@ aarch64_parse_arch (char *str) { march_cpu_opt = &opt->value; if (ext != NULL) - return aarch64_parse_features (ext, &march_cpu_opt); + return aarch64_parse_features (ext, &march_cpu_opt, FALSE); return 1; } @@ -7559,7 +7564,7 @@ s_aarch64_cpu (int ignored ATTRIBUTE_UNUSED) { mcpu_cpu_opt = &opt->value; if (ext != NULL) - if (!aarch64_parse_features (ext, &mcpu_cpu_opt)) + if (!aarch64_parse_features (ext, &mcpu_cpu_opt, FALSE)) return; cpu_variant = *mcpu_cpu_opt; @@ -7605,7 +7610,7 @@ s_aarch64_arch (int ignored ATTRIBUTE_UNUSED) { mcpu_cpu_opt = &opt->value; if (ext != NULL) - if (!aarch64_parse_features (ext, &mcpu_cpu_opt)) + if (!aarch64_parse_features (ext, &mcpu_cpu_opt, FALSE)) return; cpu_variant = *mcpu_cpu_opt; @@ -7620,6 +7625,28 @@ s_aarch64_arch (int ignored ATTRIBUTE_UNUSED) ignore_rest_of_line (); } +/* Parse a .arch_extension directive. */ + +static void +s_aarch64_arch_extension (int ignored ATTRIBUTE_UNUSED) +{ + char saved_char; + char *ext = input_line_pointer;; + + while (*input_line_pointer && !ISSPACE (*input_line_pointer)) + input_line_pointer++; + saved_char = *input_line_pointer; + *input_line_pointer = 0; + + if (!aarch64_parse_features (ext, &mcpu_cpu_opt, TRUE)) + return; + + cpu_variant = *mcpu_cpu_opt; + + *input_line_pointer = saved_char; + demand_empty_rest_of_line (); +} + /* Copy symbol information. */ void |