This patch is part of the support needed to properly swap IEEE 128-bit floating
point on little endian systems.  Note, you will need the rs6000.md changes for
this to become effective.

I have built the compiler with this patch and the previous subpatches (1-9).  I
have bootstrapped the compiler with all 16 subpatches installed, and there were
no regressions.  Is it ok to install in the trunk?

2015-10-22  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        * config/rs6000/rs6000.c (rs6000_gen_le_vsx_permute): On little
        endian systems generate a ROTATE insn instead of VEC_SELECT for
        IEEE 128-bit floating point types that can go in vector
        registers.
        (chain_contains_only_swaps): Properly swap IEEE 128-bit floating
        point types that can go in vector registers on little endian
        PowerPC systems.
        (mark_swaps_for_removal): Likewise.
        (rs6000_analyze_swaps): Likewise.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 229194)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -8467,8 +8467,14 @@ rs6000_const_vec (machine_mode mode)
 rtx
 rs6000_gen_le_vsx_permute (rtx source, machine_mode mode)
 {
-  rtx par = gen_rtx_PARALLEL (VOIDmode, rs6000_const_vec (mode));
-  return gen_rtx_VEC_SELECT (mode, source, par);
+  /* Use ROTATE instead of VEC_SELECT on IEEE 128-bit floating point.  */
+  if (FLOAT128_VECTOR_P (mode))
+    return gen_rtx_ROTATE (mode, source, GEN_INT (64));
+  else
+    {
+      rtx par = gen_rtx_PARALLEL (VOIDmode, rs6000_const_vec (mode));
+      return gen_rtx_VEC_SELECT (mode, source, par);
+    }
 }
 
 /* Emit a little-endian load from vector memory location SOURCE to VSX
@@ -35844,7 +35850,7 @@ chain_contains_only_swaps (swap_web_entr
 
   for (; link; link = link->next)
     {
-      if (!VECTOR_MODE_P (GET_MODE (DF_REF_REG (link->ref))))
+      if (!ALTIVEC_OR_VSX_VECTOR_MODE (GET_MODE (DF_REF_REG (link->ref))))
        continue;
 
       if (DF_REF_IS_ARTIFICIAL (link->ref))
@@ -35943,7 +35949,7 @@ mark_swaps_for_removal (swap_web_entry *
        {
          /* Ignore uses for addressability.  */
          machine_mode mode = GET_MODE (DF_REF_REG (use));
-         if (!VECTOR_MODE_P (mode))
+         if (!ALTIVEC_OR_VSX_VECTOR_MODE (mode))
            continue;
 
          struct df_link *link = DF_REF_CHAIN (use);
@@ -36457,10 +36463,11 @@ rs6000_analyze_swaps (function *fun)
                    mode = V4SImode;
                }
 
-             if (VECTOR_MODE_P (mode) || mode == TImode)
+             if (ALTIVEC_OR_VSX_VECTOR_MODE (mode) || mode == TImode)
                {
                  insn_entry[uid].is_relevant = 1;
-                 if (mode == TImode || mode == V1TImode)
+                 if (mode == TImode || mode == V1TImode
+                     || FLOAT128_VECTOR_P (mode))
                    insn_entry[uid].is_128_int = 1;
                  if (DF_REF_INSN_INFO (mention))
                    insn_entry[uid].contains_subreg
@@ -36481,13 +36488,14 @@ rs6000_analyze_swaps (function *fun)
                 isn't sufficient to ensure we union the call into the
                 web with the parameter setup code.  */
              if (mode == DImode && GET_CODE (insn) == SET
-                 && VECTOR_MODE_P (GET_MODE (SET_DEST (insn))))
+                 && ALTIVEC_OR_VSX_VECTOR_MODE (GET_MODE (SET_DEST (insn))))
                mode = GET_MODE (SET_DEST (insn));
 
-             if (VECTOR_MODE_P (mode) || mode == TImode)
+             if (ALTIVEC_OR_VSX_VECTOR_MODE (mode) || mode == TImode)
                {
                  insn_entry[uid].is_relevant = 1;
-                 if (mode == TImode || mode == V1TImode)
+                 if (mode == TImode || mode == V1TImode
+                     || FLOAT128_VECTOR_P (mode))
                    insn_entry[uid].is_128_int = 1;
                  if (DF_REF_INSN_INFO (mention))
                    insn_entry[uid].contains_subreg

Reply via email to