This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][m68k] PR target/36134 Prefer LEA over ADD.L


The attached patch attempts to resolve pr36134 by preferring the 4-byte LEA instruction over the longer 6-byte ADD.L instruction, where appropriate.

This patch differs somewhat from the original patch posted by Gunnar von Boehm in that it only prefers LEA when it would not use an extra register. It also takes the split condition and scheduling attributes into account, and adds a test-case.

I've run a full test with no regressions.

OK?

Andrew Stubbs
2008-11-13  Maxim Kuvyrkov  <maxim@codesourcery.com>
	    Andrew Stubbs  <ams@codesourcery.com>
	    Gunnar Von Boehn  <gunnar@genesi-usa.com>

	gcc/
	PR target/36134
	* config/m68k/m68k.md (addsi3_5200): Add a new alternative preferring
	the shorter LEA insn over ADD.L where possible.

	gcc/testsuite/
	PR target/36134
	* gcc.target/m68k/pr36134.c: New test.

---
 src/gcc-4.3/gcc/config/m68k/m68k.md                 |   25 ++++++++++----------
 src/gcc-4.3/gcc/testsuite/gcc.target/m68k/pr36134.c |   23 ++++++++++++++++++
 2 files changed, 36 insertions(+), 12 deletions(-)

Index: issue3283/src/gcc-4.3/gcc/config/m68k/m68k.md
===================================================================
--- issue3283.orig/src/gcc-4.3/gcc/config/m68k/m68k.md	2008-11-12 15:07:27.000000000 +0000
+++ issue3283/src/gcc-4.3/gcc/config/m68k/m68k.md	2008-11-13 12:42:12.000000000 +0000
@@ -2368,9 +2368,9 @@
   "* return output_addsi3 (operands);")
 
 (define_insn_and_split "*addsi3_5200"
-  [(set (match_operand:SI 0 "nonimmediate_operand"         "=mr,mr,m,r,  ?a,?a,?a,?a")
-	(plus:SI (match_operand:SI 1 "general_operand"     "%0, 0, 0,0,   a, a, r, a")
-		 (match_operand:SI 2 "general_src_operand" " I, L, d,mrKi,Cj,r, a, J")))]
+  [(set (match_operand:SI 0 "nonimmediate_operand"         "=mr,mr,a,m,r,  ?a, ?a,?a,?a")
+	(plus:SI (match_operand:SI 1 "general_operand"     "%0, 0, 0,0,0,   a,  a, r, a")
+		 (match_operand:SI 2 "general_src_operand" " I, L, J,d,mrKi,Cj, r, a, J")))]
   "TARGET_COLDFIRE"
 {
   switch (which_alternative)
@@ -2382,21 +2382,22 @@
       operands[2] = GEN_INT (- INTVAL (operands[2]));
       return "subq%.l %2,%0";
 
-    case 2:
     case 3:
+    case 4:
       return "add%.l %2,%0";
 
-    case 4:
+    case 5:
       /* move%.l %2,%0\n\tadd%.l %1,%0 */
       return "#";
 
-    case 5:
+    case 6:
       return MOTOROLA ? "lea (%1,%2.l),%0" : "lea %1@(0,%2:l),%0";
 
-    case 6:
+    case 7:
       return MOTOROLA ? "lea (%2,%1.l),%0" : "lea %2@(0,%1:l),%0";
 
-    case 7:
+    case 2:
+    case 8:
       return MOTOROLA ? "lea (%c2,%1),%0" : "lea %1@(%c2),%0";
 
     default:
@@ -2404,16 +2405,16 @@
       return "";
     }
 }
-  "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 4) && !operands_match_p (operands[0], operands[1])"
+  "&& reload_completed && (extract_constrain_insn_cached (insn), which_alternative == 5) && !operands_match_p (operands[0], operands[1])"
   [(set (match_dup 0)
 	(match_dup 2))
    (set (match_dup 0)
 	(plus:SI (match_dup 0)
 		 (match_dup 1)))]
   ""
-  [(set_attr "type" "aluq_l,aluq_l,alu_l,alu_l,*,lea,lea,lea")
-   (set_attr "opy" "2,2,2,2,*,*,*,*")
-   (set_attr "opy_type" "*,*,*,*,*,mem6,mem6,mem5")])
+  [(set_attr "type" "aluq_l,aluq_l,lea,alu_l,alu_l,*,lea,lea,lea")
+   (set_attr "opy" "2,2,*,2,2,*,*,*,*")
+   (set_attr "opy_type" "*,*,mem5,*,*,*,mem6,mem6,mem5")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
Index: issue3283/src/gcc-4.3/gcc/testsuite/gcc.target/m68k/pr36134.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ issue3283/src/gcc-4.3/gcc/testsuite/gcc.target/m68k/pr36134.c	2008-11-12 15:10:47.000000000 +0000
@@ -0,0 +1,23 @@
+/* pr36134.c
+
+   This test ensures that the shorter LEA instruction is used in preference
+   to the longer ADD instruction.  */
+
+/* { dg-do compile }  */
+/* { dg-options "-O2" }  */
+/* { dg-final { scan-assembler "lea" } } */
+/* { dg-final { scan-assembler-not "add" } } */
+
+int *a, *b;
+
+void
+f ()
+{
+  while (a > b)
+    {
+      *a++ = *b++;
+      *a++ = *b++;
+      *a++ = *b++;
+      *a++ = *b++;
+    }
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]