#include "sbitmap.h"
#include "fibheap.h"
#include "opts.h"
+#include "diagnostic.h"
enum upper_128bits_state
{
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;
{
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);
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
{
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? */
{
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)
{
&& ! 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)
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;
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);
}
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;
{
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, "",
? 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)
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 }
ix86_opt_yes,
ix86_opt_no,
ix86_opt_str,
+ ix86_opt_enum,
ix86_opt_isa
};
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 */
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;
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;
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 ();
}
{
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
|| 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. */
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);
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++)
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)
&& !(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);