Patchwork powerpc64le-linux support

login
register
mail settings
Submitter Alan Modra
Date May 5, 2013, 4:35 a.m.
Message ID <20130505043500.GX5221@bubble.grove.modra.org>
Download mbox | patch
Permalink /patch/241501/
State New
Headers show

Comments

Alan Modra - May 5, 2013, 4:35 a.m.
This fixes a couple more little-endian bugs.  bswapdi stores when
!TARGET_LDBRX were being split to two bswapsi but written to the wrong
words because we word swapped twice.  ashrdi3 resulted in a libcall.

I think I have ashrdi3_no_power correct.  For LE, the first reg of a
register pair is the low word, the second the high word, and you use
%L to select the high reg.  (For BE the second reg is the low word and
%L really does stand for low).  So a quick rule of thumb for
converting big-endian register pair patterns to little-endian is
replace all the reg pair %n with %Ln and all %Ln with %n.

	* config/rs6000/rs6000.md (bswapdi 2nd splitter): Don't swap words
	twice for little-endian.
	(ashrdi3_no_power, ashrdi3): Support little-endian.
David Edelsohn - May 5, 2013, 3:05 p.m.
On Sun, May 5, 2013 at 12:35 AM, Alan Modra <amodra@gmail.com> wrote:
> This fixes a couple more little-endian bugs.  bswapdi stores when
> !TARGET_LDBRX were being split to two bswapsi but written to the wrong
> words because we word swapped twice.  ashrdi3 resulted in a libcall.
>
> I think I have ashrdi3_no_power correct.  For LE, the first reg of a
> register pair is the low word, the second the high word, and you use
> %L to select the high reg.  (For BE the second reg is the low word and
> %L really does stand for low).  So a quick rule of thumb for
> converting big-endian register pair patterns to little-endian is
> replace all the reg pair %n with %Ln and all %Ln with %n.
>
>         * config/rs6000/rs6000.md (bswapdi 2nd splitter): Don't swap words
>         twice for little-endian.
>         (ashrdi3_no_power, ashrdi3): Support little-endian.

This is okay.

Thanks, David

Patch

Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 198274)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -2329,16 +2330,14 @@ 
     {
       word_high = change_address (dest, SImode, addr1);
       word_low  = change_address (dest, SImode, addr2);
-      emit_insn (gen_bswapsi2 (word_high, src_si));
-      emit_insn (gen_bswapsi2 (word_low, op3_si));
     }
   else
     {
       word_high = change_address (dest, SImode, addr2);
       word_low  = change_address (dest, SImode, addr1);
-      emit_insn (gen_bswapsi2 (word_low, src_si));
-      emit_insn (gen_bswapsi2 (word_high, op3_si));
     }
+  emit_insn (gen_bswapsi2 (word_high, src_si));
+  emit_insn (gen_bswapsi2 (word_low, op3_si));
 }")
 
 (define_split
@@ -6634,10 +6633,25 @@ 
   [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
 	(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
 		     (match_operand:SI 2 "const_int_operand" "M,i")))]
-  "TARGET_32BIT && !TARGET_POWERPC64 && WORDS_BIG_ENDIAN"
-  "@
-   srawi %0,%1,31\;srawi %L0,%1,%h2
-   srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2"
+  "!TARGET_POWERPC64"
+  "*
+{
+  switch (which_alternative)
+    {
+    default:
+      gcc_unreachable ();
+    case 0:
+      if (WORDS_BIG_ENDIAN)
+        return \"srawi %0,%1,31\;srawi %L0,%1,%h2\";
+      else
+        return \"srawi %L0,%L1,31\;srawi %0,%L1,%h2\";
+    case 1:
+      if (WORDS_BIG_ENDIAN)
+	return \"srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2\";
+      else
+	return \"srwi %0,%1,%h2\;insrwi %0,%L1,%h2,0\;srawi %L0,%L1,%h2\";
+    }
+}"
   [(set_attr "type" "two,three")
    (set_attr "length" "8,12")])
 
@@ -7734,13 +7748,12 @@ 
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
 	(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
 		     (match_operand:SI 2 "reg_or_cint_operand" "")))]
-  "WORDS_BIG_ENDIAN"
+  ""
   "
 {
   if (TARGET_POWERPC64)
     ;
-  else if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT
-	   && WORDS_BIG_ENDIAN)
+  else if (GET_CODE (operands[2]) == CONST_INT)
     {
       emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2]));
       DONE;