2013-11-24 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
authorwschmidt <wschmidt@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 24 Nov 2013 14:23:54 +0000 (14:23 +0000)
committerwschmidt <wschmidt@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 24 Nov 2013 14:23:54 +0000 (14:23 +0000)
* config/rs6000/rs6000.c (rs6000_expand_vec_perm_const_1): Correct
for little endian.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205333 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index 4d20aef..126109e 100644 (file)
@@ -1,3 +1,8 @@
+2013-11-24  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       * config/rs6000/rs6000.c (rs6000_expand_vec_perm_const_1): Correct
+       for little endian.
+
 2013-11-24  H.J. Lu  <hongjiu.lu@intel.com>
 
        * graphite-sese-to-poly.c: Don't include extra "expr.h".
index 7ada5d2..599cf49 100644 (file)
@@ -30046,6 +30046,21 @@ rs6000_expand_vec_perm_const_1 (rtx target, rtx op0, rtx op1,
       gcc_assert (GET_MODE_NUNITS (vmode) == 2);
       dmode = mode_for_vector (GET_MODE_INNER (vmode), 4);
 
+      /* For little endian, swap operands and invert/swap selectors
+        to get the correct xxpermdi.  The operand swap sets up the
+        inputs as a little endian array.  The selectors are swapped
+        because they are defined to use big endian ordering.  The
+        selectors are inverted to get the correct doublewords for
+        little endian ordering.  */
+      if (!BYTES_BIG_ENDIAN)
+       {
+         int n;
+         perm0 = 3 - perm0;
+         perm1 = 3 - perm1;
+         n = perm0, perm0 = perm1, perm1 = n;
+         x = op0, op0 = op1, op1 = x;
+       }
+
       x = gen_rtx_VEC_CONCAT (dmode, op0, op1);
       v = gen_rtvec (2, GEN_INT (perm0), GEN_INT (perm1));
       x = gen_rtx_VEC_SELECT (vmode, x, gen_rtx_PARALLEL (VOIDmode, v));