The uaddv patterns in the arm back-end do not currenty handle immediates
during expansion.  This patch adds this support for uaddvsi4.  It's really
a stepping-stone towards early expansion of uaddvdi4, but it complete and
a useful change in its own right.

Whilst making this change I also observed that we really had two patterns
that did exactly the same thing, but with slightly different properties;
consequently I've cleaned up all of the add-and-compare patterns to bring
some consistency.

        * config/arm/arm.md (adddi3): Call gen_addsi3_compare_op1.
        * (uaddv<mode>4): Delete expansion pattern.
        (uaddvsi4): New pattern.
        (uaddvdi4): Likewise.
        (addsi3_compareC): Delete pattern, change callers to use
        addsi3_compare_op1.
        (addsi3_compare_op1): No-longer anonymous.  Clean up constraints to
        reduce the number of alternatives and re-work type attribute handling.
        (addsi3_compare_op2): Clean up constraints to reduce the number of
        alternatives and re-work type attribute handling.
        (compare_addsi2_op0): Likewise.
        (compare_addsi2_op1): Likewise.
---
 gcc/config/arm/arm.md | 118 ++++++++++++++++++++++--------------------
 1 file changed, 62 insertions(+), 56 deletions(-)

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index eaadfd64128..4ea6f4b226c 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -470,7 +470,7 @@ (define_expand "adddi3"
 	  if (!arm_not_operand (hi_op2, SImode))
 	    hi_op2 = force_reg (SImode, hi_op2);
 
-	  emit_insn (gen_addsi3_compareC (lo_dest, lo_op1, lo_op2));
+	  emit_insn (gen_addsi3_compare_op1 (lo_dest, lo_op1, lo_op2));
 	  rtx carry = gen_rtx_LTU (SImode, gen_rtx_REG (CC_Cmode, CC_REGNUM),
 				   const0_rtx);
 	  if (hi_op2 == const0_rtx)
@@ -501,14 +501,27 @@ (define_expand "addv<mode>4"
   DONE;
 })
 
