summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog32
-rw-r--r--gcc/config/i386/i386-c.c4
-rw-r--r--gcc/config/i386/i386-opts.h6
-rw-r--r--gcc/config/i386/i386.c130
-rw-r--r--gcc/config/i386/i386.h8
-rw-r--r--gcc/config/i386/i386.opt31
-rw-r--r--gcc/config/i386/t-i3862
-rw-r--r--gcc/opts-common.c16
-rw-r--r--gcc/opts.h2
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,5 +1,37 @@
2011-05-16 Joseph Myers <joseph@codesourcery.com>
+ * 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 <joseph@codesourcery.com>
+
PR preprocessor/48677
* cppspec.c (lang_specific_driver): Set new_decoded_options[0]
from decoded_options[0], not from itself.
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]
: "<unknown>"));
- 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