aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog31
-rw-r--r--gas/config/tc-arm.c95
-rw-r--r--gas/config/tc-arm.h4
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