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;


Reply via email to