diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4bcf816e8339..94b3e509cfcc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2016-12-15 Richard Earnshaw + + * 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 * arm-isa.h (isa_feature): Add bits for VFPv4, FPv5, fp16conv, diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c index b5921342f2e9..9dd9a8d59c87 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 659959bcec11..da3484f3294d 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 bc246c919db8..437ee2da72cf 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 a37faccbb02e..934144de7799 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