diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 31 | ||||
-rw-r--r-- | gas/config/tc-arm.c | 95 | ||||
-rw-r--r-- | gas/config/tc-arm.h | 4 |
3 files changed, 101 insertions, 29 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index d85e1d4..462c921 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,36 @@ 2017-06-21 Thomas Preud'homme <thomas.preudhomme@arm.com> + * config/tc-arm.c (dyn_mcpu_ext_opt): New static variable. + (dyn_march_ext_opt): Likewise. + (md_begin): Copy extension feature bits alongside architecture ones. + Merge extensions feature bits in selected_cpu and cpu_variant if there + is some. + (arm_parse_extension): Pass architecture and extension feature bits in + separate parameters, with architecture bits being read only. Update + **opt_p directly rather than *ext_set and initialize it if needed. + (arm_parse_cpu): Stop merging architecture and extension feature bits + and instead use mcpu_cpu_opt and dyn_mcpu_ext_opt to memorize them + respectively. Adapt to change in parameters of arm_parse_extension. + (arm_parse_arch): Adapt to change in parameters of arm_parse_extension. + (aeabi_set_attribute_string): Make function static. + (arm_md_post_relax): New function. + (s_arm_cpu): Stop merging architecture and extension feature bits and + instead use mcpu_cpu_opt and dyn_mcpu_ext_opt to memorize them + respectively. Merge extension feature bits in cpu_variant + if there is any. + (s_arm_arch): Reset extension feature bit. Set selected_cpu from + *mcpu_cpu_opt and cpu_variant from selected_cpu and *mfpu_opt for + consistency with s_arm_cpu. + (s_arm_arch_extension): Update *dyn_mcpu_ext_opt rather than + selected_cpu, allocating it before hand if needed. Set selected_cpu + from it and then cpu_variant. + (s_arm_fpu): Merge *mcpu_ext_opt feature bits if any in cpu_variant. + * config/tc-arm.h (md_post_relax_hook): Set to arm_md_post_relax. + (aeabi_set_public_attributes): Delete external declaration. + (arm_md_post_relax): Declare externally. + +2017-06-21 Thomas Preud'homme <thomas.preudhomme@arm.com> + * config/tc-arm.c (struct arm_cpu_option_table): New ext field. (ARM_CPU_OPT): Add parameter to set new ext field and reorder canonical name field just after the name field. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index ca458d4..2be50f5 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -147,8 +147,10 @@ static const arm_feature_set *legacy_cpu = NULL; static const arm_feature_set *legacy_fpu = NULL; static const arm_feature_set *mcpu_cpu_opt = NULL; +static arm_feature_set *dyn_mcpu_ext_opt = NULL; static const arm_feature_set *mcpu_fpu_opt = NULL; static const arm_feature_set *march_cpu_opt = NULL; +static arm_feature_set *dyn_march_ext_opt = NULL; static const arm_feature_set *march_fpu_opt = NULL; static const arm_feature_set *mfpu_opt = NULL; static const arm_feature_set *object_arch = NULL; @@ -25033,7 +25035,12 @@ md_begin (void) mcpu_cpu_opt = legacy_cpu; } else if (!mcpu_cpu_opt) - mcpu_cpu_opt = march_cpu_opt; + { + mcpu_cpu_opt = march_cpu_opt; + dyn_mcpu_ext_opt = dyn_march_ext_opt; + /* Avoid double free in arm_md_end. */ + dyn_march_ext_opt = NULL; + } if (legacy_fpu) { @@ -25073,16 +25080,22 @@ md_begin (void) mcpu_cpu_opt = &cpu_default; selected_cpu = cpu_default; } + else if (dyn_mcpu_ext_opt) + ARM_MERGE_FEATURE_SETS (selected_cpu, *mcpu_cpu_opt, *dyn_mcpu_ext_opt); else selected_cpu = *mcpu_cpu_opt; #else - if (mcpu_cpu_opt) + if (mcpu_cpu_opt && dyn_mcpu_ext_opt) + ARM_MERGE_FEATURE_SETS (selected_cpu, *mcpu_cpu_opt, *dyn_mcpu_ext_opt); + else if (mcpu_cpu_opt) selected_cpu = *mcpu_cpu_opt; else mcpu_cpu_opt = &arm_arch_any; #endif ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt); + if (dyn_mcpu_ext_opt) + ARM_MERGE_FEATURE_SETS (cpu_variant, cpu_variant, *dyn_mcpu_ext_opt); autoselect_thumb_from_cpu_variant (); @@ -26081,10 +26094,9 @@ struct arm_long_option_table }; static bfd_boolean -arm_parse_extension (const char *str, const arm_feature_set **opt_p) +arm_parse_extension (const char *str, const arm_feature_set *opt_set, + arm_feature_set **ext_set_p) { - arm_feature_set *ext_set = XNEW (arm_feature_set); - /* We insist on extensions being specified in alphabetical order, and with extensions being added before being removed. We achieve this by having the global ARM_EXTENSIONS table in alphabetical order, and using the @@ -26095,9 +26107,11 @@ arm_parse_extension (const char *str, const arm_feature_set **opt_p) const arm_feature_set arm_any = ARM_ANY; int adding_value = -1; - /* Copy the feature set, so that we can modify it. */ - *ext_set = **opt_p; - *opt_p = ext_set; + if (!*ext_set_p) + { + *ext_set_p = XNEW (arm_feature_set); + **ext_set_p = arm_arch_none; + } while (str != NULL && *str != 0) { @@ -26165,7 +26179,7 @@ arm_parse_extension (const char *str, const arm_feature_set **opt_p) /* Empty entry. */ if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any)) continue; - if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *ext_set)) + if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *opt_set)) break; } if (i == nb_allowed_archs) @@ -26176,9 +26190,10 @@ arm_parse_extension (const char *str, const arm_feature_set **opt_p) /* Add or remove the extension. */ if (adding_value) - ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->merge_value); + ARM_MERGE_FEATURE_SETS (**ext_set_p, **ext_set_p, + opt->merge_value); else - ARM_CLEAR_FEATURE (*ext_set, *ext_set, opt->clear_value); + ARM_CLEAR_FEATURE (**ext_set_p, **ext_set_p, opt->clear_value); break; } @@ -26234,9 +26249,10 @@ arm_parse_cpu (const char *str) for (opt = arm_cpus; opt->name != NULL; opt++) if (opt->name_len == len && strncmp (opt->name, str, len) == 0) { - arm_feature_set *cpu_set = XNEW (arm_feature_set); - ARM_MERGE_FEATURE_SETS (*cpu_set, opt->value, opt->ext); - mcpu_cpu_opt = cpu_set; + mcpu_cpu_opt = &opt->value; + if (!dyn_mcpu_ext_opt) + dyn_mcpu_ext_opt = XNEW (arm_feature_set); + *dyn_mcpu_ext_opt = opt->ext; mcpu_fpu_opt = &opt->default_fpu; if (opt->canonical_name) { @@ -26256,7 +26272,7 @@ arm_parse_cpu (const char *str) } if (ext != NULL) - return arm_parse_extension (ext, &mcpu_cpu_opt); + return arm_parse_extension (ext, mcpu_cpu_opt, &dyn_mcpu_ext_opt); return TRUE; } @@ -26291,7 +26307,7 @@ arm_parse_arch (const char *str) strcpy (selected_cpu_name, opt->name); if (ext != NULL) - return arm_parse_extension (ext, &march_cpu_opt); + return arm_parse_extension (ext, march_cpu_opt, &dyn_march_ext_opt); return TRUE; } @@ -26577,7 +26593,7 @@ aeabi_set_attribute_string (int tag, const char *value) } /* Set the public EABI object attributes. */ -void +static void aeabi_set_public_attributes (void) { int arch; @@ -26824,6 +26840,18 @@ aeabi_set_public_attributes (void) aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec); } +/* Post relaxation hook. Recompute ARM attributes now that relaxation is + finished and free extension feature bits which will not be used anymore. */ +void +arm_md_post_relax (void) +{ + aeabi_set_public_attributes (); + XDELETE (dyn_mcpu_ext_opt); + dyn_mcpu_ext_opt = NULL; + XDELETE (dyn_march_ext_opt); + dyn_march_ext_opt = NULL; +} + /* Add the default contents for the .ARM.attributes section. */ void arm_md_end (void) @@ -26855,10 +26883,11 @@ s_arm_cpu (int ignored ATTRIBUTE_UNUSED) for (opt = arm_cpus + 1; opt->name != NULL; opt++) if (streq (opt->name, name)) { - arm_feature_set *cpu_set = XNEW (arm_feature_set); - ARM_MERGE_FEATURE_SETS (*cpu_set, opt->value, opt->ext); - mcpu_cpu_opt = cpu_set; - selected_cpu = *mcpu_cpu_opt; + mcpu_cpu_opt = &opt->value; + if (!dyn_mcpu_ext_opt) + dyn_mcpu_ext_opt = XNEW (arm_feature_set); + *dyn_mcpu_ext_opt = opt->ext; + ARM_MERGE_FEATURE_SETS (selected_cpu, *mcpu_cpu_opt, *dyn_mcpu_ext_opt); if (opt->canonical_name) strcpy (selected_cpu_name, opt->canonical_name); else @@ -26870,6 +26899,8 @@ s_arm_cpu (int ignored ATTRIBUTE_UNUSED) selected_cpu_name[i] = 0; } ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt); + if (dyn_mcpu_ext_opt) + ARM_MERGE_FEATURE_SETS (cpu_variant, cpu_variant, *dyn_mcpu_ext_opt); *input_line_pointer = saved_char; demand_empty_rest_of_line (); return; @@ -26900,9 +26931,11 @@ s_arm_arch (int ignored ATTRIBUTE_UNUSED) if (streq (opt->name, name)) { mcpu_cpu_opt = &opt->value; - selected_cpu = opt->value; + XDELETE (dyn_mcpu_ext_opt); + dyn_mcpu_ext_opt = NULL; + selected_cpu = *mcpu_cpu_opt; strcpy (selected_cpu_name, opt->name); - ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt); + ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, *mfpu_opt); *input_line_pointer = saved_char; demand_empty_rest_of_line (); return; @@ -26989,14 +27022,20 @@ s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED) break; } + if (!dyn_mcpu_ext_opt) + { + dyn_mcpu_ext_opt = XNEW (arm_feature_set); + *dyn_mcpu_ext_opt = arm_arch_none; + } if (adding_value) - ARM_MERGE_FEATURE_SETS (selected_cpu, selected_cpu, + ARM_MERGE_FEATURE_SETS (*dyn_mcpu_ext_opt, *dyn_mcpu_ext_opt, opt->merge_value); else - ARM_CLEAR_FEATURE (selected_cpu, selected_cpu, opt->clear_value); + ARM_CLEAR_FEATURE (*dyn_mcpu_ext_opt, *dyn_mcpu_ext_opt, + opt->clear_value); - mcpu_cpu_opt = &selected_cpu; - ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt); + ARM_MERGE_FEATURE_SETS (selected_cpu, *mcpu_cpu_opt, *dyn_mcpu_ext_opt); + ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, *mfpu_opt); *input_line_pointer = saved_char; demand_empty_rest_of_line (); return; @@ -27029,6 +27068,8 @@ s_arm_fpu (int ignored ATTRIBUTE_UNUSED) { mfpu_opt = &opt->value; ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt); + if (dyn_mcpu_ext_opt) + ARM_MERGE_FEATURE_SETS (cpu_variant, cpu_variant, *dyn_mcpu_ext_opt); *input_line_pointer = saved_char; demand_empty_rest_of_line (); return; diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h index 53c4986..1187d19 100644 --- a/gas/config/tc-arm.h +++ b/gas/config/tc-arm.h @@ -118,8 +118,8 @@ extern bfd_boolean tc_start_label_without_colon (void); extern void arm_md_end (void); bfd_boolean arm_is_eabi (void); -#define md_post_relax_hook aeabi_set_public_attributes () -extern void aeabi_set_public_attributes (void); +#define md_post_relax_hook arm_md_post_relax () +extern void arm_md_post_relax (void); #endif /* NOTE: The fake label creation in stabs.c:s_stab_generic() has |