From: Bill Schmidt Date: Sun, 24 Nov 2013 14:23:54 +0000 (+0000) Subject: rs6000.c (rs6000_expand_vec_perm_const_1): Correct for little endian. X-Git-Tag: releases/gcc-4.9.0~2487 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=523c1561c9ca9cbf980ccb61ce198c70c866a104;p=thirdparty%2Fgcc.git rs6000.c (rs6000_expand_vec_perm_const_1): Correct for little endian. 2013-11-24 Bill Schmidt * config/rs6000/rs6000.c (rs6000_expand_vec_perm_const_1): Correct for little endian. From-SVN: r205333 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4d20aefed719..126109e7a88a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2013-11-24 Bill Schmidt + + * config/rs6000/rs6000.c (rs6000_expand_vec_perm_const_1): Correct + for little endian. + 2013-11-24 H.J. Lu * 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 7ada5d231cfc..599cf49570f3 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));