aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>2013-11-24 14:23:54 +0000
committerWilliam Schmidt <wschmidt@gcc.gnu.org>2013-11-24 14:23:54 +0000
commit523c1561c9ca9cbf980ccb61ce198c70c866a104 (patch)
tree188e7f0a54cdfec747cac21b63a82f0716d43a54
parent9c7d8960a4dc32fa3eb9d0756da2d1fd6f1a423e (diff)
downloadgcc-523c1561c9ca9cbf980ccb61ce198c70c866a104.zip
gcc-523c1561c9ca9cbf980ccb61ce198c70c866a104.tar.gz
gcc-523c1561c9ca9cbf980ccb61ce198c70c866a104.tar.bz2
rs6000.c (rs6000_expand_vec_perm_const_1): Correct for little endian.
2013-11-24 Bill Schmidt <wschmidt@linux.vnet.ibm.com> * config/rs6000/rs6000.c (rs6000_expand_vec_perm_const_1): Correct for little endian. From-SVN: r205333
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/rs6000/rs6000.c15
2 files changed, 20 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4d20aef..126109e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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".
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 7ada5d2..599cf49 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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));