[13/29,arm] Add alternative canonicalizations for subtract-with-carry + shift
diff mbox series

Message ID 20191018194900.34795-14-Richard.Earnshaw@arm.com
State New
Headers show
Series
  • Rewrite DImode arithmetic support
Related show

Commit Message

Richard Earnshaw (lists) Oct. 18, 2019, 7:48 p.m. UTC
This patch adds a couple of alternative canonicalizations to allow
combine to match a subtract-with-carry operation when one of the operands
is shifted first.  The most common case of this is when combining a
sign-extend of one operand with a long-long value during subtraction.
The RSC variant is only enabled for Arm, the SBC variant for any 32-bit
compilation.

	* config/arm/arm.md (subsi3_carryin_shift_alt): New pattern.
	(rsbsi3_carryin_shift_alt): Likewise.
---
 gcc/config/arm/arm.md | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

Patch
diff mbox series

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 74f417fbe4b..613f50ae5f0 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -1048,6 +1048,23 @@  (define_insn "*subsi3_carryin_shift"
 				    (const_string "alu_shift_reg")))]
 )
 
+(define_insn "*subsi3_carryin_shift_alt"
+  [(set (match_operand:SI 0 "s_register_operand" "=r")
+	(minus:SI (minus:SI
+		   (match_operand:SI 1 "s_register_operand" "r")
+		   (match_operand:SI 5 "arm_borrow_operation" ""))
+		  (match_operator:SI 2 "shift_operator"
+		   [(match_operand:SI 3 "s_register_operand" "r")
+		    (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
+  "TARGET_32BIT"
+  "sbc%?\\t%0, %1, %3%S2"
+  [(set_attr "conds" "use")
+   (set_attr "predicable" "yes")
+   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
+				    (const_string "alu_shift_imm")
+				    (const_string "alu_shift_reg")))]
+)
+
 (define_insn "*rsbsi3_carryin_shift"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
 	(minus:SI (minus:SI
@@ -1065,6 +1082,23 @@  (define_insn "*rsbsi3_carryin_shift"
 		      (const_string "alu_shift_reg")))]
 )
 
+(define_insn "*rsbsi3_carryin_shift_alt"
+  [(set (match_operand:SI 0 "s_register_operand" "=r")
+	(minus:SI (minus: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 5 "arm_borrow_operation" ""))
+		  (match_operand:SI 1 "s_register_operand" "r")))]
+  "TARGET_ARM"
+  "rsc%?\\t%0, %1, %3%S2"
+  [(set_attr "conds" "use")
+   (set_attr "predicable" "yes")
+   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
+		      (const_string "alu_shift_imm")
+		      (const_string "alu_shift_reg")))]
+)
+
 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
 (define_split
   [(set (match_operand:SI 0 "s_register_operand" "")