-(define_expand "uaddv<mode>4"
-  [(match_operand:SIDI 0 "register_operand")
-   (match_operand:SIDI 1 "register_operand")
-   (match_operand:SIDI 2 "register_operand")
+(define_expand "uaddvsi4"
+  [(match_operand:SI 0 "s_register_operand")
+   (match_operand:SI 1 "s_register_operand")
+   (match_operand:SI 2 "arm_add_operand")
    (match_operand 3 "")]
   "TARGET_32BIT"
 {
-  emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
+  emit_insn (gen_addsi3_compare_op1 (operands[0], operands[1], operands[2]));
+  arm_gen_unlikely_cbranch (LTU, CC_Cmode, operands[3]);
+
+  DONE;
+})
+
+(define_expand "uaddvdi4"
+  [(match_operand:DI 0 "s_register_operand")
+   (match_operand:DI 1 "s_register_operand")
+   (match_operand:DI 2 "s_register_operand")
+   (match_operand 3 "")]
+  "TARGET_32BIT"
+{
+  emit_insn (gen_adddi3_compareC (operands[0], operands[1], operands[2]));
   arm_gen_unlikely_cbranch (LTU, CC_Cmode, operands[3]);
 
   DONE;
@@ -639,19 +652,6 @@ (define_insn "adddi3_compareC"
    (set_attr "type" "multiple")]
 )
 
-(define_insn "addsi3_compareC"
-   [(set (reg:CC_C CC_REGNUM)
-	 (compare:CC_C (plus:SI (match_operand:SI 1 "register_operand" "r")
-				(match_operand:SI 2 "register_operand" "r"))
-		       (match_dup 1)))
-    (set (match_operand:SI 0 "register_operand" "=r")
-	 (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_32BIT"
-  "adds%?\\t%0, %1, %2"
-  [(set_attr "conds" "set")
-   (set_attr "type" "alus_sreg")]
-)
-
 (define_insn "addsi3_compare0"
   [(set (reg:CC_NOOV CC_REGNUM)
 	(compare:CC_NOOV
@@ -770,13 +770,13 @@ (define_peephole2
 ;; the operands, and we know that the use of the condition code is
 ;; either GEU or LTU, so we can use the carry flag from the addition
 ;; instead of doing the compare a second time.
-(define_insn "*addsi3_compare_op1"
+(define_insn "addsi3_compare_op1"
   [(set (reg:CC_C CC_REGNUM)
 	(compare:CC_C
-	 (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r,r")
-		  (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,I,L,r"))
+	 (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,rk,rk")
+		  (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,rkI,L"))
 	 (match_dup 1)))
-   (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r,r")
+   (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,rk,rk")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   "TARGET_32BIT"
   "@
@@ -785,22 +785,23 @@ (define_insn "*addsi3_compare_op1"
    subs%?\\t%0, %1, #%n2
    subs%?\\t%0, %0, #%n2
    adds%?\\t%0, %1, %2
-   subs%?\\t%0, %1, #%n2
-   adds%?\\t%0, %1, %2"
+   subs%?\\t%0, %1, #%n2"
   [(set_attr "conds" "set")
-   (set_attr "arch" "t2,t2,t2,t2,*,*,*")
-   (set_attr "length" "2,2,2,2,4,4,4")
-   (set_attr "type"
-    "alus_sreg,alus_imm,alus_sreg,alus_imm,alus_imm,alus_imm,alus_sreg")]
+   (set_attr "arch" "t2,t2,t2,t2,*,*")
+   (set_attr "length" "2,2,2,2,4,4")
+   (set (attr "type")
+	(if_then_else (match_operand 2 "const_int_operand")
+		      (const_string "alu_imm")
+		      (const_string "alu_sreg")))]
 )
 
 (define_insn "*addsi3_compare_op2"
   [(set (reg:CC_C CC_REGNUM)
 	(compare:CC_C
-	 (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r,r")
-		  (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,I,L,r"))
+	 (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r")
+		  (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,rI,L"))
 	 (match_dup 2)))
-   (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r,r")
+   (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   "TARGET_32BIT"
   "@
@@ -809,55 +810,60 @@ (define_insn "*addsi3_compare_op2"
    subs%?\\t%0, %1, #%n2
    subs%?\\t%0, %0, #%n2
    adds%?\\t%0, %1, %2
-   subs%?\\t%0, %1, #%n2
-   adds%?\\t%0, %1, %2"
+   subs%?\\t%0, %1, #%n2"
   [(set_attr "conds" "set")
-   (set_attr "arch" "t2,t2,t2,t2,*,*,*")
-   (set_attr "length" "2,2,2,2,4,4,4")
-   (set_attr "type"
-    "alus_sreg,alus_imm,alus_sreg,alus_imm,alus_imm,alus_imm,alus_sreg")]
+   (set_attr "arch" "t2,t2,t2,t2,*,*")
+   (set_attr "length" "2,2,2,2,4,4")
+   (set (attr "type")
+	(if_then_else (match_operand 2 "const_int_operand")
+		      (const_string "alu_imm")
+		      (const_string "alu_sreg")))]
 )
 
 (define_insn "*compare_addsi2_op0"
   [(set (reg:CC_C CC_REGNUM)
         (compare:CC_C
-          (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
-                   (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
+          (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r")
+                   (match_operand:SI 1 "arm_add_operand"    "l,Pw,rI,L"))
           (match_dup 0)))]
   "TARGET_32BIT"
   "@
-   cmp%?\\t%0, #%n1
-   cmn%?\\t%0, %1
    cmn%?\\t%0, %1
    cmp%?\\t%0, #%n1
-   cmn%?\\t%0, %1"
+   cmn%?\\t%0, %1
+   cmp%?\\t%0, #%n1"
   [(set_attr "conds" "set")
    (set_attr "predicable" "yes")
-   (set_attr "arch" "t2,t2,*,*,*")
-   (set_attr "predicable_short_it" "yes,yes,no,no,no")
-   (set_attr "length" "2,2,4,4,4")
-   (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
+   (set_attr "arch" "t2,t2,*,*")
+   (set_attr "predicable_short_it" "yes,yes,no,no")
+   (set_attr "length" "2,2,4,4")
+   (set (attr "type")
+	(if_then_else (match_operand 1 "const_int_operand")
+		      (const_string "alu_imm")
+		      (const_string "alu_sreg")))]
 )
 
 (define_insn "*compare_addsi2_op1"
   [(set (reg:CC_C CC_REGNUM)
         (compare:CC_C
-          (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
-                   (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
+          (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r")
+                   (match_operand:SI 1 "arm_add_operand" "l,Pw,rI,L"))
           (match_dup 1)))]
   "TARGET_32BIT"
   "@
-   cmp%?\\t%0, #%n1
-   cmn%?\\t%0, %1
    cmn%?\\t%0, %1
    cmp%?\\t%0, #%n1
-   cmn%?\\t%0, %1"
+   cmn%?\\t%0, %1
+   cmp%?\\t%0, #%n1"
   [(set_attr "conds" "set")
    (set_attr "predicable" "yes")
-   (set_attr "arch" "t2,t2,*,*,*")
-   (set_attr "predicable_short_it" "yes,yes,no,no,no")
-   (set_attr "length" "2,2,4,4,4")
-   (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
+   (set_attr "arch" "t2,t2,*,*")
+   (set_attr "predicable_short_it" "yes,yes,no,no")
+   (set_attr "length" "2,2,4,4")
+   (set (attr "type")
+	(if_then_else (match_operand 1 "const_int_operand")
+		      (const_string "alu_imm")
+		      (const_string "alu_sreg")))]
  )
 
 (define_insn "addsi3_carryin"

Reply via email to