Patchwork [ARM,10/n] Split scc patterns using cond_exec

login
register
mail settings
Submitter Greta Yorsh
Date April 12, 2013, 11:04 a.m.
Message ID <000401ce376d$7ade8750$709b95f0$@yorsh@arm.com>
Download mbox | patch
Permalink /patch/236031/
State New
Headers show

Comments

Greta Yorsh - April 12, 2013, 11:04 a.m.
This patch converts define_insn into define_insn_and_split to split
some alternatives of movsicc_insn and some scc patterns that cannot be
expressed using movsicc. The patch emits cond_exec RTL insns.

Tested as part of the series for splitting arm.md patterns that output
multiple asm instructions.

Ok for trunk?

gcc/

2013-02-19  Greta Yorsh  <Greta.Yorsh@arm.com>

        * config/arm/arm.md (movsicc_insn): Convert define_insn into
        define_insn_and_split.
        (and_scc,ior_scc,negscc): Likewise.
        (cmpsi2_addneg, subsi3_compare): Convert to named patterns.
Richard Earnshaw - April 12, 2013, 1:06 p.m.
On 12/04/13 12:04, Greta Yorsh wrote:
> This patch converts define_insn into define_insn_and_split to split
> some alternatives of movsicc_insn and some scc patterns that cannot be
> expressed using movsicc. The patch emits cond_exec RTL insns.
>
> Tested as part of the series for splitting arm.md patterns that output
> multiple asm instructions.
>
> Ok for trunk?
>
> gcc/
>
> 2013-02-19  Greta Yorsh  <Greta.Yorsh@arm.com>
>
>          * config/arm/arm.md (movsicc_insn): Convert define_insn into
>          define_insn_and_split.
>          (and_scc,ior_scc,negscc): Likewise.
>          (cmpsi2_addneg, subsi3_compare): Convert to named patterns.
>

OK.

R.
Greta Yorsh - April 12, 2013, 3:28 p.m.
Sorry, I've just realized that there is a possible issue with the way
SELECT_CC_MODE is used in a few places in this patch. Working on a fix.

Thanks,
Greta

> -----Original Message-----
> From: Richard Earnshaw
> Sent: 12 April 2013 14:07
> To: Greta Yorsh
> Cc: GCC Patches; Ramana Radhakrishnan; paul@codesourcery.com;
> nickc@redhat.com
> Subject: Re: [PATCH, ARM][10/n] Split scc patterns using cond_exec
> 
> On 12/04/13 12:04, Greta Yorsh wrote:
> > This patch converts define_insn into define_insn_and_split to split
> > some alternatives of movsicc_insn and some scc patterns that cannot
> be
> > expressed using movsicc. The patch emits cond_exec RTL insns.
> >
> > Tested as part of the series for splitting arm.md patterns that
> output
> > multiple asm instructions.
> >
> > Ok for trunk?
> >
> > gcc/
> >
> > 2013-02-19  Greta Yorsh  <Greta.Yorsh@arm.com>
> >
> >          * config/arm/arm.md (movsicc_insn): Convert define_insn into
> >          define_insn_and_split.
> >          (and_scc,ior_scc,negscc): Likewise.
> >          (cmpsi2_addneg, subsi3_compare): Convert to named patterns.
> >
> 
> OK.
> 
> R.

Patch

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 701e465..d190a17 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -858,7 +858,7 @@ 
 
 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
 ;; addend is a constant.
