diff mbox

Improve additions involving SP on Thumb-1

Message ID 4C44E173.4050300@codesourcery.com
State New
Headers show

Commit Message

Bernd Schmidt July 19, 2010, 11:36 p.m. UTC
Thumb-1 supports a range of up to 1020 for add insns of the form

  add rn, sp, #1020

If the constant is somewhat larger, we can do it with a sequence of two
adds, which is better than the available alternatives:

-       ldr     r4, .L64+12
-       add     r4, r4, sp
+       add     r4, sp, #1020
+       add     r4, r4, #224

or

-       mov     r0, #156
-       lsl     r0, r0, #3
-       add     r0, r0, sp
+       add     r0, sp, #1020
+       add     r0, r0, #228

It's conceivable that we might even prefer a three-insn add sequence
over either of these alternatives, but the following patch doesn't do this.

Regression tested on arm-linux, with one extra timeout (which comes and
goes - it went away vs. baseline for a different set of compiler flags).
 Ok?


Bernd
* config/arm/arm.md (thumb1_addsi3): Add alternative and split for
	computing the sum of the stack pointer and a large constant.
	* config/arm/constraints.md (M): Remove superfluous parentheses.
	(Pc): New constraint.

Comments

Richard Earnshaw July 20, 2010, 8:26 a.m. UTC | #1
On Tue, 2010-07-20 at 01:36 +0200, Bernd Schmidt wrote:
> Thumb-1 supports a range of up to 1020 for add insns of the form
> 
>   add rn, sp, #1020
> 
> If the constant is somewhat larger, we can do it with a sequence of two
> adds, which is better than the available alternatives:
> 
> -       ldr     r4, .L64+12
> -       add     r4, r4, sp
> +       add     r4, sp, #1020
> +       add     r4, r4, #224
> 
> or
> 
> -       mov     r0, #156
> -       lsl     r0, r0, #3
> -       add     r0, r0, sp
> +       add     r0, sp, #1020
> +       add     r0, r0, #228
> 
> It's conceivable that we might even prefer a three-insn add sequence
> over either of these alternatives, but the following patch doesn't do this.
> 
> Regression tested on arm-linux, with one extra timeout (which comes and
> goes - it went away vs. baseline for a different set of compiler flags).
>  Ok?
> 
> 
> Bernd

Please also update the list of multi-list constants in the comment near
the start of constraints.md.

OK with that change.

R.
diff mbox

Patch

Index: config/arm/arm.md
===================================================================
--- config/arm/arm.md	(revision 162287)
+++ config/arm/arm.md	(working copy)
@@ -638,9 +638,9 @@  (define_insn_and_split "*arm_addsi3"
 )
 
 (define_insn_and_split "*thumb1_addsi3"
-  [(set (match_operand:SI          0 "register_operand" "=l,l,l,*rk,*hk,l,k,l,l")
-	(plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,k,k,0,l")
-		 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,M,O,Pa,Pb")))]
+  [(set (match_operand:SI          0 "register_operand" "=l,l,l,*rk,*hk,l,k,l,l,l")
+	(plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,k,k,0,l,k")
+		 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,M,O,Pa,Pb,Pc")))]
   "TARGET_THUMB1"
   "*
    static const char * const asms[] = 
@@ -653,6 +653,7 @@  (define_insn_and_split "*thumb1_addsi3"
      \"add\\t%0, %1, %2\",
      \"add\\t%0, %1, %2\",
      \"#\",
+     \"#\",
      \"#\"
    };
    if ((which_alternative == 2 || which_alternative == 6)
@@ -662,21 +663,27 @@  (define_insn_and_split "*thumb1_addsi3"
    return asms[which_alternative];
   "
   "&& reload_completed && CONST_INT_P (operands[2])
-   && operands[1] != stack_pointer_rtx
-   && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255)"
+   && ((operands[1] != stack_pointer_rtx
+        && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255))
+       || (operands[1] == stack_pointer_rtx
+ 	   && INTVAL (operands[2]) > 1020))"
   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
   {
     HOST_WIDE_INT offset = INTVAL (operands[2]);
-    if (offset > 255)
-      offset = 255;
-    else if (offset < -255)
-      offset = -255;
-    
+    if (operands[1] == stack_pointer_rtx)
+      offset -= 1020;
+    else
+      {
+        if (offset > 255)
+	  offset = 255;
+	else if (offset < -255)
+	  offset = -255;
+      }
     operands[3] = GEN_INT (offset);
     operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
   }
-  [(set_attr "length" "2,2,2,2,2,2,2,4,4")]
+  [(set_attr "length" "2,2,2,2,2,2,2,4,4,4")]
 )
 
 ;; Reloading and elimination of the frame pointer can
Index: config/arm/constraints.md
===================================================================
--- config/arm/constraints.md	(revision 162287)
+++ config/arm/constraints.md	(working copy)
@@ -122,7 +122,7 @@  (define_constraint "M"
  (and (match_code "const_int")
       (match_test "TARGET_32BIT ? ((ival >= 0 && ival <= 32)
 				 || ((ival & (ival - 1)) == 0))
-		   : ((ival >= 0 && ival <= 1020) && ((ival & 3) == 0))")))
+		   : ival >= 0 && ival <= 1020 && (ival & 3) == 0")))
 
 (define_constraint "N"
  "Thumb-1 state a constant in the range 0-31."
@@ -148,6 +148,12 @@  (define_constraint "Pb"
        (match_test "TARGET_THUMB1 && ival >= -262 && ival <= 262
 		    && (ival > 255 || ival < -255)")))
 
+(define_constraint "Pc"
+  "@internal In Thumb-1 state a constant that is in the range 1021 to 1275"
+  (and (match_code "const_int")
+       (match_test "TARGET_THUMB1
+  		    && ival > 1020 && ival <= 1275")))
+
 (define_constraint "Ps"
   "@internal In Thumb-2 state a constant in the range -255 to +255"
   (and (match_code "const_int")