* [PATCH, ARM][10/n] Split scc patterns using cond_exec
@ 2013-04-12 13:06 Greta Yorsh
2013-04-12 14:19 ` Richard Earnshaw
0 siblings, 1 reply; 5+ messages in thread
From: Greta Yorsh @ 2013-04-12 13:06 UTC (permalink / raw)
To: GCC Patches; +Cc: Richard Earnshaw, Ramana Radhakrishnan, paul, nickc
[-- Attachment #1: Type: text/plain, Size: 597 bytes --]
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.
[-- Attachment #2: 10-split-scc-condexec.v3.patch.txt --]
[-- Type: text/plain, Size: 9688 bytes --]
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")])
\f
-(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")]
)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH, ARM][10/n] Split scc patterns using cond_exec
2013-04-12 13:06 [PATCH, ARM][10/n] Split scc patterns using cond_exec Greta Yorsh
@ 2013-04-12 14:19 ` Richard Earnshaw
2013-04-12 18:11 ` Greta Yorsh
0 siblings, 1 reply; 5+ messages in thread
From: Richard Earnshaw @ 2013-04-12 14:19 UTC (permalink / raw)
To: Greta Yorsh; +Cc: GCC Patches, Ramana Radhakrishnan, paul, nickc
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.
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [PATCH, ARM][10/n] Split scc patterns using cond_exec
2013-04-12 14:19 ` Richard Earnshaw
@ 2013-04-12 18:11 ` Greta Yorsh
0 siblings, 0 replies; 5+ messages in thread
From: Greta Yorsh @ 2013-04-12 18:11 UTC (permalink / raw)
To: Richard Earnshaw; +Cc: GCC Patches, Ramana Radhakrishnan, paul, nickc
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.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH, ARM][10/n] Split scc patterns using cond_exec
2013-04-17 15:12 Greta Yorsh
@ 2013-04-17 16:22 ` Richard Earnshaw
0 siblings, 0 replies; 5+ messages in thread
From: Richard Earnshaw @ 2013-04-17 16:22 UTC (permalink / raw)
To: Greta Yorsh; +Cc: GCC Patches, Ramana Radhakrishnan, paul, nickc
On 17/04/13 14:12, 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.
>
> Ok for trunk?
>
> Thanks,
> Greta
>
> 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.
>
>
OK.
R.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH, ARM][10/n] Split scc patterns using cond_exec
@ 2013-04-17 15:12 Greta Yorsh
2013-04-17 16:22 ` Richard Earnshaw
0 siblings, 1 reply; 5+ messages in thread
From: Greta Yorsh @ 2013-04-17 15:12 UTC (permalink / raw)
To: GCC Patches; +Cc: Richard Earnshaw, Ramana Radhakrishnan, paul, nickc
[-- Attachment #1: Type: text/plain, Size: 444 bytes --]
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.
Ok for trunk?
Thanks,
Greta
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.
[-- Attachment #2: 10-split-scc-condexec.v5.patch.txt --]
[-- Type: text/plain, Size: 9347 bytes --]
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 83b36ca..c2e59ed 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")))
@@ -8619,7 +8619,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"
@@ -8632,10 +8632,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 = GET_MODE (operands[4]);
+ 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")
@@ -9604,27 +9639,64 @@
(set_attr "type" "alu_shift,alu_shift_reg")])
\f
-(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 = GET_MODE (operands[2]);
+ enum rtx_code rc = GET_CODE (operands[1]);
+
+ /* Note that operands[4] is the same as operands[1],
+ but with VOIDmode as the result. */
+ 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 = GET_MODE (operands[2]);
+ enum rtx_code rc = GET_CODE (operands[1]);
+
+ /* Note that operands[4] is the same as operands[1],
+ but with VOIDmode as the result. */
+ 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")]
)
@@ -10331,24 +10403,75 @@
"")
;; ??? 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]);
+
+ 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")]
)
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-04-17 15:01 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-12 13:06 [PATCH, ARM][10/n] Split scc patterns using cond_exec Greta Yorsh
2013-04-12 14:19 ` Richard Earnshaw
2013-04-12 18:11 ` Greta Yorsh
2013-04-17 15:12 Greta Yorsh
2013-04-17 16:22 ` Richard Earnshaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).