-(define_insn "*cmpsi2_addneg"
+(define_insn "cmpsi2_addneg"
   [(set (reg:CC CC_REGNUM)
 	(compare:CC
 	 (match_operand:SI 1 "s_register_operand" "r,r")
@@ -1415,7 +1415,7 @@ 
    (set_attr "type"  "simple_alu_imm,*,*")]
 )
 
-(define_insn "*subsi3_compare"
+(define_insn "subsi3_compare"
   [(set (reg:CC CC_REGNUM)
 	(compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
 		    (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
@@ -8620,7 +8620,7 @@ 
    (set_attr "type" "f_sel<vfp_type>")]
 )
 
-(define_insn "*movsicc_insn"
+(define_insn_and_split "*movsicc_insn"
   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
 	(if_then_else:SI
 	 (match_operator 3 "arm_comparison_operator"
@@ -8633,10 +8633,45 @@ 
    mvn%D3\\t%0, #%B2
    mov%d3\\t%0, %1
    mvn%d3\\t%0, #%B1
-   mov%d3\\t%0, %1\;mov%D3\\t%0, %2
-   mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
-   mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
-   mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
+   #
+   #
+   #
+   #"
+   ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
+   ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
+   ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
+   ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
+  "&& reload_completed"
+  [(const_int 0)]
+  {
+    enum rtx_code rev_code;
+    enum machine_mode mode;
+    rtx rev_cond;
+
+    emit_insn (gen_rtx_COND_EXEC (VOIDmode,
+                                  operands[3],
+                                  gen_rtx_SET (VOIDmode,
+                                               operands[0],
+                                               operands[1])));
+
+    rev_code = GET_CODE (operands[3]);
+    mode = SELECT_CC_MODE (rev_code, operands[4], const0_rtx);
+    if (mode == CCFPmode || mode == CCFPEmode)
+      rev_code = reverse_condition_maybe_unordered (rev_code);
+    else
+      rev_code = reverse_condition (rev_code);
+
+    rev_cond = gen_rtx_fmt_ee (rev_code,
+                               VOIDmode,
+                               operands[4],
+                               const0_rtx);
+    emit_insn (gen_rtx_COND_EXEC (VOIDmode,
+                                  rev_cond,
+                                  gen_rtx_SET (VOIDmode,
+                                               operands[0],
+                                               operands[2])));
+    DONE;
+  }
   [(set_attr "length" "4,4,4,4,8,8,8,8")
    (set_attr "conds" "use")
    (set_attr "insn" "mov,mvn,mov,mvn,mov,mov,mvn,mvn")
@@ -9605,27 +9640,64 @@ 
    (set_attr "type" "alu_shift,alu_shift_reg")])
 
 
-(define_insn "*and_scc"
+(define_insn_and_split "*and_scc"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
 	(and:SI (match_operator:SI 1 "arm_comparison_operator"
-		 [(match_operand 3 "cc_register" "") (const_int 0)])
-		(match_operand:SI 2 "s_register_operand" "r")))]
+		 [(match_operand 2 "cc_register" "") (const_int 0)])
+		(match_operand:SI 3 "s_register_operand" "r")))]
   "TARGET_ARM"
-  "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
+  "#"   ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
+  "&& reload_completed"
+  [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
+   (cond_exec (match_dup 4) (set (match_dup 0)
+                                 (and:SI (match_dup 3) (const_int 1))))]
+  {
+    enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
+                                                       operands[2],
+                                                       const0_rtx);
+    enum rtx_code rc = GET_CODE (operands[1]);
+
+    operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
+    if (mode == CCFPmode || mode == CCFPEmode)
+      rc = reverse_condition_maybe_unordered (rc);
+    else
+      rc = reverse_condition (rc);
+    operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
+  }
   [(set_attr "conds" "use")
    (set_attr "insn" "mov")
    (set_attr "length" "8")]
 )
 
-(define_insn "*ior_scc"
+(define_insn_and_split "*ior_scc"
   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
-	(ior:SI (match_operator:SI 2 "arm_comparison_operator"
-		 [(match_operand 3 "cc_register" "") (const_int 0)])
-		(match_operand:SI 1 "s_register_operand" "0,?r")))]
+	(ior:SI (match_operator:SI 1 "arm_comparison_operator"
+		 [(match_operand 2 "cc_register" "") (const_int 0)])
+		(match_operand:SI 3 "s_register_operand" "0,?r")))]
   "TARGET_ARM"
   "@
-   orr%d2\\t%0, %1, #1
-   mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
+   orr%d1\\t%0, %3, #1
+   #"
+  "&& reload_completed
+   && REGNO (operands [0]) != REGNO (operands[3])"
+  ;; && which_alternative == 1
+  ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
+  [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
+   (cond_exec (match_dup 4) (set (match_dup 0)
+                                 (ior:SI (match_dup 3) (const_int 1))))]
+  {
+    enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
+                                                       operands[2],
+                                                       const0_rtx);
+    enum rtx_code rc = GET_CODE (operands[1]);
+
+    operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
+    if (mode == CCFPmode || mode == CCFPEmode)
+      rc = reverse_condition_maybe_unordered (rc);
+    else
+      rc = reverse_condition (rc);
+    operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
+  }
   [(set_attr "conds" "use")
    (set_attr "length" "4,8")]
 )
@@ -10332,24 +10404,79 @@ 
   "")
 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
 
-(define_insn "*negscc"
+(define_insn_and_split "*negscc"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
 	(neg:SI (match_operator 3 "arm_comparison_operator"
 		 [(match_operand:SI 1 "s_register_operand" "r")
 		  (match_operand:SI 2 "arm_rhs_operand" "rI")])))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM"
-  "*
-  if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
-    return \"mov\\t%0, %1, asr #31\";
-
-  if (GET_CODE (operands[3]) == NE)
-    return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\";
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+  {
+    rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
 
-  output_asm_insn (\"cmp\\t%1, %2\", operands);
-  output_asm_insn (\"mov%D3\\t%0, #0\", operands);
-  return \"mvn%d3\\t%0, #0\";
-  "
+    if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
+       {
+         /* Emit mov\\t%0, %1, asr #31 */
+         emit_insn (gen_rtx_SET (VOIDmode,
+                                 operands[0],
+                                 gen_rtx_ASHIFTRT (SImode,
+                                                   operands[1],
+                                                   GEN_INT (31))));
+         DONE;
+       }
+     else if (GET_CODE (operands[3]) == NE)
+       {
+        /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
+        if (CONST_INT_P (operands[2]))
+          emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
+                                        GEN_INT (- INTVAL (operands[2]))));
+        else
+          emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
+
+        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
+                                      gen_rtx_NE (SImode,
+                                                  cc_reg,
+                                                  const0_rtx),
+                                      gen_rtx_SET (SImode,
+                                                   operands[0],
+                                                   GEN_INT (~0))));
+        DONE;
+      }
+    else
+      {
+        /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
+        emit_insn (gen_rtx_SET (VOIDmode,
+                                cc_reg,
+                                gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
+        enum rtx_code rc = GET_CODE (operands[3]);
+        enum machine_mode mode = SELECT_CC_MODE (rc, operands[1], operands[2]);
+
+        if (mode == CCFPmode || mode == CCFPEmode)
+          rc = reverse_condition_maybe_unordered (rc);
+        else
+          rc = reverse_condition (rc);
+        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
+                                      gen_rtx_fmt_ee (rc,
+                                                      VOIDmode,
+                                                      cc_reg,
+                                                      const0_rtx),
+                                      gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
+        rc = GET_CODE (operands[3]);
+        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
+                                      gen_rtx_fmt_ee (rc,
+                                                      VOIDmode,
+                                                      cc_reg,
+                                                      const0_rtx),
+                                      gen_rtx_SET (VOIDmode,
+                                                   operands[0],
+                                                   GEN_INT (~0))));
+        DONE;
+      }
+     FAIL;
+  }
   [(set_attr "conds" "clob")
    (set_attr "length" "12")]
 )