diff mbox

[15/21,arm] Initialize fpu capability bits in arm_active_target.

Message ID 07e8b5b9-e6c0-9fb3-f5ea-c6b415a5e0c6@arm.com
State New
Headers show

Commit Message

Richard Earnshaw (lists) Dec. 15, 2016, 4:07 p.m. UTC
Now that we can describe the FPU with the standard ISA bits we need to
initialize them.  However, the FPU settings can be changed with target build
attributes, so we also need to reset them if things change.  This requires
a bit of juggling about with the existing code to ensure that the active
target is reconfigured after each change to the target options.

	* arm-protos.h: Include sbitmap.h
	(arm_configure_build_target): Make public.
	* arm.c (arm_configure_build_target): Now not static.
	(arm_valid_target_attribute_rec): Move internal option check to...
	(arm_valid_target_attribute_tree0: ... here.  Also reconfingure the
	active target.
	(arm_override_options_after_change): Call arm_configure_build_target.
	(isa_all_fpubits): Renamed from isa_fpubits.
	(arm_option_restore): New function.
	(TARGET_OPTION_RESTORE): Register it.
	(arm_configure_build_target): Initialize the FPU capability bits in
	the isa.
	(arm_option_override): Move the code that forces the setting of the
	FPU option before the call to arm_configure_build_target.
	* arm.opt (march): Mark as Save.
	(mcpu, mtune): Likewise.
	* arm-c.c (arm_pragma_target_parse): Reconfigure the build target
	after pragmas change the target options.
---
 gcc/config/arm/arm-c.c      |  2 ++
 gcc/config/arm/arm-protos.h |  4 +++
 gcc/config/arm/arm.c        | 69
++++++++++++++++++++++++++++++---------------
 gcc/config/arm/arm.opt      |  6 ++--
 4 files changed, 55 insertions(+), 26 deletions(-)
diff mbox

Patch

diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c
index b592134..9dd9a8d 100644
--- a/gcc/config/arm/arm-c.c
+++ b/gcc/config/arm/arm-c.c
@@ -243,6 +243,8 @@  arm_pragma_target_parse (tree args, tree pop_target)
       /* handle_pragma_pop_options and handle_pragma_reset_options will set
        target_option_current_node, but not handle_pragma_target.  */
       target_option_current_node = cur_tree;
+      arm_configure_build_target (&arm_active_target, &global_options,
+				  &global_options_set, false);
     }
 
   /* Update macros if target_node changes. The global state will be restored
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 659959b..da3484f 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -24,6 +24,7 @@ 
 
 #include "arm-flags.h"
 #include "arm-isa.h"
+#include "sbitmap.h"
 
 extern enum unwind_info_type arm_except_unwind_info (struct gcc_options *);
 extern int use_return_insn (int, rtx);
@@ -223,6 +224,9 @@  extern bool arm_change_mode_p (tree);
 
 extern tree arm_valid_target_attribute_tree (tree, struct gcc_options *,
 					     struct gcc_options *);
+extern void arm_configure_build_target (struct arm_build_target *,
+					struct gcc_options *,
+					struct gcc_options *, bool);
 extern void arm_pr_long_calls (struct cpp_reader *);
 extern void arm_pr_no_long_calls (struct cpp_reader *);
 extern void arm_pr_long_calls_off (struct cpp_reader *);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index bc246c9..437ee2d 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -231,6 +231,8 @@  static tree arm_build_builtin_va_list (void);
 static void arm_expand_builtin_va_start (tree, rtx);
 static tree arm_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
 static void arm_option_override (void);
+static void arm_option_restore (struct gcc_options *,
+				struct cl_target_option *);
 static void arm_override_options_after_change (void);
 static void arm_option_print (FILE *, int, struct cl_target_option *);
 static void arm_set_current_function (tree);
@@ -408,6 +410,9 @@  static const struct attribute_spec arm_attribute_table[] =
 #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
 #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE arm_override_options_after_change
 
+#undef TARGET_OPTION_RESTORE
+#define TARGET_OPTION_RESTORE arm_option_restore
+
 #undef TARGET_OPTION_PRINT
 #define TARGET_OPTION_PRINT arm_option_print
 
@@ -2932,9 +2937,19 @@  arm_override_options_after_change_1 (struct gcc_options *opts)
 static void
 arm_override_options_after_change (void)
 {
+  arm_configure_build_target (&arm_active_target, &global_options,
+			      &global_options_set, false);
+
   arm_override_options_after_change_1 (&global_options);
 }
 
+static void
+arm_option_restore (struct gcc_options *opts, struct cl_target_option *ptr)
+{
+  arm_configure_build_target (&arm_active_target, opts, &global_options_set,
+			      false);
+}
+
 /* Reset options between modes that the user has specified.  */
 static void
 arm_option_override_internal (struct gcc_options *opts,
@@ -3048,13 +3063,13 @@  arm_initialize_isa (sbitmap isa, const enum isa_feature *isa_bits)
     bitmap_set_bit (isa, *(isa_bits++));
 }
 
-static sbitmap isa_fpubits;
+static sbitmap isa_all_fpubits;
 static sbitmap isa_quirkbits;
 
 /* Configure a build target TARGET from the user-specified options OPTS and
    OPTS_SET.  If WARN_COMPATIBLE, emit a diagnostic if both the CPU and
    architecture have been specified, but the two are not identical.  */
-static void
+void
 arm_configure_build_target (struct arm_build_target *target,
 			    struct gcc_options *opts,
 			    struct gcc_options *opts_set,
@@ -3063,6 +3078,7 @@  arm_configure_build_target (struct arm_build_target *target,
   const struct processors *arm_selected_tune = NULL;
   const struct processors *arm_selected_arch = NULL;
   const struct processors *arm_selected_cpu = NULL;
+  const struct arm_fpu_desc *arm_selected_fpu = NULL;
 
   bitmap_clear (target->isa);
   target->core_name = NULL;
@@ -3093,7 +3109,7 @@  arm_configure_build_target (struct arm_build_target *target,
 	  /* Ignore any bits that are quirk bits.  */
 	  bitmap_and_compl (cpu_isa, cpu_isa, isa_quirkbits);
 	  /* Ignore (for now) any bits that might be set by -mfpu.  */
-	  bitmap_and_compl (cpu_isa, cpu_isa, isa_fpubits);
+	  bitmap_and_compl (cpu_isa, cpu_isa, isa_all_fpubits);
 
 	  if (!bitmap_empty_p (cpu_isa))
 	    {
@@ -3239,6 +3255,13 @@  arm_configure_build_target (struct arm_build_target *target,
 
   gcc_assert (arm_selected_cpu);
 
+  arm_selected_fpu = &all_fpus[opts->x_arm_fpu_index];
+  auto_sbitmap fpu_bits(isa_num_bits);
+
+  arm_initialize_isa (fpu_bits, arm_selected_fpu->isa_bits);
+  bitmap_and_compl (target->isa, target->isa, isa_all_fpubits);
+  bitmap_ior (target->isa, target->isa, fpu_bits);
+
   /* The selected cpu may be an architecture, so lookup tuning by core ID.  */
   if (!arm_selected_tune)
     arm_selected_tune = &all_cores[arm_selected_cpu->core];
@@ -3263,11 +3286,27 @@  arm_option_override (void)
   isa_quirkbits = sbitmap_alloc (isa_num_bits);
   arm_initialize_isa (isa_quirkbits, quirk_bitlist);
 
-  isa_fpubits = sbitmap_alloc (isa_num_bits);
-  arm_initialize_isa (isa_fpubits, fpu_bitlist);
+  isa_all_fpubits = sbitmap_alloc (isa_num_bits);
+  arm_initialize_isa (isa_all_fpubits, fpu_bitlist);
 
   arm_active_target.isa = sbitmap_alloc (isa_num_bits);
 
+  if (!global_options_set.x_arm_fpu_index)
+    {
+      const char *target_fpu_name;
+      bool ok;
+
+#ifdef FPUTYPE_DEFAULT
+      target_fpu_name = FPUTYPE_DEFAULT;
+#else
+      target_fpu_name = "vfp";
+#endif
+
+      ok = opt_enum_arg_to_value (OPT_mfpu_, target_fpu_name, &arm_fpu_index,
+				  CL_TARGET);
+      gcc_assert (ok);
+    }
+
   arm_configure_build_target (&arm_active_target, &global_options,
 			      &global_options_set, true);
 
@@ -3378,22 +3417,6 @@  arm_option_override (void)
   if (TARGET_IWMMXT_ABI && !TARGET_IWMMXT)
     error ("iwmmxt abi requires an iwmmxt capable cpu");
 
-  if (!global_options_set.x_arm_fpu_index)
-    {
-      const char *target_fpu_name;
-      bool ok;
-
-#ifdef FPUTYPE_DEFAULT
-      target_fpu_name = FPUTYPE_DEFAULT;
-#else
-      target_fpu_name = "vfp";
-#endif
-
-      ok = opt_enum_arg_to_value (OPT_mfpu_, target_fpu_name, &arm_fpu_index,
-				  CL_TARGET);
-      gcc_assert (ok);
-    }
-
   /* If soft-float is specified then don't use FPU.  */
   if (TARGET_SOFT_FLOAT)
     arm_fpu_attr = FPU_NONE;
@@ -30293,8 +30316,6 @@  arm_valid_target_attribute_rec (tree args, struct gcc_options *opts)
 	  error ("attribute(target(\"%s\")) is unknown", q);
 	  return false;
 	}
-
-      arm_option_check_internal (opts);
     }
 
   return true;
@@ -30309,6 +30330,8 @@  arm_valid_target_attribute_tree (tree args, struct gcc_options *opts,
   if (!arm_valid_target_attribute_rec (args, opts))
     return NULL_TREE;
 
+  arm_configure_build_target (&arm_active_target, opts, opts_set, false);
+  arm_option_check_internal (opts);
   /* Do any overrides, such as global options arch=xxx.  */
   arm_option_override_internal (opts, opts_set);
 
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index a37facc..934144d 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -73,7 +73,7 @@  mapcs-stack-check
 Target Report Mask(APCS_STACK) Undocumented
 
 march=
-Target RejectNegative ToLower Joined Enum(arm_arch) Var(arm_arch_option)
+Target RejectNegative ToLower Joined Enum(arm_arch) Var(arm_arch_option) Save
 Specify the name of the target architecture.
 
 ; Other arm_arch values are loaded from arm-tables.opt
@@ -98,7 +98,7 @@  Target Report Mask(CALLER_INTERWORKING)
 Thumb: Assume function pointers may go to non-Thumb aware code.
 
 mcpu=
-Target RejectNegative ToLower Joined Enum(processor_type) Var(arm_cpu_option) Init(TARGET_CPU_arm_none)
+Target RejectNegative ToLower Joined Enum(processor_type) Var(arm_cpu_option) Init(TARGET_CPU_arm_none) Save
 Specify the name of the target CPU.
 
 mfloat-abi=
@@ -223,7 +223,7 @@  Target Report Mask(TPCS_LEAF_FRAME)
 Thumb: Generate (leaf) stack frames even if not needed.
 
 mtune=
-Target RejectNegative ToLower Joined Enum(processor_type) Var(arm_tune_option) Init(TARGET_CPU_arm_none)
+Target RejectNegative ToLower Joined Enum(processor_type) Var(arm_tune_option) Init(TARGET_CPU_arm_none) Save
 Tune code for the given processor.
 
 mprint-tune-info