From 8023568eaa1a93e7782e6854d21520374862034c Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Mon, 16 May 2011 22:26:29 +0100 Subject: [PATCH] opts-common.c (opt_enum_arg_to_value): New. * opts-common.c (opt_enum_arg_to_value): New. * opts.h (opt_enum_arg_to_value): Declare. * config/i386/i386.opt (fpmath): Remove. (mfpmath=): Use Enum, Init and Save. (fpmath_unit): New Enum and EnumValue entries. * config/i386/i386-c.c (ix86_pragma_target_parse): Update field name for function fpmath state. * config/i386/i386-opts.h (enum fpmath_unit): Move from i386.h. * config/i386/i386.c: Include diagnostic.h. (ix86_fpmath, IX86_FUNCTION_SPECIFIC_FPMATH): Remove. (ix86_target_string): Take enum fpmath_unit value instead of string. (ix86_debug_options): Update call to ix86_target_string. (ix86_option_override_internal): Don't process fpmath strings here. (x86_function_specific_save, ix86_function_specific_restore): Don't handle fpmath state specially. (ix86_function_specific_print): Pass fpmath state to ix86_target_string instead of printing in this function. (ix86_valid_target_attribute_inner_p): Take gcc_options pointer. Handle enum attributes. (IX86_ATTR_ENUM, ix86_opt_enum): New. (ix86_valid_target_attribute_tree): Update option_strings handling. Handle fpmath as enum option. (ix86_can_inline_p): Update field names for function fpmath state. (ix86_expand_builtin): Update call to ix86_target_string. * config/i386/i386.h (enum fpmath_unit): Move to i386-opts.h. (ix86_fpmath): Remove. * config/i386/t-i386 (i386.o): Update dependencies. From-SVN: r173809 --- gcc/ChangeLog | 32 +++++++++ gcc/config/i386/i386-c.c | 4 +- gcc/config/i386/i386-opts.h | 6 ++ gcc/config/i386/i386.c | 130 +++++++++++++++++++++--------------- gcc/config/i386/i386.h | 8 --- gcc/config/i386/i386.opt | 31 +++++++-- gcc/config/i386/t-i386 | 2 +- gcc/opts-common.c | 16 +++++ gcc/opts.h | 2 + 9 files changed, 160 insertions(+), 71 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2258bc1f318..7f140b84fab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,35 @@ +2011-05-16 Joseph Myers + + * opts-common.c (opt_enum_arg_to_value): New. + * opts.h (opt_enum_arg_to_value): Declare. + * config/i386/i386.opt (fpmath): Remove. + (mfpmath=): Use Enum, Init and Save. + (fpmath_unit): New Enum and EnumValue entries. + * config/i386/i386-c.c (ix86_pragma_target_parse): Update field + name for function fpmath state. + * config/i386/i386-opts.h (enum fpmath_unit): Move from i386.h. + * config/i386/i386.c: Include diagnostic.h. + (ix86_fpmath, IX86_FUNCTION_SPECIFIC_FPMATH): Remove. + (ix86_target_string): Take enum fpmath_unit value instead of + string. + (ix86_debug_options): Update call to ix86_target_string. + (ix86_option_override_internal): Don't process fpmath strings + here. + (x86_function_specific_save, ix86_function_specific_restore): + Don't handle fpmath state specially. + (ix86_function_specific_print): Pass fpmath state to + ix86_target_string instead of printing in this function. + (ix86_valid_target_attribute_inner_p): Take gcc_options pointer. + Handle enum attributes. + (IX86_ATTR_ENUM, ix86_opt_enum): New. + (ix86_valid_target_attribute_tree): Update option_strings + handling. Handle fpmath as enum option. + (ix86_can_inline_p): Update field names for function fpmath state. + (ix86_expand_builtin): Update call to ix86_target_string. + * config/i386/i386.h (enum fpmath_unit): Move to i386-opts.h. + (ix86_fpmath): Remove. + * config/i386/t-i386 (i386.o): Update dependencies. + 2011-05-16 Joseph Myers PR preprocessor/48677 diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c index 14973513334..56765484364 100644 --- a/gcc/config/i386/i386-c.c +++ b/gcc/config/i386/i386-c.c @@ -340,14 +340,14 @@ ix86_pragma_target_parse (tree args, tree pop_target) ix86_target_macros_internal (prev_isa & diff_isa, prev_arch, prev_tune, - (enum fpmath_unit) prev_opt->fpmath, + (enum fpmath_unit) prev_opt->x_ix86_fpmath, cpp_undef); /* Define all of the macros for new options that were just turned on. */ ix86_target_macros_internal (cur_isa & diff_isa, cur_arch, cur_tune, - (enum fpmath_unit) cur_opt->fpmath, + (enum fpmath_unit) cur_opt->x_ix86_fpmath, cpp_define); return true; diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h index 791304d931a..3cc2253c3c2 100644 --- a/gcc/config/i386/i386-opts.h +++ b/gcc/config/i386/i386-opts.h @@ -47,6 +47,12 @@ enum calling_abi MS_ABI = 1 }; +enum fpmath_unit +{ + FPMATH_387 = 1, + FPMATH_SSE = 2 +}; + enum tls_dialect { TLS_DIALECT_GNU, diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index db64434fb45..80f356f3ee7 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see #include "sbitmap.h" #include "fibheap.h" #include "opts.h" +#include "diagnostic.h" enum upper_128bits_state { @@ -2325,9 +2326,6 @@ struct ix86_frame bool save_regs_using_mov; }; -/* Which unit we are generating floating point math for. */ -enum fpmath_unit ix86_fpmath; - /* Which cpu are we scheduling for. */ enum attr_cpu ix86_schedule; @@ -2429,19 +2427,19 @@ enum ix86_function_specific_strings { IX86_FUNCTION_SPECIFIC_ARCH, IX86_FUNCTION_SPECIFIC_TUNE, - IX86_FUNCTION_SPECIFIC_FPMATH, IX86_FUNCTION_SPECIFIC_MAX }; static char *ix86_target_string (int, int, const char *, const char *, - const char *, bool); + enum fpmath_unit, bool); static void ix86_debug_options (void) ATTRIBUTE_UNUSED; static void ix86_function_specific_save (struct cl_target_option *); static void ix86_function_specific_restore (struct cl_target_option *); static void ix86_function_specific_print (FILE *, int, struct cl_target_option *); static bool ix86_valid_target_attribute_p (tree, tree, tree, int); -static bool ix86_valid_target_attribute_inner_p (tree, char *[]); +static bool ix86_valid_target_attribute_inner_p (tree, char *[], + struct gcc_options *); static bool ix86_can_inline_p (tree, tree); static void ix86_set_current_function (tree); static unsigned int ix86_minimum_incoming_stack_boundary (bool); @@ -3085,7 +3083,7 @@ ix86_handle_option (struct gcc_options *opts, static char * ix86_target_string (int isa, int flags, const char *arch, const char *tune, - const char *fpmath, bool add_nl_p) + enum fpmath_unit fpmath, bool add_nl_p) { struct ix86_target_opts { @@ -3219,7 +3217,23 @@ ix86_target_string (int isa, int flags, const char *arch, const char *tune, if (fpmath) { opts[num][0] = "-mfpmath="; - opts[num++][1] = fpmath; + switch ((int) fpmath) + { + case FPMATH_387: + opts[num++][1] = "387"; + break; + + case FPMATH_SSE: + opts[num++][1] = "sse"; + break; + + case FPMATH_387 | FPMATH_SSE: + opts[num++][1] = "sse+387"; + break; + + default: + gcc_unreachable (); + } } /* Any options? */ @@ -3294,7 +3308,7 @@ ix86_debug_options (void) { char *opts = ix86_target_string (ix86_isa_flags, target_flags, ix86_arch_string, ix86_tune_string, - ix86_fpmath_string, true); + ix86_fpmath, true); if (opts) { @@ -4003,44 +4017,24 @@ ix86_option_override_internal (bool main_args_p) && ! TARGET_SSE) error ("%ssseregparm%s used without SSE enabled", prefix, suffix); - ix86_fpmath = TARGET_FPMATH_DEFAULT; - if (ix86_fpmath_string != 0) + if (global_options_set.x_ix86_fpmath) { - if (! strcmp (ix86_fpmath_string, "387")) - ix86_fpmath = FPMATH_387; - else if (! strcmp (ix86_fpmath_string, "sse")) - { - if (!TARGET_SSE) - { - warning (0, "SSE instruction set disabled, using 387 arithmetics"); - ix86_fpmath = FPMATH_387; - } - else - ix86_fpmath = FPMATH_SSE; - } - else if (! strcmp (ix86_fpmath_string, "387,sse") - || ! strcmp (ix86_fpmath_string, "387+sse") - || ! strcmp (ix86_fpmath_string, "sse,387") - || ! strcmp (ix86_fpmath_string, "sse+387") - || ! strcmp (ix86_fpmath_string, "both")) + if (ix86_fpmath & FPMATH_SSE) { if (!TARGET_SSE) { warning (0, "SSE instruction set disabled, using 387 arithmetics"); ix86_fpmath = FPMATH_387; } - else if (!TARGET_80387) + else if ((ix86_fpmath & FPMATH_387) && !TARGET_80387) { warning (0, "387 instruction set disabled, using SSE arithmetics"); ix86_fpmath = FPMATH_SSE; } - else - ix86_fpmath = (enum fpmath_unit) (FPMATH_SSE | FPMATH_387); } - else - error ("bad value (%s) for %sfpmath=%s %s", - ix86_fpmath_string, prefix, suffix, sw); } + else + ix86_fpmath = TARGET_FPMATH_DEFAULT; /* If the i387 is disabled, then do not return values in it. */ if (!TARGET_80387) @@ -4344,7 +4338,6 @@ ix86_function_specific_save (struct cl_target_option *ptr) ptr->arch = ix86_arch; ptr->schedule = ix86_schedule; ptr->tune = ix86_tune; - ptr->fpmath = ix86_fpmath; ptr->branch_cost = ix86_branch_cost; ptr->tune_defaulted = ix86_tune_defaulted; ptr->arch_specified = ix86_arch_specified; @@ -4356,7 +4349,6 @@ ix86_function_specific_save (struct cl_target_option *ptr) gcc_assert (ptr->arch == ix86_arch); gcc_assert (ptr->schedule == ix86_schedule); gcc_assert (ptr->tune == ix86_tune); - gcc_assert (ptr->fpmath == ix86_fpmath); gcc_assert (ptr->branch_cost == ix86_branch_cost); } @@ -4373,7 +4365,6 @@ ix86_function_specific_restore (struct cl_target_option *ptr) ix86_arch = (enum processor_type) ptr->arch; ix86_schedule = (enum attr_cpu) ptr->schedule; ix86_tune = (enum processor_type) ptr->tune; - ix86_fpmath = (enum fpmath_unit) ptr->fpmath; ix86_branch_cost = ptr->branch_cost; ix86_tune_defaulted = ptr->tune_defaulted; ix86_arch_specified = ptr->arch_specified; @@ -4407,7 +4398,7 @@ ix86_function_specific_print (FILE *file, int indent, { char *target_string = ix86_target_string (ptr->x_ix86_isa_flags, ptr->x_target_flags, - NULL, NULL, NULL, false); + NULL, NULL, ptr->x_ix86_fpmath, false); fprintf (file, "%*sarch = %d (%s)\n", indent, "", @@ -4423,9 +4414,6 @@ ix86_function_specific_print (FILE *file, int indent, ? cpu_names[ptr->tune] : "")); - fprintf (file, "%*sfpmath = %d%s%s\n", indent, "", ptr->fpmath, - (ptr->fpmath & FPMATH_387) ? ", 387" : "", - (ptr->fpmath & FPMATH_SSE) ? ", sse" : ""); fprintf (file, "%*sbranch_cost = %d\n", indent, "", ptr->branch_cost); if (target_string) @@ -4441,13 +4429,15 @@ ix86_function_specific_print (FILE *file, int indent, over the list. */ static bool -ix86_valid_target_attribute_inner_p (tree args, char *p_strings[]) +ix86_valid_target_attribute_inner_p (tree args, char *p_strings[], + struct gcc_options *enum_opts_set) { char *next_optstr; bool ret = true; #define IX86_ATTR_ISA(S,O) { S, sizeof (S)-1, ix86_opt_isa, O, 0 } #define IX86_ATTR_STR(S,O) { S, sizeof (S)-1, ix86_opt_str, O, 0 } +#define IX86_ATTR_ENUM(S,O) { S, sizeof (S)-1, ix86_opt_enum, O, 0 } #define IX86_ATTR_YES(S,O,M) { S, sizeof (S)-1, ix86_opt_yes, O, M } #define IX86_ATTR_NO(S,O,M) { S, sizeof (S)-1, ix86_opt_no, O, M } @@ -4457,6 +4447,7 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[]) ix86_opt_yes, ix86_opt_no, ix86_opt_str, + ix86_opt_enum, ix86_opt_isa }; @@ -4493,9 +4484,11 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[]) IX86_ATTR_ISA ("rdrnd", OPT_mrdrnd), IX86_ATTR_ISA ("f16c", OPT_mf16c), + /* enum options */ + IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), + /* string options */ IX86_ATTR_STR ("arch=", IX86_FUNCTION_SPECIFIC_ARCH), - IX86_ATTR_STR ("fpmath=", IX86_FUNCTION_SPECIFIC_FPMATH), IX86_ATTR_STR ("tune=", IX86_FUNCTION_SPECIFIC_TUNE), /* flag options */ @@ -4536,7 +4529,8 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[]) for (; args; args = TREE_CHAIN (args)) if (TREE_VALUE (args) - && !ix86_valid_target_attribute_inner_p (TREE_VALUE (args), p_strings)) + && !ix86_valid_target_attribute_inner_p (TREE_VALUE (args), + p_strings, enum_opts_set)) ret = false; return ret; @@ -4592,7 +4586,9 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[]) type = attrs[i].type; opt_len = attrs[i].len; if (ch == attrs[i].string[0] - && ((type != ix86_opt_str) ? len == opt_len : len > opt_len) + && ((type != ix86_opt_str && type != ix86_opt_enum) + ? len == opt_len + : len > opt_len) && memcmp (p, attrs[i].string, opt_len) == 0) { opt = attrs[i].opt; @@ -4640,6 +4636,23 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[]) p_strings[opt] = xstrdup (p + opt_len); } + else if (type == ix86_opt_enum) + { + bool arg_ok; + int value; + + arg_ok = opt_enum_arg_to_value (opt, p + opt_len, &value, CL_TARGET); + if (arg_ok) + set_option (&global_options, enum_opts_set, opt, value, + p + opt_len, DK_UNSPECIFIED, input_location, + global_dc); + else + { + error ("attribute(target(\"%s\")) is unknown", orig_p); + ret = false; + } + } + else gcc_unreachable (); } @@ -4654,17 +4667,21 @@ ix86_valid_target_attribute_tree (tree args) { const char *orig_arch_string = ix86_arch_string; const char *orig_tune_string = ix86_tune_string; - const char *orig_fpmath_string = ix86_fpmath_string; + enum fpmath_unit orig_fpmath_set = global_options_set.x_ix86_fpmath; int orig_tune_defaulted = ix86_tune_defaulted; int orig_arch_specified = ix86_arch_specified; - char *option_strings[IX86_FUNCTION_SPECIFIC_MAX] = { NULL, NULL, NULL }; + char *option_strings[IX86_FUNCTION_SPECIFIC_MAX] = { NULL, NULL }; tree t = NULL_TREE; int i; struct cl_target_option *def = TREE_TARGET_OPTION (target_option_default_node); + struct gcc_options enum_opts_set; + + memset (&enum_opts_set, 0, sizeof (enum_opts_set)); /* Process each of the options on the chain. */ - if (! ix86_valid_target_attribute_inner_p (args, option_strings)) + if (! ix86_valid_target_attribute_inner_p (args, option_strings, + &enum_opts_set)) return NULL_TREE; /* If the changed options are different from the default, rerun @@ -4675,7 +4692,7 @@ ix86_valid_target_attribute_tree (tree args) || target_flags != def->x_target_flags || option_strings[IX86_FUNCTION_SPECIFIC_ARCH] || option_strings[IX86_FUNCTION_SPECIFIC_TUNE] - || option_strings[IX86_FUNCTION_SPECIFIC_FPMATH]) + || ix86_fpmath != def->x_ix86_fpmath) { /* If we are using the default tune= or arch=, undo the string assigned, and use the default. */ @@ -4690,10 +4707,13 @@ ix86_valid_target_attribute_tree (tree args) ix86_tune_string = NULL; /* If fpmath= is not set, and we now have sse2 on 32-bit, use it. */ - if (option_strings[IX86_FUNCTION_SPECIFIC_FPMATH]) - ix86_fpmath_string = option_strings[IX86_FUNCTION_SPECIFIC_FPMATH]; + if (enum_opts_set.x_ix86_fpmath) + global_options_set.x_ix86_fpmath = (enum fpmath_unit) 1; else if (!TARGET_64BIT && TARGET_SSE) - ix86_fpmath_string = "sse,387"; + { + ix86_fpmath = (enum fpmath_unit) (FPMATH_SSE | FPMATH_387); + global_options_set.x_ix86_fpmath = (enum fpmath_unit) 1; + } /* Do any overrides, such as arch=xxx, or tune=xxx support. */ ix86_option_override_internal (false); @@ -4707,7 +4727,7 @@ ix86_valid_target_attribute_tree (tree args) ix86_arch_string = orig_arch_string; ix86_tune_string = orig_tune_string; - ix86_fpmath_string = orig_fpmath_string; + global_options_set.x_ix86_fpmath = orig_fpmath_set; /* Free up memory allocated to hold the strings */ for (i = 0; i < IX86_FUNCTION_SPECIFIC_MAX; i++) @@ -4805,7 +4825,7 @@ ix86_can_inline_p (tree caller, tree callee) else if (caller_opts->tune != callee_opts->tune) ret = false; - else if (caller_opts->fpmath != callee_opts->fpmath) + else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath) ret = false; else if (caller_opts->branch_cost != callee_opts->branch_cost) @@ -27378,7 +27398,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, && !(ix86_builtins_isa[fcode].isa & ix86_isa_flags)) { char *opts = ix86_target_string (ix86_builtins_isa[fcode].isa, 0, NULL, - NULL, NULL, false); + NULL, (enum fpmath_unit) 0, false); if (!opts) error ("%qE needs unknown isa option", fndecl); diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index f3b0cb9acd1..8badcbbce61 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2029,14 +2029,6 @@ enum processor_type extern enum processor_type ix86_tune; extern enum processor_type ix86_arch; -enum fpmath_unit -{ - FPMATH_387 = 1, - FPMATH_SSE = 2 -}; - -extern enum fpmath_unit ix86_fpmath; - /* Size of the RED_ZONE area. */ #define RED_ZONE_SIZE 128 /* Reserved area of the red zone for temporaries. */ diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index ea40dd7e5c9..21e0def1549 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -40,10 +40,6 @@ unsigned char arch TargetSave unsigned char tune -;; -mfpath= -TargetSave -unsigned char fpmath - ;; CPU schedule model TargetSave unsigned char schedule @@ -170,9 +166,34 @@ Target Report Mask(FLOAT_RETURNS) Save Return values of functions in FPU registers mfpmath= -Target RejectNegative Joined Var(ix86_fpmath_string) +Target RejectNegative Joined Var(ix86_fpmath) Enum(fpmath_unit) Init(FPMATH_387) Save Generate floating point mathematics using given instruction set +Enum +Name(fpmath_unit) Type(enum fpmath_unit) +Valid arguments to -mfpmath=: + +EnumValue +Enum(fpmath_unit) String(387) Value(FPMATH_387) + +EnumValue +Enum(fpmath_unit) String(sse) Value(FPMATH_SSE) + +EnumValue +Enum(fpmath_unit) String(387,sse) Value({(enum fpmath_unit) (FPMATH_SSE | FPMATH_387)}) + +EnumValue +Enum(fpmath_unit) String(387+sse) Value({(enum fpmath_unit) (FPMATH_SSE | FPMATH_387)}) + +EnumValue +Enum(fpmath_unit) String(sse,387) Value({(enum fpmath_unit) (FPMATH_SSE | FPMATH_387)}) + +EnumValue +Enum(fpmath_unit) String(sse+387) Value({(enum fpmath_unit) (FPMATH_SSE | FPMATH_387)}) + +EnumValue +Enum(fpmath_unit) String(both) Value({(enum fpmath_unit) (FPMATH_SSE | FPMATH_387)}) + mhard-float Target RejectNegative Mask(80387) MaskExists Save Use hardware fp diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386 index e9fa3cd8d6f..a43843351a0 100644 --- a/gcc/config/i386/t-i386 +++ b/gcc/config/i386/t-i386 @@ -24,7 +24,7 @@ i386.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(GGC_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h $(CGRAPH_H) \ $(TREE_GIMPLE_H) $(DWARF2_H) $(DF_H) tm-constrs.h $(PARAMS_H) \ i386-builtin-types.inc debug.h dwarf2out.h sbitmap.h $(FIBHEAP_H) \ - $(OPTS_H) + $(OPTS_H) $(DIAGNOSTIC_H) i386-c.o: $(srcdir)/config/i386/i386-c.c \ $(srcdir)/config/i386/i386-protos.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \ diff --git a/gcc/opts-common.c b/gcc/opts-common.c index 089d8199d50..973dd7e97e7 100644 --- a/gcc/opts-common.c +++ b/gcc/opts-common.c @@ -212,6 +212,22 @@ enum_arg_to_value (const struct cl_enum_arg *enum_args, return false; } +/* Look up ARG in the enum used by option OPT_INDEX for language + LANG_MASK, returning true and storing the value in *VALUE if found, + and returning false without modifying *VALUE if not found. */ + +bool +opt_enum_arg_to_value (size_t opt_index, const char *arg, int *value, + unsigned int lang_mask) +{ + const struct cl_option *option = &cl_options[opt_index]; + + gcc_assert (option->var_type == CLVC_ENUM); + + return enum_arg_to_value (cl_enums[option->var_enum].values, arg, + value, lang_mask); +} + /* Look of VALUE in ENUM_ARGS for language LANG_MASK and store the corresponding string in *ARGP, returning true if the found string was marked as canonical, false otherwise. If VALUE is not found diff --git a/gcc/opts.h b/gcc/opts.h index c0c597f8601..b070c8fd6ac 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -395,4 +395,6 @@ extern void default_options_optimization (struct gcc_options *opts, extern void set_struct_debug_option (struct gcc_options *opts, location_t loc, const char *value); +extern bool opt_enum_arg_to_value (size_t opt_index, const char *arg, + int *value, unsigned int lang_mask); #endif -- 2.30.2