Patchwork [PowerPC] Fix unaligned Altivec load/stores in LE mode

login
register
mail settings
Submitter William J. Schmidt
Date July 24, 2013, 3:19 a.m.
Message ID <1374635951.3633.132.camel@gnopaine>
Download mbox | patch
Permalink /patch/261265/
State New
Headers show

Comments

William J. Schmidt - July 24, 2013, 3:19 a.m.
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  <wschmidt@vnet.linux.ibm.com>
	    Anton Blanchard <anton@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.
David Edelsohn - July 24, 2013, 12:49 p.m.
On Tue, Jul 23, 2013 at 11:19 PM, Bill Schmidt
<wschmidt@linux.vnet.ibm.com> wrote:
> 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  <wschmidt@vnet.linux.ibm.com>
>             Anton Blanchard <anton@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.

Okay.

Thanks, David

Patch

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;