In order to use vperm for aligning loads and stores in little endian mode, we need to reverse the order of the input operands and use lvsl instead of lvsr. This corrects 32 regressions in the test suite when run in LE mode.
Bootstrapped and tested on powerpc64-unknown-linux-gnu in BE mode with no new regressions. Is this ok for trunk? Patch by Anton Blanchard. Thanks, Bill 2013-07-23 Bill Schmidt <wschm...@vnet.linux.ibm.com> Anton Blanchard <an...@au1.ibm.com> * vector.md (vec_realign_load_<mode>): Reorder input operands to vperm for little endian. * rs6000.c (rs6000_expand_builtin): Use lvsr instead of lvsl to create the control mask for a vperm for little endian. Index: gcc/config/rs6000/vector.md =================================================================== --- gcc/config/rs6000/vector.md (revision 201194) +++ gcc/config/rs6000/vector.md (working copy) @@ -936,8 +936,12 @@ (match_operand:V16QI 3 "vlogical_operand" "")] "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" { - emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1], operands[2], - operands[3])); + if (BYTES_BIG_ENDIAN) + emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1], + operands[2], operands[3])); + else + emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[2], + operands[1], operands[3])); DONE; }) Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 201195) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -12351,7 +12351,8 @@ rs6000_expand_builtin (tree exp, rtx target, rtx s case ALTIVEC_BUILTIN_MASK_FOR_LOAD: case ALTIVEC_BUILTIN_MASK_FOR_STORE: { - int icode = (int) CODE_FOR_altivec_lvsr; + int icode = (BYTES_BIG_ENDIAN ? (int) CODE_FOR_altivec_lvsr + : (int) CODE_FOR_altivec_lvsl); enum machine_mode tmode = insn_data[icode].operand[0].mode; enum machine_mode mode = insn_data[icode].operand[1].mode; tree arg;