I've rewritten my rs6000 infrastructure patch to allow more target switches, so
that it does not change the flags currently in the target_flags.  This should
reduce the number of changes due to TARGET_<xxx> being called OPTION_<xxx>, and
MASK_<xxx> being called OPTION_MASK_<xxx>.  In addition, since it might be
possible to build a powerpc 32-bit compiler on a 32-bit system without long
long support, I don't use HOST_WIDE_INT any more to get 64-bit ints, but
instead just use plain ints.

Instead it adds a second flags word that the cpu definitions in rs6000-cpus.def
can set.  I moved the -mavoid-indexed-addresses processing into this second
word, and had the power6 cpu definition set this second word to make sure that
the logic works correctly.  I also moved the -mpaired support into this frame
work.

I also have expanded the debug information that -mdebug=reg prints out to print
all of the flags switches.

Finally, in doing the builds, I noticed some signed vs. unsigned warnings in
the *builtin_expand functions that were caused by comparing an enum to an
unsigned integer, and I fixed these as well.

I have checked this by doing bootstrap builds and there were no regressions in
the test suite.  In addition, I built a linuxpaired compiler, and verified that
the defaults and -mpaired support are exactly the same.  Are these patches ok
to check in?

2012-10-05  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        * common/config/rs6000/rs6000-common.c (rs6000_handle_option):
        Give an error for -mpaired if the compiler is not configured for
        paired support.

        * config/rs6000/rs6000.opt (rs6000_flags2): Add second target
        flags word, and move some options to use this new flag word.
        Save/restore the second flag word.  Add support for initializing
        the second flags word for -mcpu=<xxx> selection.  Print all of the
        options set if -mdebug=reg. Change mapping of RS6000_BTM_* not to
        use target flags masks.  Fix unsigned/signed warnings.  Add more
        specific warnings for trying to use builtins with the wrong cpu.
        (x_rs6000_flags2): Likewise.
        (x_rs6000_flags2_explicit): Likewise.
        (-mfriz): Likewise.
        (-mavoid-indexed-addresses): Likewise.
        (-mpaired): Likewise.
        (-mlongcall): Likewise.
        * config/rs6000/rs6000-c.c (rs6000_pragma_longcall): Likewise.
        (rs6000_define_or_undefine_macro): Likewise.
        (rs6000_target_modify_macros): Likewise.
        * config/rs6000/rs6000.c (rs6000_target_modify_macros_ptr):
        Likewise.
        (POWERPC_MASKS2): Likewise.
        (struct rs6000_ptt): Likewise.
        (RS6000_CPU): Likewise.
        (RS6000_CPU2): Likewise.
        (DEBUG_FMT_X): Likewise.
        (DEBUG_FMT_S2): Likewise.
        (rs6000_debug_reg_global): Likewise.
        (darwin_rs6000_override_options): Likewise.
        (rs6000_builtin_mask_calculate): Likewise.
        (rs6000_option_override_internal): Likewise.
        (init_cumulative_args): Likewise.
        (altivec_expand_ld_builtin): Likewise.
        (altivec_expand_st_builtin): Likewise.
        (altivec_expand_dst_builtin): Likewise.
        (paired_expand_builtin): Likewise.
        (spe_expand_builtin): Likewise.
        (rs6000_invalid_builtin): Likewise.
        (rs6000_handle_longcall_attribute): Likewise.
        (rs6000_set_default_type_attributes): Likewise.
        (rs6000_opt_masks2): Likewise.
        (rs6000_builtin_mask_names): Likewise.
        (rs6000_opt_var): Likewise.
        (rs6000_opt_var2): Likewise.
        (rs6000_find_target_option): Likewise.
        (rs6000_inner_target_options): Likewise.
        (rs6000_pragma_target_parse): Likewise.
        (rs6000_print_flags_internal): Likewise.
        (rs6000_print_target_flags): Likewise.
        (rs6000_print_rs6000_flags2): Likewise.
        (rs6000_print_builtin_types): Likewise.
        (rs6000_function_specific_save): Likewise.
        (rs6000_function_specific_restore): Likewise.
        (rs6000_function_specific_print): Likewise.
        * config/rs6000/750cl.h (TARGET_PAIRED_FLOAT): Likewise.
        (HAVE_PAIRED_FLOAT): Likewise.
        * config/rs6000/rs6000.h (TARGET_PAIRED_FLOAT): Likewise.
        (TARGET_DEFAULT_FLAGS2): Likewise.
        (TARGET_FRIZ): Likewise.
        (TARGET_AVOID_XFORM): Likewise.
        (TARGET_LONG_CALLS): Likewise.
        (TARGET_PAIRED_FLOAT): Likewise.
        (RS6000_BTM_ALWAYS): Likewise.
        (RS6000_BTM_ALTIVEC): Likewise.
        (RS6000_BTM_VSX): Likewise.
        (RS6000_BTM_SPE): Likewise.
        (RS6000_BTM_PAIRED): Likewise.
        (RS6000_BTM_GFXOPT): Likewise.
        (RS6000_BTM_CELL): Likewise.
        (RS6000_BTM_POPCNTB): Likewise.
        (RS6000_BTM_FPRND): Likewise.
        (RS6000_BTM_POPCNTD): Likewise.
        (RS6000_BTM_FRE): Likewise.
        (RS6000_BTM_FRES): Likewise.
        (RS6000_BTM_FRSQRTE): Likewise.
        (RS6000_BTM_FRSQRTES): Likewise.
        (RS6000_BTM_COMMON): Likewise.
        * config/rs6000/rs6000-cpus.def (power6 cpu): Likewise.
        (power6x cpu): Likewise.
        * config/rs6000/rs6000-protos.h (rs6000_target_modify_macros):
        Likewise.
        (rs6000_target_modify_macros_ptr): Likewise.

-- 
Michael Meissner, IBM
5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA
meiss...@linux.vnet.ibm.com     fax +1 (978) 399-6899
Index: gcc/common/config/rs6000/rs6000-common.c
===================================================================
--- gcc/common/config/rs6000/rs6000-common.c    (revision 192041)
+++ gcc/common/config/rs6000/rs6000-common.c    (working copy)
@@ -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;
 }
Index: gcc/config/rs6000/rs6000.opt
===================================================================
--- gcc/config/rs6000/rs6000.opt        (revision 192041)
+++ gcc/config/rs6000/rs6000.opt        (working copy)
@@ -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
Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c        (revision 192041)
+++ gcc/config/rs6000/rs6000-c.c        (working copy)
@@ -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)
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 192041)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -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");
 }
 
 
Index: gcc/config/rs6000/750cl.h
===================================================================
--- gcc/config/rs6000/750cl.h   (revision 192041)
+++ gcc/config/rs6000/750cl.h   (working copy)
@@ -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 (e...@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"
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h  (revision 192041)
+++ gcc/config/rs6000/rs6000.h  (working copy)
@@ -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.  */
 
Index: gcc/config/rs6000/rs6000-cpus.def
===================================================================
--- gcc/config/rs6000/rs6000-cpus.def   (revision 192041)
+++ gcc/config/rs6000/rs6000-cpus.def   (working copy)
@@ -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
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
--- gcc/config/rs6000/rs6000-protos.h   (revision 192041)
+++ gcc/config/rs6000/rs6000-protos.h   (working copy)
@@ -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);

Reply via email to