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
This commit is contained in:
Joseph Myers 2011-05-16 22:26:29 +01:00 committed by Joseph Myers
parent c22cb03b64
commit 8023568eaa
9 changed files with 160 additions and 71 deletions

View File

@ -1,3 +1,35 @@
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

View File

@ -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;

View File

@ -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,

View File

@ -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 (ix86_fpmath & FPMATH_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 (!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);

View File

@ -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. */

View File

@ -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

View File

@ -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 \

View File

@ -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

View File

@ -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