Patchwork ARM patch: Split compare_scc (PR42835)

login
register
mail settings
Submitter Bernd Schmidt
Date July 3, 2010, 12:15 p.m.
Message ID <4C2F29D9.1030505@codesourcery.com>
Download mbox | patch
Permalink /patch/57803/
State New
Headers show

Comments

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.
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

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"