Commit f6ff841b by Richard Earnshaw Committed by Richard Earnshaw

[arm] Implement negscc using SBC when appropriate.

When the carry flag is appropriately set by a comprison, negscc
patterns can expand into a simple SBC of a register with itself.  This
means we can convert two conditional instructions into a single
non-conditional instruction.  Furthermore, in Thumb2 we can avoid the
need for an IT instruction as well.  This patch also fixes the remaining
testcase that we initially XFAILed in the first patch of this series.

gcc:
	* config/arm/arm.md (negscc_borrow): New pattern.
	(mov_negscc): Don't split if the insn would match negscc_borrow.
	* config/arm/thumb2.md (thumb2_mov_negscc): Likewise.
	(thumb2_mov_negscc_strict_it): Likewise.

testsuite:
	* gcc.target/arm/negdi-3.c: Remove XFAIL markers.

From-SVN: r277175
parent 24d28a87
2019-10-18 Richard Earnshaw <rearnsha@arm.com>
* config/arm/arm.md (negscc_borrow): New pattern.
(mov_negscc): Don't split if the insn would match negscc_borrow.
* config/arm/thumb2.md (thumb2_mov_negscc): Likewise.
(thumb2_mov_negscc_strict_it): Likewise.
2019-10-18 Richard Earnshaw <rearnsha@arm.com>
* config/arm/arm.c (arm_insn_cost): New function.
(TARGET_INSN_COST): Override default definition.
......
......@@ -6612,13 +6612,23 @@
(set_attr "type" "multiple")]
)
(define_insn "*negscc_borrow"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(neg:SI (match_operand:SI 1 "arm_borrow_operation" "")))]
"TARGET_32BIT"
"sbc\\t%0, %0, %0"
[(set_attr "conds" "use")
(set_attr "length" "4")
(set_attr "type" "adc_reg")]
)
(define_insn_and_split "*mov_negscc"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
[(match_operand 2 "cc_register" "") (const_int 0)])))]
"TARGET_ARM"
"TARGET_ARM && !arm_borrow_operation (operands[1], SImode)"
"#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
"TARGET_ARM"
"&& true"
[(set (match_dup 0)
(if_then_else:SI (match_dup 1)
(match_dup 3)
......
......@@ -368,7 +368,9 @@
[(set (match_operand:SI 0 "s_register_operand" "=r")
(neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
[(match_operand 2 "cc_register" "") (const_int 0)])))]
"TARGET_THUMB2 && !arm_restrict_it"
"TARGET_THUMB2
&& !arm_restrict_it
&& !arm_borrow_operation (operands[1], SImode)"
"#" ; "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
"&& true"
[(set (match_dup 0)
......@@ -387,7 +389,9 @@
[(set (match_operand:SI 0 "low_register_operand" "=l")
(neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
[(match_operand 2 "cc_register" "") (const_int 0)])))]
"TARGET_THUMB2 && arm_restrict_it"
"TARGET_THUMB2
&& arm_restrict_it
&& !arm_borrow_operation (operands[1], SImode)"
"#" ; ";mvn\\t%0, #0 ;it\\t%D1\;mov%D1\\t%0, #0\"
"&& reload_completed"
[(set (match_dup 0)
......
2019-10-18 Richard Earnshaw <rearnsha@arm.com>
* gcc.target/arm/negdi-3.c: Remove XFAIL markers.
2019-10-18 Richard Earnshaw <rearnsha@arm.com>
* gcc.target/arm/pr53447-1.c: Remove XFAIL.
* gcc.target/arm/pr53447-3.c: Remove XFAIL.
* gcc.target/arm/pr53447-4.c: Remove XFAIL.
......
......@@ -11,7 +11,7 @@ Expected output:
rsbs r0, r0, #0
sbc r1, r1, r1
*/
/* { dg-final { scan-assembler-times "rsb" 1 { xfail *-*-* } } } */
/* { dg-final { scan-assembler-times "sbc" 1 { xfail *-*-* } } } */
/* { dg-final { scan-assembler-times "mov" 0 { xfail *-*-* } } } */
/* { dg-final { scan-assembler-times "rsc" 0 { xfail *-*-* } } } */
/* { dg-final { scan-assembler-times "rsb" 1 } } */
/* { dg-final { scan-assembler-times "sbc" 1 } } */
/* { dg-final { scan-assembler-times "mov" 0 } } */
/* { dg-final { scan-assembler-times "rsc" 0 } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment