[arm] Initialize fpu capability bits in arm_active_target
authorRichard Earnshaw <rearnsha@arm.com>
Thu, 15 Dec 2016 15:56:29 +0000 (15:56 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Thu, 15 Dec 2016 15:56:29 +0000 (15:56 +0000)
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.

From-SVN: r243710

gcc/ChangeLog
gcc/config/arm/arm-c.c
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.opt

index 4bcf816e83399664a2b2b28ddf4867d7cf6554f2..94b3e509cfccd32bf546d546b7cbda2d3b7fab72 100644 (file)
@@ -1,3 +1,24 @@
+2016-12-15  Richard Earnshaw  <rearnsha@arm.com>
+
+       * 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.
+
 2016-12-15  Richard Earnshaw  <rearnsha@arm.com>
 
        * arm-isa.h (isa_feature): Add bits for VFPv4, FPv5, fp16conv,
index b5921342f2e90224ed59064e3ebec06e7cc4cab8..9dd9a8d59c872a28da6ff7363b5d4e3c75e42901 100644 (file)
@@ -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
index 659959bcec117ff01d1164956d971e93e5f845b4..da3484f3294d288a6c7905f23b3b194a3061bb99 100644 (file)
@@ -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 *);
index bc246c919db806698cd11657fa48707dec7bd4ea..437ee2da72cf5906a992eeadda7c3c98806127f1 100644 (file)
@@ -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);
 
index a37faccbb02eef7cca9f0e2eea35289e7e898901..934144de7799e91ae249d4e723ea815c75ee31ae 100644 (file)
@@ -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