PR target/40327
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 13 Jun 2009 12:49:25 +0000 (12:49 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 13 Jun 2009 12:49:25 +0000 (12:49 +0000)
* arm/constraints.md (Pa, Pb): New constraints.
* arm/arm.md (thumb1_addsi3): Support more complex additions.  Add a
split pattern to deal with them.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@148452 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/arm.md
gcc/config/arm/constraints.md

index 37d8bef..c2bdc07 100644 (file)
@@ -1,3 +1,10 @@
+2009-06-13  Richard Earnshaw  <rearnsha@arm.com>
+
+       PR target/40327
+       * arm/constraints.md (Pa, Pb): New constraints.
+       * arm/arm.md (thumb1_addsi3): Support more complex additions.  Add a 
+       split pattern to deal with them.
+
 2009-06-13  Joerg Sonnenberger  <joerg@britannica.bec.de>
 
        * doc/invoke.texi: Add missing option -Wp,OPTION in list,
index 5f3a5e0..40e41c5 100644 (file)
 ;; register.  Trying to reload it will always fail catastrophically,
 ;; so never allow those alternatives to match if reloading is needed.
 
-(define_insn "*thumb1_addsi3"
-  [(set (match_operand:SI          0 "register_operand" "=l,l,l,*rk,*hk,l,!k")
-       (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
-                (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,!M,!O")))]
+(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")))]
   "TARGET_THUMB1"
   "*
    static const char * const asms[] = 
      \"add\\t%0, %0, %2\",
      \"add\\t%0, %0, %2\",
      \"add\\t%0, %1, %2\",
-     \"add\\t%0, %1, %2\"
+     \"add\\t%0, %1, %2\",
+     \"#\",
+     \"#\"
    };
    if ((which_alternative == 2 || which_alternative == 6)
        && GET_CODE (operands[2]) == CONST_INT
      return \"sub\\t%0, %1, #%n2\";
    return asms[which_alternative];
   "
-  [(set_attr "length" "2")]
+  "&& reload_completed && CONST_INT_P (operands[2])
+   && operands[1] != stack_pointer_rtx
+   && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255)"
+  [(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;
+    
+    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")]
 )
 
 ;; Reloading and elimination of the frame pointer can
index 6cefa4e..f71599e 100644 (file)
@@ -30,6 +30,7 @@
 
 ;; The following multi-letter normal constraints have been used:
 ;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv
+;; in Thumb-1 state: Pa, Pb
 
 ;; The following memory constraints have been used:
 ;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Um, Us
       (match_test "TARGET_THUMB1 && ival >= -508 && ival <= 508
                   && ((ival & 3) == 0)")))
 
+(define_constraint "Pa"
+  "@internal In Thumb-1 state a constant in the range -510 to +510"
+  (and (match_code "const_int")
+       (match_test "TARGET_THUMB1 && ival >= -510 && ival <= 510
+                   && (ival > 255 || ival < -255)")))
+
+(define_constraint "Pb"
+  "@internal In Thumb-1 state a constant in the range -262 to +262"
+  (and (match_code "const_int")
+       (match_test "TARGET_THUMB1 && ival >= -262 && ival <= 262
+                   && (ival > 255 || ival < -255)")))
+
 (define_constraint "G"
  "In ARM/Thumb-2 state a valid FPA immediate constant."
  (and (match_code "const_double")