ARM patch: Split compare_scc (PR42835)

Submitted by Bernd Schmidt on July 3, 2010, 12:15 p.m.

Details

Message ID 4C2F29D9.1030505@codesourcery.com
State New
Headers show

Commit Message

Bernd Schmidt July 3, 2010, 12:15 p.m.
On 07/03/2010 01:46 PM, Bernd Schmidt wrote:
> Tested with my usual set of multilibs on QEMU arm-linux.  Ok?

And here's the patch file.  I think I need to hack Thunderbird somehow
to recognize more phrases for the "missing attachment" warning.


Bernd
* config/arm/arm.md (arm_adddi3): Generate canonical RTL.
	(adddi_sesidi_di, adddi_zesidi_di): Likewise.
	(LTUGEU): New code_iterator.
	(cnb): New corresponding code_attr.
	(addsi3_carryin): Change pattern to canonical form.  Operands 1 and 2
	are commutative.  Parametrize using LTUGEU.
	(addsi3_carryin_shift): Likewise.
	(addsi3_carryin_alt2): Operands 1 and 2 are commutative.  Parametrize using
	LTUGEU.
	(addsi3_carryin_alt1, addsi3_carryin_alt3): Remove.
	(arm_subsi3_insn): Allow constants for operand 0.
	(compare scc peephole for eq case): New.

Comments

Bernd Schmidt July 3, 2010, 12:46 p.m.
On 07/03/2010 02:15 PM, Bernd Schmidt wrote:
> On 07/03/2010 01:46 PM, Bernd Schmidt wrote:
>> Tested with my usual set of multilibs on QEMU arm-linux.  Ok?
> 
> And here's the patch file.  I think I need to hack Thunderbird somehow
> to recognize more phrases for the "missing attachment" warning.

In case anyone is interested, you can actually configure that, in
Preferences/Advanced/Config Editor (i.e. about:config), search for
"keywords".


Bernd
Richard Earnshaw July 3, 2010, 2:15 p.m.
On 03/07/10 13:15, Bernd Schmidt wrote:
> On 07/03/2010 01:46 PM, Bernd Schmidt wrote:
>> Tested with my usual set of multilibs on QEMU arm-linux.  Ok?
>
> And here's the patch file.  I think I need to hack Thunderbird somehow
> to recognize more phrases for the "missing attachment" warning.
>
>
> Bernd

This is OK with one minor nit.  Please can you put something in the 
pattern names that distinguishes which variant of the iterator the 
pattern was expanded for.  For example:

+(define_insn "*addsi3_carryin_shift"
    [(set (match_operand:SI 0 "s_register_operand" "=r")
+	(plus:SI (plus:SI
+		  (match_operator:SI 2 "shift_operator"
+		    [(match_operand:SI 3 "s_register_operand" "r")
+		     (match_operand:SI 4 "reg_or_int_operand" "rM")])
+		  (match_operand:SI 1 "s_register_operand" "r"))
+		 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]

Should use something like

+(define_insn "*addsi3_carryin_<optab>_shift"
    [(set (match_operand:SI 0 "s_register_operand" "=r")
+	(plus:SI (plus:SI
+		  (match_operator:SI 2 "shift_operator"
+		    [(match_operand:SI 3 "s_register_operand" "r")
+		     (match_operand:SI 4 "reg_or_int_operand" "rM")])
+		  (match_operand:SI 1 "s_register_operand" "r"))
+		 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]

Where optab expands to ltu or geu as appropriate.

(I think you'll need to define the optab attribute -- pity that that 
isn't a default one).

R.

Patch hide | download patch | download mbox

Index: config/arm/arm.md
===================================================================
--- config/arm/arm.md	(revision 161726)
+++ config/arm/arm.md	(working copy)
@@ -502,8 +502,8 @@  (define_insn_and_split "*arm_adddi3"
 		   (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
 				 (match_dup 1)))
 	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
-   (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-			       (plus:SI (match_dup 4) (match_dup 5))))]
+   (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
+			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
   "
   {
     operands[3] = gen_highpart (SImode, operands[0]);
@@ -530,10 +530,10 @@  (define_insn_and_split "*adddi_sesidi_di
 		   (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
 				 (match_dup 1)))
 	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
-   (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-			       (plus:SI (ashiftrt:SI (match_dup 2)
+   (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
 						     (const_int 31))
-					(match_dup 4))))]
+					(match_dup 4))
+			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
   "
   {
     operands[3] = gen_highpart (SImode, operands[0]);
@@ -559,8 +559,8 @@  (define_insn_and_split "*adddi_zesidi_di
 		   (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
 				 (match_dup 1)))
 	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
-   (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-			       (plus:SI (match_dup 4) (const_int 0))))]
+   (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
+			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
   "
   {
     operands[3] = gen_highpart (SImode, operands[0]);
@@ -848,37 +848,14 @@  (define_insn "*compare_addsi2_op1"
   [(set_attr "conds" "set")]
 )
 
-(define_insn "*addsi3_carryin"
-  [(set (match_operand:SI 0 "s_register_operand" "=r")
-	(plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-		 (plus:SI (match_operand:SI 1 "s_register_operand" "r")
-			  (match_operand:SI 2 "arm_rhs_operand" "rI"))))]
-  "TARGET_32BIT"
-  "adc%?\\t%0, %1, %2"
-  [(set_attr "conds" "use")]
-)
-
-(define_insn "*addsi3_carryin_shift"
-  [(set (match_operand:SI 0 "s_register_operand" "=r")
-	(plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-		 (plus:SI
-		   (match_operator:SI 2 "shift_operator"
-		      [(match_operand:SI 3 "s_register_operand" "r")
-		       (match_operand:SI 4 "reg_or_int_operand" "rM")])
-		    (match_operand:SI 1 "s_register_operand" "r"))))]
-  "TARGET_32BIT"
-  "adc%?\\t%0, %1, %3%S2"
-  [(set_attr "conds" "use")
-   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
-		      (const_string "alu_shift")
-		      (const_string "alu_shift_reg")))]
-)
+(define_code_iterator LTUGEU [ltu geu])
+(define_code_attr cnb [(ltu "CC_C") (geu "CC_NOTB")])
 
-(define_insn "*addsi3_carryin_alt1"
+(define_insn "*addsi3_carryin"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
-	(plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
+	(plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
 			  (match_operand:SI 2 "arm_rhs_operand" "rI"))
-		 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+		 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
   "TARGET_32BIT"
   "adc%?\\t%0, %1, %2"
   [(set_attr "conds" "use")]
@@ -886,22 +863,28 @@  (define_insn "*addsi3_carryin_alt1"
 
 (define_insn "*addsi3_carryin_alt2"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
-	(plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-			  (match_operand:SI 1 "s_register_operand" "r"))
+	(plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
+			  (match_operand:SI 1 "s_register_operand" "%r"))
 		 (match_operand:SI 2 "arm_rhs_operand" "rI")))]
   "TARGET_32BIT"
   "adc%?\\t%0, %1, %2"
   [(set_attr "conds" "use")]
 )
 
-(define_insn "*addsi3_carryin_alt3"
+(define_insn "*addsi3_carryin_shift"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
-	(plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
-			  (match_operand:SI 2 "arm_rhs_operand" "rI"))
-		 (match_operand:SI 1 "s_register_operand" "r")))]
+	(plus:SI (plus:SI
+		  (match_operator:SI 2 "shift_operator"
+		    [(match_operand:SI 3 "s_register_operand" "r")
+		     (match_operand:SI 4 "reg_or_int_operand" "rM")])
+		  (match_operand:SI 1 "s_register_operand" "r"))
+		 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
   "TARGET_32BIT"
-  "adc%?\\t%0, %1, %2"
-  [(set_attr "conds" "use")]
+  "adc%?\\t%0, %1, %3%S2"
+  [(set_attr "conds" "use")
+   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
+		      (const_string "alu_shift")
+		      (const_string "alu_shift_reg")))]
 )
 
 (define_expand "incscc"
@@ -1103,24 +1086,27 @@  (define_insn "*thumb1_subsi3_insn"
 
 ; ??? Check Thumb-2 split length
 (define_insn_and_split "*arm_subsi3_insn"
-  [(set (match_operand:SI           0 "s_register_operand" "=r,rk,r")
-	(minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,!k,?n")
-		  (match_operand:SI 2 "s_register_operand" "r, r, r")))]
+  [(set (match_operand:SI           0 "s_register_operand" "=r,r,rk,r,r")
+	(minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,r,!k,?n,r")
+		  (match_operand:SI 2 "reg_or_int_operand" "r,rI, r, r,?n")))]
   "TARGET_32BIT"
   "@
    rsb%?\\t%0, %2, %1
    sub%?\\t%0, %1, %2
+   sub%?\\t%0, %1, %2
+   #
    #"
-  "TARGET_32BIT
-   && GET_CODE (operands[1]) == CONST_INT
-   && !const_ok_for_arm (INTVAL (operands[1]))"
+  "&& ((GET_CODE (operands[1]) == CONST_INT
+       	&& !const_ok_for_arm (INTVAL (operands[1])))
+       || (GET_CODE (operands[2]) == CONST_INT
+	   && !const_ok_for_arm (INTVAL (operands[2]))))"
   [(clobber (const_int 0))]
   "
   arm_split_constant (MINUS, SImode, curr_insn,
                       INTVAL (operands[1]), operands[0], operands[2], 0);
   DONE;
   "
-  [(set_attr "length" "4,4,16")
+  [(set_attr "length" "4,4,4,16,16")
    (set_attr "predicable" "yes")]
 )
 
@@ -9233,7 +9219,7 @@  (define_insn_and_split "*compare_scc"
   enum rtx_code rc = GET_CODE (operands[1]);
 
   tmp1 = gen_rtx_REG (mode, CC_REGNUM);
-  
+
   operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
   if (mode == CCFPmode || mode == CCFPEmode)
     rc = reverse_condition_maybe_unordered (rc);
@@ -9242,6 +9228,27 @@  (define_insn_and_split "*compare_scc"
   operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
 })
 
+;; Attempt to improve the sequence generated by the compare_scc splitters
+;; not to use conditional execution.
+(define_peephole2
+  [(set (reg:CC CC_REGNUM)
+	(compare:CC (match_operand:SI 1 "register_operand" "")
+		    (match_operand:SI 2 "arm_rhs_operand" "")))
+   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
+	      (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
+   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
+	      (set (match_dup 0) (const_int 1)))
+   (match_scratch:SI 3 "r")]
+  "TARGET_32BIT"
+  [(set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))
+   (parallel
+    [(set (reg:CC_NOTB CC_REGNUM)
+	  (compare:CC_NOTB (const_int 0) (match_dup 3)))
+     (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
+   (set (match_dup 0)
+	(plus:SI (plus:SI (match_dup 0) (match_dup 3))
+		 (geu:SI (reg:CC_NOTB CC_REGNUM) (const_int 0))))])
+
 (define_insn "*cond_move"
   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
 	(if_then_else:SI (match_operator 3 "equality_operator"