===================================================================
@@ -281,6 +281,12 @@ rs6000_handle_option (struct gcc_options
case OPT_mrecip:
opts->x_rs6000_recip_name = (value) ? "default" : "none";
break;
+
+#if !HAVE_PAIRED_FLOAT
+ case OPT_mpaired:
+ error_at (loc, "this compiler does not support -mpaired");
+ break;
+#endif
}
return true;
}
===================================================================
@@ -90,6 +90,17 @@ unsigned int rs6000_debug
TargetSave
int rs6000_target_flags_explicit
+;; Secondary flags word. We have run out of bits in target_flags, so push
+;; newer flag bits into rs6000_flags2 and rs6000_flags2_explicit
+Variable
+int rs6000_flags2 = TARGET_DEFAULT_FLAGS2
+
+TargetSave
+int x_rs6000_flags2
+
+TargetSave
+int x_rs6000_flags2_explicit
+
;; This option existed in the past, but now is always on.
mpowerpc
Target RejectNegative Undocumented Ignore
@@ -163,7 +174,7 @@ Target Report Mask(POPCNTD) Save
Use PowerPC V2.06 popcntd instruction
mfriz
-Target Report Var(TARGET_FRIZ) Init(-1) Save
+Target Report Mask(FRIZ) Var(rs6000_flags2)
Under -ffast-math, generate a FRIZ instruction for (double)(long long) conversions
mveclibabi=
@@ -223,7 +234,7 @@ Target Report Var(TARGET_SINGLE_PIC_BASE
Do not load the PIC register in function prologues
mavoid-indexed-addresses
-Target Report Var(TARGET_AVOID_XFORM) Init(-1) Save
+Target Report Mask(AVOID_XFORM) Var(rs6000_flags2)
Avoid generation of indexed load/store instructions when possible
mtls-markers
@@ -325,7 +336,7 @@ Target Var(rs6000_spe) Save
Generate SPE SIMD instructions on E500
mpaired
-Target Var(rs6000_paired_float) Save
+Target Mask(PAIRED_FLOAT) Var(rs6000_flags2)
Generate PPC750CL paired-single instructions
mspe=no
@@ -397,7 +408,7 @@ EnumValue
Enum(rs6000_traceback_type) String(no) Value(traceback_none)
mlongcall
-Target Report Var(rs6000_default_long_calls) Save
+Target Report Mask(LONG_CALLS) Var(rs6000_flags2)
Avoid all range limits on call instructions
mgen-cell-microcode
===================================================================
@@ -41,7 +41,7 @@
where TOGGLE is either 0 or 1.
- rs6000_default_long_calls is set to the value of TOGGLE, changing
+ TARGET_LONG_CALLS is set to the value of TOGGLE, changing
whether or not new function declarations receive a longcall
attribute by default. */
@@ -72,7 +72,10 @@ rs6000_pragma_longcall (cpp_reader *pfil
if (pragma_lex (&x) != CPP_EOF)
warning (OPT_Wpragmas, "junk at end of #pragma longcall");
- rs6000_default_long_calls = (n == integer_one_node);
+ if (n == integer_one_node)
+ rs6000_flags2 |= OPTION_MASK_LONG_CALLS;
+ else
+ rs6000_flags2 &= ~OPTION_MASK_LONG_CALLS;
}
/* Handle defining many CPP flags based on TARGET_xxx. As a general
@@ -285,12 +288,13 @@ rs6000_define_or_undefine_macro (bool de
have both the target flags and the builtin flags as arguments. */
void
-rs6000_target_modify_macros (bool define_p, int flags, unsigned bu_mask)
+rs6000_target_modify_macros (bool define_p, int flags, int flags2,
+ unsigned bu_mask)
{
if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET)
- fprintf (stderr, "rs6000_target_modify_macros (%s, 0x%x, 0x%x)\n",
+ fprintf (stderr, "rs6000_target_modify_macros (%s, 0x%x, 0x%x, 0x%x)\n",
(define_p) ? "define" : "undef",
- (unsigned) flags, bu_mask);
+ (unsigned) flags, (unsigned) flags2, bu_mask);
/* target_flags based options. */
rs6000_define_or_undefine_macro (define_p, "_ARCH_PPC");
@@ -342,7 +346,7 @@ void
rs6000_cpu_cpp_builtins (cpp_reader *pfile)
{
/* Define all of the common macros. */
- rs6000_target_modify_macros (true, target_flags,
+ rs6000_target_modify_macros (true, target_flags, rs6000_flags2,
rs6000_builtin_mask_calculate ());
if (TARGET_FRE)
===================================================================
@@ -288,7 +288,7 @@ typedef rtx (*gen_2arg_fn_t) (rtx, rtx,
/* Pointer to function (in rs6000-c.c) that can define or undefine target
macros that have changed. Languages that don't support the preprocessor
don't link in rs6000-c.c, so we can't call it directly. */
-void (*rs6000_target_modify_macros_ptr) (bool, int, unsigned);
+void (*rs6000_target_modify_macros_ptr) (bool, int, int, unsigned);
/* Target cpu costs. */
@@ -990,6 +990,9 @@ static bool rs6000_debug_cannot_change_m
enum machine_mode,
enum reg_class);
static bool rs6000_save_toc_in_prologue_p (void);
+static void rs6000_print_target_flags (FILE *, int, int, const char *);
+static void rs6000_print_rs6000_flags2 (FILE *, int, int, const char *);
+static void rs6000_print_builtin_flags (FILE *, unsigned, int, const char *);
rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
int, int *)
@@ -1477,7 +1480,8 @@ enum {
| MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
| MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
| MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
- | MASK_RECIP_PRECISION)
+ | MASK_RECIP_PRECISION | MASK_SOFT_FLOAT),
+ POWERPC_MASKS2 = (OPTION_MASK_AVOID_XFORM)
};
/* Masks for instructions set at various powerpc ISAs. */
@@ -1506,13 +1510,16 @@ struct rs6000_ptt
const char *const name; /* Canonical processor name. */
const enum processor_type processor; /* Processor type enum value. */
const int target_enable; /* Target flags to enable. */
+ const int target_enable2; /* 2nd target flags word to enable. */
};
static struct rs6000_ptt const processor_target_table[] =
{
-#define RS6000_CPU(NAME, CPU, FLAGS) { NAME, CPU, FLAGS },
+#define RS6000_CPU(NAME, CPU, FLAGS) { NAME, CPU, FLAGS, 0 },
+#define RS6000_CPU2(NAME, CPU, FLAGS, FLAGS2) { NAME, CPU, FLAGS, FLAGS2 },
#include "rs6000-cpus.def"
#undef RS6000_CPU
+#undef RS6000_CPU2
};
/* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
@@ -1717,8 +1724,9 @@ rs6000_debug_reg_print (int first_regno,
}
#define DEBUG_FMT_D "%-32s= %d\n"
-#define DEBUG_FMT_X "%-32s= 0x%x\n"
+#define DEBUG_FMT_X "%-32s= 0x%.8x"
#define DEBUG_FMT_S "%-32s= %s\n"
+#define DEBUG_FMT_S2 "%-32s= %s (%d)\n"
/* Print various interesting information with -mdebug=reg. */
static void
@@ -1813,12 +1821,28 @@ rs6000_debug_reg_global (void)
}
if (rs6000_cpu_index >= 0)
- fprintf (stderr, DEBUG_FMT_S, "cpu",
- processor_target_table[rs6000_cpu_index].name);
+ {
+ const struct rs6000_ptt *p = &processor_target_table[rs6000_cpu_index];
+ fprintf (stderr, DEBUG_FMT_S2, "cpu", p->name, (int)p->processor);
+ rs6000_print_target_flags (stderr, p->target_enable, 0, "cpu_flags");
+ rs6000_print_rs6000_flags2 (stderr, p->target_enable2, 0, "cpu_flags2");
+ }
+ else
+ fprintf (stderr, DEBUG_FMT_S, "cpu", "<none>");
if (rs6000_tune_index >= 0)
- fprintf (stderr, DEBUG_FMT_S, "tune",
- processor_target_table[rs6000_tune_index].name);
+ {
+ const struct rs6000_ptt *p = &processor_target_table[rs6000_tune_index];
+ fprintf (stderr, DEBUG_FMT_S2, "tune", p->name, (int)p->processor);
+ rs6000_print_target_flags (stderr, p->target_enable, 0, "tune_flags");
+ rs6000_print_rs6000_flags2 (stderr, p->target_enable2, 0, "tune_flags2");
+ }
+ else
+ fprintf (stderr, DEBUG_FMT_S, "tune", "<none>");
+
+ rs6000_print_target_flags (stderr, target_flags, 0, "target_flags");
+ rs6000_print_rs6000_flags2 (stderr, rs6000_flags2, 0, "rs6000_flags2");
+ rs6000_print_builtin_flags (stderr, rs6000_builtin_mask, 0, "builtins");
switch (rs6000_sched_costly_dep)
{
@@ -1948,7 +1972,6 @@ rs6000_debug_reg_global (void)
(int)END_BUILTINS);
fprintf (stderr, DEBUG_FMT_D, "Number of rs6000 builtins",
(int)RS6000_BUILTIN_COUNT);
- fprintf (stderr, DEBUG_FMT_X, "Builtin mask", rs6000_builtin_mask);
}
/* Initialize the various global tables that are based on register size. */
@@ -2317,8 +2340,8 @@ darwin_rs6000_override_options (void)
}
if (flag_mkernel)
{
- rs6000_default_long_calls = 1;
target_flags |= MASK_SOFT_FLOAT;
+ target_flags2 |= OPTION_MASK_LONG_CALLS;
}
/* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
@@ -2361,10 +2384,9 @@ rs6000_builtin_mask_calculate (void)
| ((TARGET_VSX) ? RS6000_BTM_VSX : 0)
| ((TARGET_SPE) ? RS6000_BTM_SPE : 0)
| ((TARGET_PAIRED_FLOAT) ? RS6000_BTM_PAIRED : 0)
- | ((TARGET_FRE) ? RS6000_BTM_FRE : 0)
- | ((TARGET_FRES) ? RS6000_BTM_FRES : 0)
- | ((TARGET_FRSQRTE) ? RS6000_BTM_FRSQRTE : 0)
- | ((TARGET_FRSQRTES) ? RS6000_BTM_FRSQRTES : 0)
+ | ((TARGET_PPC_GFXOPT) ? RS6000_BTM_GFXOPT : 0)
+ | ((TARGET_POPCNTB) ? RS6000_BTM_POPCNTB : 0)
+ | ((TARGET_FPRND) ? RS6000_BTM_FPRND : 0)
| ((TARGET_POPCNTD) ? RS6000_BTM_POPCNTD : 0)
| ((rs6000_cpu == PROCESSOR_CELL) ? RS6000_BTM_CELL : 0));
}
@@ -2382,6 +2404,7 @@ rs6000_option_override_internal (bool gl
const char *implicit_cpu = OPTION_TARGET_CPU_DEFAULT;
int set_masks;
+ int set_masks2;
int cpu_index;
int tune_index;
struct cl_target_option *main_target_opt
@@ -2418,18 +2441,21 @@ rs6000_option_override_internal (bool gl
rs6000_pointer_size = 32;
}
- set_masks = POWERPC_MASKS | MASK_SOFT_FLOAT;
+ set_masks = POWERPC_MASKS;
+ set_masks2 = POWERPC_MASKS2;
+
#ifdef OS_MISSING_POWERPC64
if (OS_MISSING_POWERPC64)
set_masks &= ~MASK_POWERPC64;
#endif
#ifdef OS_MISSING_ALTIVEC
if (OS_MISSING_ALTIVEC)
- set_masks &= ~MASK_ALTIVEC;
+ set_masks &= ~(MASK_ALTIVEC | MASK_VSX);
#endif
/* Don't override by the processor default if given explicitly. */
set_masks &= ~target_flags_explicit;
+ set_masks2 &= ~rs6000_flags2_explicit;
/* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
the cpu in a target attribute or pragma, but did not specify a tuning
@@ -2470,10 +2496,17 @@ rs6000_option_override_internal (bool gl
target_flags &= ~set_masks;
target_flags |= (processor_target_table[cpu_index].target_enable
& set_masks);
+ rs6000_flags2 &= ~set_masks2;
+ rs6000_flags2 |= (processor_target_table[cpu_index].target_enable2
+ & set_masks2);
}
else
- target_flags |= (processor_target_table[cpu_index].target_enable
- & ~target_flags_explicit);
+ {
+ target_flags |= (processor_target_table[cpu_index].target_enable
+ & ~target_flags_explicit);
+ rs6000_flags2 |= (processor_target_table[cpu_index].target_enable2
+ & ~rs6000_flags2_explicit);
+ }
if (rs6000_tune_index >= 0)
tune_index = rs6000_tune_index;
@@ -2583,6 +2616,13 @@ rs6000_option_override_internal (bool gl
}
}
+ /* Reset -mavoid-indexed-addresses if it was enabled by default but
+ altivec/vsx were used. */
+ if (((rs6000_flags2_explicit & OPTION_MASK_AVOID_XFORM) == 0)
+ && TARGET_AVOID_XFORM
+ && (TARGET_ALTIVEC || TARGET_VSX))
+ rs6000_flags2 &= ~OPTION_MASK_AVOID_XFORM;
+
/* Add some warnings for VSX. */
if (TARGET_VSX)
{
@@ -2602,7 +2642,7 @@ rs6000_option_override_internal (bool gl
systems at this point. */
else if (!BYTES_BIG_ENDIAN)
msg = N_("-mvsx used with little endian code");
- else if (TARGET_AVOID_XFORM > 0)
+ else if (TARGET_AVOID_XFORM)
msg = N_("-mvsx needs indexed addressing");
else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
{
@@ -3113,16 +3153,6 @@ rs6000_option_override_internal (bool gl
&& rs6000_single_float == 0 && rs6000_double_float == 0)
rs6000_single_float = rs6000_double_float = 1;
- /* If not explicitly specified via option, decide whether to generate indexed
- load/store instructions. */
- if (TARGET_AVOID_XFORM == -1)
- /* Avoid indexed addressing when targeting Power6 in order to avoid the
- DERAT mispredict penalty. However the LVE and STVE altivec instructions
- need indexed accesses and the type used is the scalar type of the element
- being loaded or stored. */
- TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
- && !TARGET_ALTIVEC);
-
/* Set the -mrecip options. */
if (rs6000_recip_name)
{
@@ -3176,11 +3206,7 @@ rs6000_option_override_internal (bool gl
target_flags. */
rs6000_builtin_mask = rs6000_builtin_mask_calculate ();
if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET)
- fprintf (stderr, "new builtin mask = 0x%x%s%s%s%s\n", rs6000_builtin_mask,
- (rs6000_builtin_mask & RS6000_BTM_ALTIVEC) ? ", altivec" : "",
- (rs6000_builtin_mask & RS6000_BTM_VSX) ? ", vsx" : "",
- (rs6000_builtin_mask & RS6000_BTM_PAIRED) ? ", paired" : "",
- (rs6000_builtin_mask & RS6000_BTM_SPE) ? ", spe" : "");
+ rs6000_print_builtin_flags (stderr, rs6000_builtin_mask, 0, "builtins");
/* Initialize all of the registers. */
rs6000_init_hard_regno_mode_ok (global_init_p);
@@ -7451,7 +7477,7 @@ init_cumulative_args (CUMULATIVE_ARGS *c
cum->nargs_prototype = n_named_args;
/* Check for a longcall attribute. */
- if ((!fntype && rs6000_default_long_calls)
+ if ((!fntype && TARGET_LONG_CALLS)
|| (fntype
&& lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
&& !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
@@ -10326,7 +10352,7 @@ static rtx
altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
tree arg0;
enum machine_mode tmode, mode0;
rtx pat, op0;
@@ -10385,7 +10411,7 @@ altivec_expand_st_builtin (tree exp, rtx
bool *expandedp)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
tree arg0, arg1;
enum machine_mode mode0, mode1;
rtx pat, op0, op1;
@@ -10442,7 +10468,7 @@ altivec_expand_dst_builtin (tree exp, rt
bool *expandedp)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
tree arg0, arg1, arg2;
enum machine_mode mode0, mode1;
rtx pat, op0, op1, op2;
@@ -10844,7 +10870,7 @@ static rtx
paired_expand_builtin (tree exp, rtx target, bool * expandedp)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
const struct builtin_description *d;
size_t i;
@@ -10909,7 +10935,7 @@ spe_expand_builtin (tree exp, rtx target
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
tree arg1, arg0;
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
enum insn_code icode;
enum machine_mode tmode, mode0;
rtx pat, op0;
@@ -11287,6 +11313,12 @@ rs6000_invalid_builtin (enum rs6000_buil
error ("Builtin function %s requires the -mpaired option", name);
else if ((fnmask & RS6000_BTM_SPE) != 0)
error ("Builtin function %s requires the -mspe option", name);
+ else if ((fnmask & RS6000_BTM_POPCNTB) != 0)
+ error ("Builtin function %s requires the -mpopcntb option", name);
+ else if ((fnmask & RS6000_BTM_FPRND) != 0)
+ error ("Builtin function %s requires the -mfprnd option", name);
+ else if ((fnmask & RS6000_BTM_POPCNTD) != 0)
+ error ("Builtin function %s requires the -mpopcntd option", name);
else
error ("Builtin function %s is not supported with the current options",
name);
@@ -24648,11 +24680,11 @@ rs6000_handle_longcall_attribute (tree *
}
/* Set longcall attributes on all functions declared when
- rs6000_default_long_calls is true. */
+ TARGET_LONG_CALLS is true. */
static void
rs6000_set_default_type_attributes (tree type)
{
- if (rs6000_default_long_calls
+ if (TARGET_LONG_CALLS
&& (TREE_CODE (type) == FUNCTION_TYPE
|| TREE_CODE (type) == METHOD_TYPE))
TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
@@ -27384,9 +27416,9 @@ rs6000_final_prescan_insn (rtx insn, rtx
/* Mask options that we want to support inside of attribute((target)) and
- #pragma GCC target operations. Note, we do not include things like
- 64/32-bit, endianess, hard/soft floating point, etc. that would have
- different calling sequences. */
+ #pragma GCC target operations that are options set in target_flags. Note,
+ we do not include things like 64/32-bit, endianess, hard/soft floating
+ point, etc. that would have different calling sequences. */
struct rs6000_opt_mask {
const char *name; /* option name */
@@ -27441,6 +27473,16 @@ static struct rs6000_opt_mask const rs60
{ "string", MASK_STRING, false, false },
};
+/* Mask options that we want to support inside of attribute((target)) and
+ #pragma GCC target operations that are set in rs6000_flags2. */
+static struct rs6000_opt_mask const rs6000_opt_masks2[] =
+{
+ { "friz", OPTION_MASK_FRIZ, false, true },
+ { "avoid-indexed-addresses", OPTION_MASK_AVOID_XFORM, true, true },
+ { "longcall", OPTION_MASK_LONG_CALLS, false, true },
+ { "paired", OPTION_MASK_PAIRED_FLOAT, false, true },
+};
+
/* Builtin mask mapping for printing the flags. */
static struct rs6000_opt_mask const rs6000_builtin_mask_names[] =
{
@@ -27448,38 +27490,68 @@ static struct rs6000_opt_mask const rs60
{ "vsx", RS6000_BTM_VSX, false, false },
{ "spe", RS6000_BTM_SPE, false, false },
{ "paired", RS6000_BTM_PAIRED, false, false },
- { "fre", RS6000_BTM_FRE, false, false },
- { "fres", RS6000_BTM_FRES, false, false },
- { "frsqrte", RS6000_BTM_FRSQRTE, false, false },
- { "frsqrtes", RS6000_BTM_FRSQRTES, false, false },
- { "popcntd", RS6000_BTM_POPCNTD, false, false },
+ { "gfxopt", RS6000_BTM_GFXOPT, false, false },
{ "cell", RS6000_BTM_CELL, false, false },
+ { "popcntb", RS6000_BTM_POPCNTB, false, false },
+ { "fprnd", RS6000_BTM_FPRND, false, false },
+ { "popcntd", RS6000_BTM_POPCNTD, false, false },
};
-/* Option variables that we want to support inside attribute((target)) and
- #pragma GCC target operations. */
-
-struct rs6000_opt_var {
- const char *name; /* option name */
- size_t global_offset; /* offset of the option in global_options. */
- size_t target_offset; /* offset of the option in target optiosn. */
-};
+/* Inner function to set the flags for a given option. Return true if the
+ option was found. */
-static struct rs6000_opt_var const rs6000_opt_vars[] =
+static bool
+rs6000_find_target_option (const char *name)
{
- { "friz",
- offsetof (struct gcc_options, x_TARGET_FRIZ),
- offsetof (struct cl_target_option, x_TARGET_FRIZ), },
- { "avoid-indexed-addresses",
- offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
- offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
- { "paired",
- offsetof (struct gcc_options, x_rs6000_paired_float),
- offsetof (struct cl_target_option, x_rs6000_paired_float), },
- { "longcall",
- offsetof (struct gcc_options, x_rs6000_default_long_calls),
- offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
-};
+ size_t i, j;
+ bool invert = false;
+ const struct rs6000_opt_mask *opts;
+ size_t n_opts;
+ int *flags, *explicit_flags;
+
+ if (strncmp (name, "no-", 3) == 0)
+ {
+ invert = true;
+ name += 3;
+ }
+
+ for (i = 0; i < 2; i++)
+ {
+ if (i == 0)
+ {
+ opts = rs6000_opt_masks;
+ n_opts = ARRAY_SIZE (rs6000_opt_masks);
+ flags = &target_flags;
+ explicit_flags = &target_flags_explicit;
+ }
+ else
+ {
+ opts = rs6000_opt_masks2;
+ n_opts = ARRAY_SIZE (rs6000_opt_masks2);
+ flags = &rs6000_flags2;
+ explicit_flags = &rs6000_flags2_explicit;
+ }
+
+ for (j = 0; j < n_opts; j++)
+ if (opts[j].valid_target && strcmp (name, opts[j].name) == 0)
+ {
+ int mask = opts[j].mask;
+
+ *explicit_flags |= mask;
+
+ if (opts[j].invert)
+ invert = !invert;
+
+ if (invert)
+ *flags &= ~mask;
+ else
+ *flags |= mask;
+ return true;
+ }
+ }
+
+ return false;
+}
/* Inner function to handle attribute((target("..."))) and #pragma GCC target
parsing. Return true if there were no errors. */
@@ -27500,7 +27572,6 @@ rs6000_inner_target_options (tree args,
while ((q = strtok (p, ",")) != NULL)
{
bool error_p = false;
- bool not_valid_p = false;
const char *cpu_opt = NULL;
p = NULL;
@@ -27526,59 +27597,15 @@ rs6000_inner_target_options (tree args,
cpu_opt = q+5;
}
}
- else
+ else if (rs6000_find_target_option (q))
{
- size_t i;
- bool invert = false;
- char *r = q;
-
- error_p = true;
- if (strncmp (r, "no-", 3) == 0)
- {
- invert = true;
- r += 3;
- }
-
- for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
- if (strcmp (r, rs6000_opt_masks[i].name) == 0)
- {
- int mask = rs6000_opt_masks[i].mask;
-
- if (!rs6000_opt_masks[i].valid_target)
- not_valid_p = true;
- else
- {
- error_p = false;
- target_flags_explicit |= mask;
-
- /* VSX needs altivec, so -mvsx automagically sets
- altivec. */
- if (mask == MASK_VSX && !invert)
- mask |= MASK_ALTIVEC;
-
- if (rs6000_opt_masks[i].invert)
- invert = !invert;
-
- if (invert)
- target_flags &= ~mask;
- else
- target_flags |= mask;
- }
- break;
- }
-
- if (error_p && !not_valid_p)
- {
- for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
- if (strcmp (r, rs6000_opt_vars[i].name) == 0)
- {
- size_t j = rs6000_opt_vars[i].global_offset;
- *((int *) ((char *)&global_options + j)) = !invert;
- error_p = false;
- break;
- }
- }
+ /* VSX needs altivec, so attribute((target("vsx")))
+ automagically sets altivec. */
+ if (TARGET_VSX)
+ target_flags |= MASK_ALTIVEC;
}
+ else
+ error_p = true;
if (error_p)
{
@@ -27599,8 +27626,6 @@ rs6000_inner_target_options (tree args,
if (cpu_opt)
error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
q, esuffix);
- else if (not_valid_p)
- error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
else
error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
}
@@ -27768,6 +27793,7 @@ rs6000_pragma_target_parse (tree args, t
struct cl_target_option *prev_opt, *cur_opt;
unsigned prev_bumask, cur_bumask, diff_bumask;
int prev_flags, cur_flags, diff_flags;
+ int prev_flags2, cur_flags2, diff_flags2;
if (TARGET_DEBUG_TARGET)
{
@@ -27818,24 +27844,29 @@ rs6000_pragma_target_parse (tree args, t
prev_opt = TREE_TARGET_OPTION (prev_tree);
prev_bumask = prev_opt->x_rs6000_builtin_mask;
prev_flags = prev_opt->x_target_flags;
+ prev_flags2 = prev_opt->x_rs6000_flags2;
cur_opt = TREE_TARGET_OPTION (cur_tree);
cur_flags = cur_opt->x_target_flags;
+ cur_flags2 = cur_opt->x_rs6000_flags2;
cur_bumask = cur_opt->x_rs6000_builtin_mask;
diff_bumask = (prev_bumask ^ cur_bumask);
diff_flags = (prev_flags ^ cur_flags);
+ diff_flags2 = (prev_flags2 ^ cur_flags2);
- if ((diff_flags != 0) || (diff_bumask != 0))
+ if ((diff_flags != 0) || (diff_bumask != 0) || (diff_flags2 != 0))
{
/* Delete old macros. */
rs6000_target_modify_macros_ptr (false,
prev_flags & diff_flags,
+ prev_flags2 & diff_flags2,
prev_bumask & diff_bumask);
/* Define new macros. */
rs6000_target_modify_macros_ptr (true,
cur_flags & diff_flags,
+ cur_flags2 & diff_flags2,
cur_bumask & diff_bumask);
}
}
@@ -27922,12 +27953,91 @@ rs6000_set_current_function (tree fndecl
}
+/* Decode the various flags in target_flags, rs6000_flags2, and
+ rs6000_builtin_mask. */
+
+static void
+rs6000_print_flags_internal (FILE *file, int flags, int indent,
+ const char *hdr, const char *prefix,
+ const struct rs6000_opt_mask *opts,
+ size_t n_elements)
+{
+ size_t i;
+ const char *final = ", <none>";
+ const char *nl = "\n";
+ const char *comma = ", ";
+ int start_column;
+ size_t column;
+ size_t max_column = 98;
+
+ if (indent)
+ fprintf (file, "%*s", indent, "");
+
+ column = start_column = indent + fprintf (file, DEBUG_FMT_X, hdr, flags) + 2;
+ for (i = 0; i < n_elements; i++)
+ if ((flags & opts[i].mask) != 0)
+ {
+ const char *no_str = opts[i].invert ? "no-" : "";
+ size_t len = (strlen (comma)
+ + strlen (prefix)
+ + strlen (no_str)
+ + strlen (opts[i].name));
+
+ column += len;
+ if (column > max_column)
+ {
+ fprintf (stderr, ", \\\n%*s", start_column, "");
+ column = start_column + len;
+ comma = "";
+ nl = "\n\n";
+ }
+
+ fprintf (file, "%s%s%s%s", comma, prefix, no_str, opts[i].name);
+ flags &= ~ opts[i].mask;
+ comma = ", ";
+ final = "";
+ }
+
+ fputs (final, file);
+ fputs (nl, file);
+}
+
+static void
+rs6000_print_target_flags (FILE *file, int mask, int indent, const char *hdr)
+{
+ rs6000_print_flags_internal (file, mask, indent, hdr, "-m",
+ rs6000_opt_masks,
+ ARRAY_SIZE (rs6000_opt_masks));
+}
+
+static void
+rs6000_print_rs6000_flags2 (FILE *file, int mask, int indent, const char *hdr)
+{
+ rs6000_print_flags_internal (file, mask, indent, hdr, "-m",
+ rs6000_opt_masks2,
+ ARRAY_SIZE (rs6000_opt_masks2));
+}
+
+/* Decode the builtin flags. */
+
+static void
+rs6000_print_builtin_flags (FILE *file, unsigned mask, int indent,
+ const char *hdr)
+{
+ rs6000_print_flags_internal (file, (int)mask, indent, hdr, "",
+ rs6000_builtin_mask_names,
+ ARRAY_SIZE (rs6000_builtin_mask_names));
+}
+
+
/* Save the current options */
static void
rs6000_function_specific_save (struct cl_target_option *ptr)
{
ptr->rs6000_target_flags_explicit = target_flags_explicit;
+ ptr->x_rs6000_flags2 = rs6000_flags2;
+ ptr->x_rs6000_flags2_explicit = rs6000_flags2_explicit;
}
/* Restore the current options */
@@ -27936,6 +28046,8 @@ static void
rs6000_function_specific_restore (struct cl_target_option *ptr)
{
target_flags_explicit = ptr->rs6000_target_flags_explicit;
+ rs6000_flags2 = ptr->x_rs6000_flags2;
+ rs6000_flags2_explicit = ptr->x_rs6000_flags2_explicit;
(void) rs6000_option_override_internal (false);
}
@@ -27945,37 +28057,13 @@ static void
rs6000_function_specific_print (FILE *file, int indent,
struct cl_target_option *ptr)
{
- size_t i;
- int flags = ptr->x_target_flags;
- unsigned bu_mask = ptr->x_rs6000_builtin_mask;
-
- /* Print the various mask options. */
- for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
- if ((flags & rs6000_opt_masks[i].mask) != 0)
- {
- flags &= ~ rs6000_opt_masks[i].mask;
- fprintf (file, "%*s-m%s%s\n", indent, "",
- rs6000_opt_masks[i].invert ? "no-" : "",
- rs6000_opt_masks[i].name);
- }
+ rs6000_print_target_flags (file, ptr->x_target_flags, indent,
+ "target_flags");
+ rs6000_print_rs6000_flags2 (file, ptr->x_rs6000_flags2, indent,
+ "rs6000_flags2");
- /* Print the various options that are variables. */
- for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
- {
- size_t j = rs6000_opt_vars[i].target_offset;
- if (((signed char *) ptr)[j])
- fprintf (file, "%*s-m%s\n", indent, "",
- rs6000_opt_vars[i].name);
- }
-
- /* Print the various builtin flags. */
- fprintf (file, "%*sbuiltin mask = 0x%x\n", indent, "", bu_mask);
- for (i = 0; i < ARRAY_SIZE (rs6000_builtin_mask_names); i++)
- if ((bu_mask & rs6000_builtin_mask_names[i].mask) != 0)
- {
- fprintf (file, "%*s%s builtins supported\n", indent, "",
- rs6000_builtin_mask_names[i].name);
- }
+ rs6000_print_builtin_flags (file, ptr->x_rs6000_builtin_mask, indent,
+ "builtins");
}
===================================================================
@@ -1,5 +1,5 @@
/* Enable 750cl paired single support.
- Copyright (C) 2007, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2007, 2009, 2012 Free Software Foundation, Inc.
Contributed by Revital Eres (eres@il.ibm.com)
This file is part of GCC.
@@ -22,8 +22,7 @@
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
-#undef TARGET_PAIRED_FLOAT
-#define TARGET_PAIRED_FLOAT rs6000_paired_float
+#define HAVE_PAIRED_FLOAT 1
#undef ASM_CPU_SPEC
#define ASM_CPU_SPEC "-m750cl"
===================================================================
@@ -67,10 +67,6 @@
#define PPC405_ERRATUM77 0
#endif
-#ifndef TARGET_PAIRED_FLOAT
-#define TARGET_PAIRED_FLOAT 0
-#endif
-
#ifdef HAVE_AS_POPCNTB
#define ASM_CPU_POWER5_SPEC "-mpower5"
#else
@@ -327,6 +323,10 @@ extern const char *host_detect_local_cpu
#define TARGET_DEFAULT (MASK_MULTIPLE | MASK_STRING)
+#ifndef TARGET_DEFAULT_FLAGS2
+#define TARGET_DEFAULT_FLAGS2 (OPTION_MASK_FRIZ)
+#endif
+
/* FPU operations supported.
Each use of TARGET_SINGLE_FLOAT or TARGET_DOUBLE_FLOAT must
also test TARGET_HARD_FLOAT. */
@@ -336,6 +336,12 @@ extern const char *host_detect_local_cpu
#define TARGET_SIMPLE_FPU 0
#define TARGET_XILINX_FPU 0
+/* Map options set in the 2nd flags word back to TARGET_xxx. */
+#define TARGET_FRIZ OPTION_FRIZ
+#define TARGET_AVOID_XFORM OPTION_AVOID_XFORM
+#define TARGET_LONG_CALLS OPTION_LONG_CALLS
+#define TARGET_PAIRED_FLOAT OPTION_PAIRED_FLOAT
+
/* Recast the processor type to the cpu attribute. */
#define rs6000_cpu_attr ((enum attr_cpu)rs6000_cpu)
@@ -465,6 +471,9 @@ extern int rs6000_vector_align[];
#define TARGET_FCTIDUZ TARGET_POPCNTD
#define TARGET_FCTIWUZ TARGET_POPCNTD
+/* Explicit secondary flag options that were set. */
+#define rs6000_flags2_explicit global_options_set.x_rs6000_flags2
+
/* For power systems, we want to enable Altivec and VSX builtins even if the
user did not use -maltivec or -mvsx to allow the builtins to be used inside
of #pragma GCC target or the target attribute to change the code level for a
@@ -2273,29 +2282,34 @@ extern int frame_pointer_needed;
#define RS6000_BTC_MEM RS6000_BTC_MISC /* load/store touches mem. */
#define RS6000_BTC_SAT RS6000_BTC_MISC /* saturate sets VSCR. */
-/* Builtin targets. For now, we reuse the masks for those options that are in
- target flags, and pick two random bits for SPE and paired which aren't in
- target_flags. */
-#define RS6000_BTM_ALWAYS 0 /* Always enabled. */
-#define RS6000_BTM_ALTIVEC MASK_ALTIVEC /* VMX/altivec vectors. */
-#define RS6000_BTM_VSX MASK_VSX /* VSX (vector/scalar). */
-#define RS6000_BTM_SPE MASK_STRING /* E500 */
-#define RS6000_BTM_PAIRED MASK_MULHW /* 750CL paired insns. */
-#define RS6000_BTM_FRE MASK_POPCNTB /* FRE instruction. */
-#define RS6000_BTM_FRES MASK_PPC_GFXOPT /* FRES instruction. */
-#define RS6000_BTM_FRSQRTE MASK_PPC_GFXOPT /* FRSQRTE instruction. */
-#define RS6000_BTM_FRSQRTES MASK_POPCNTB /* FRSQRTES instruction. */
-#define RS6000_BTM_POPCNTD MASK_POPCNTD /* Target supports ISA 2.06. */
-#define RS6000_BTM_CELL MASK_FPRND /* Target is cell powerpc. */
+/* Builtin targets. Originally these were bits set in target_flags, but now
+ that we have 2 words of target flags, define the builtin bits
+ separately. */
+#define RS6000_BTM_ALWAYS 0x0000 /* Always enabled. */
+#define RS6000_BTM_ALTIVEC 0x0001 /* VMX/altivec vectors. */
+#define RS6000_BTM_VSX 0x0002 /* VSX (vector/scalar). */
+#define RS6000_BTM_SPE 0x0004 /* E500 */
+#define RS6000_BTM_PAIRED 0x0008 /* 750CL paired insns. */
+#define RS6000_BTM_GFXOPT 0x0010 /* PowerPC Graphics group. */
+#define RS6000_BTM_CELL 0x0020 /* Target is cell powerpc. */
+#define RS6000_BTM_POPCNTB 0x0040 /* ISA 2.03 (power5). */
+#define RS6000_BTM_FPRND 0x0080 /* ISA 2.04 (power5+). */
+#define RS6000_BTM_POPCNTD 0x0100 /* ISA 2.06. */
+
+#define RS6000_BTM_FRE RS6000_BTM_POPCNTB /* FRE insn. */
+#define RS6000_BTM_FRES RS6000_BTM_GFXOPT /* FRES insn. */
+#define RS6000_BTM_FRSQRTE RS6000_BTM_GFXOPT /* FRSQRTE insn. */
+#define RS6000_BTM_FRSQRTES RS6000_BTM_POPCNTB /* FRSQRTES insn. */
#define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \
| RS6000_BTM_VSX \
- | RS6000_BTM_FRE \
- | RS6000_BTM_FRES \
- | RS6000_BTM_FRSQRTE \
- | RS6000_BTM_FRSQRTES \
- | RS6000_BTM_POPCNTD \
- | RS6000_BTM_CELL)
+ | RS6000_BTM_SPE \
+ | RS6000_BTM_PAIRED \
+ | RS6000_BTM_GFXOPT \
+ | RS6000_BTM_CELL \
+ | RS6000_BTM_POPCNTB \
+ | RS6000_BTM_FPRND \
+ | RS6000_BTM_POPCNTD)
/* Define builtin enum index. */
===================================================================
@@ -26,9 +26,10 @@
Please keep this list in order, and don't forget to update the documentation
in invoke.texi when adding a new processor or flag.
- Before including this file, define a macro:
+ Before including this file, define two macros:
RS6000_CPU (NAME, CPU, FLAGS)
+ RS6000_CPU2 (NAME, CPU, FLAGS, FLAGS2)
where the arguments are the fields of struct rs6000_ptt. */
@@ -94,12 +95,18 @@ RS6000_CPU ("power5", PROCESSOR_POWER5,
| MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB)
RS6000_CPU ("power5+", PROCESSOR_POWER5, MASK_POWERPC64 | MASK_PPC_GPOPT
| MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND)
-RS6000_CPU ("power6", PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT
- | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND
- | MASK_CMPB | MASK_DFP | MASK_RECIP_PRECISION)
-RS6000_CPU ("power6x", PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT
- | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND
- | MASK_CMPB | MASK_DFP | MASK_MFPGPR | MASK_RECIP_PRECISION)
+/* Avoid indexed addressing when targeting Power6 in order to avoid the
+ DERAT mispredict penalty. However the LVE and STVE altivec instructions
+ need indexed accesses and the type used is the scalar type of the element
+ being loaded or stored. */
+RS6000_CPU2 ("power6", PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT
+ | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND
+ | MASK_CMPB | MASK_DFP | MASK_RECIP_PRECISION,
+ OPTION_MASK_AVOID_XFORM)
+RS6000_CPU2 ("power6x", PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT
+ | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND
+ | MASK_CMPB | MASK_DFP | MASK_MFPGPR | MASK_RECIP_PRECISION,
+ OPTION_MASK_AVOID_XFORM)
RS6000_CPU ("power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
| MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
===================================================================
@@ -185,8 +185,8 @@ extern void rs6000_cpu_cpp_builtins (str
#ifdef TREE_CODE
extern bool rs6000_pragma_target_parse (tree, tree);
#endif
-extern void rs6000_target_modify_macros (bool, int, unsigned);
-extern void (*rs6000_target_modify_macros_ptr) (bool, int, unsigned);
+extern void rs6000_target_modify_macros (bool, int, int, unsigned);
+extern void (*rs6000_target_modify_macros_ptr) (bool, int, int, unsigned);
#if TARGET_MACHO
char *output_call (rtx, rtx *, int, int);