public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, ARM][0/n] Split patterns that output multiple assembly instruction
@ 2013-02-18 18:30 Greta Yorsh
  2013-02-18 18:35 ` [PATCH,ARM][1/n] New patterns for subtract with carry Greta Yorsh
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Greta Yorsh @ 2013-02-18 18:30 UTC (permalink / raw)
  To: GCC Patches; +Cc: Richard Earnshaw, Ramana Radhakrishnan, nickc, paul

This sequence of patches aims at cleaning up patterns that output multiple
assembly instructions.

The first few patches handle some of the patterns in arm.md. 

[1/n] Add new patterns for subtract with carry.
[2/n] Split subdi patterns.
[3/n] Split patterns andsi_iorsi3_notsi, abs, cmpdi, and negdi.
[4/n] Add negdi_extend patterns.
[5/n] Split shiftdi patterns and add rrx pattern.
[6/n] Split min and max patterns.
[7/n] Add a comment on splitting Thumb1 patterns.

No regression on qemu for arm-none-eabi cortex-a15 arm/thumb.

Bootstrap successful on Cortex-A15.

Ok for gcc 4.9 stage 1?

Thanks,
Greta




^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH,ARM][1/n] New patterns for subtract with carry
  2013-02-18 18:30 [PATCH, ARM][0/n] Split patterns that output multiple assembly instruction Greta Yorsh
@ 2013-02-18 18:35 ` Greta Yorsh
  2013-02-22 16:29   ` Richard Earnshaw
  2013-02-18 18:37 ` [PATCH,ARM][2/n] Split subdi patterns Greta Yorsh
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Greta Yorsh @ 2013-02-18 18:35 UTC (permalink / raw)
  To: Greta Yorsh, GCC Patches
  Cc: Richard Earnshaw, Ramana Radhakrishnan, nickc, paul

[-- Attachment #1: Type: text/plain, Size: 456 bytes --]

Add patterns to handle various subtract with carry operations.

These patterns match RTL insns emitted by splitters 
for DImode operations such as subdi, negdi, and cmpdi.

gcc/

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

        * config/arm/arm.md (subsi3_carryin, subsi3_carryin_const): New
patterns.
        (subsi3_carryin_compare,subsi3_carryin_compare_const): Likewise.
        (subsi3_carryin_shift,rsbsi3_carryin_shift): Likewise.

[-- Attachment #2: 1-patterns-subtract-with-carry.patch.txt --]
[-- Type: text/plain, Size: 3625 bytes --]

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 35294dd6560ac63279d95eca6cf774257e06bd93..0000000000000000000000000000000000000000 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -1019,3 +1019,86 @@ (define_insn "*addsi3_carryin_clobercc_<
    [(set_attr "conds" "set")]
 )
 
+(define_insn "*subsi3_carryin"
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
+        (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
+                            (match_operand:SI 2 "s_register_operand" "r,r"))
+                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  "TARGET_32BIT"
+  "@
+   sbc%?\\t%0, %1, %2
+   rsc%?\\t%0, %2, %1"
+  [(set_attr "conds" "use")
+   (set_attr "predicable" "yes")]
+)
+
+(define_insn "*subsi3_carryin_const"
+  [(set (match_operand:SI 0 "s_register_operand" "=r")
+        (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
+                           (match_operand:SI 2 "arm_not_operand" "K"))
+                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  "TARGET_32BIT"
+  "sbc\\t%0, %1, #%B2"
+  [(set_attr "conds" "use")]
+)
+
+(define_insn "*subsi3_carryin_compare"
+  [(set (reg:CC CC_REGNUM)
+        (compare:CC (match_operand:SI 1 "s_register_operand" "r")
+                    (match_operand:SI 2 "s_register_operand" "r")))
+   (set (match_operand:SI 0 "s_register_operand" "=r")
+        (minus:SI (minus:SI (match_dup 1)
+                            (match_dup 2))
+                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  "TARGET_32BIT"
+  "sbcs\\t%0, %1, %2"
+  [(set_attr "conds" "set")]
+)
+
+(define_insn "*subsi3_carryin_compare_const"
+  [(set (reg:CC CC_REGNUM)
+        (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
+                    (match_operand:SI 2 "arm_not_operand" "K")))
+   (set (match_operand:SI 0 "s_register_operand" "=r")
+        (minus:SI (plus:SI (match_dup 1)
+                           (match_dup 2))
+                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  "TARGET_32BIT"
+  "sbcs\\t%0, %1, #%B2"
+  [(set_attr "conds" "set")]
+)
+
+(define_insn "*subsi3_carryin_shift"
+  [(set (match_operand:SI 0 "s_register_operand" "=r")
+	(minus:SI (minus:SI
+		  (match_operand:SI 1 "s_register_operand" "r")
+                  (match_operator:SI 2 "shift_operator"
+                   [(match_operand:SI 3 "s_register_operand" "r")
+                    (match_operand:SI 4 "reg_or_int_operand" "rM")]))
+                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  "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")
+                     (const_string "alu_shift_reg")))]
+)
+
+(define_insn "*rsbsi3_carryin_shift"
+  [(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 1 "s_register_operand" "r"))
+                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  "TARGET_32BIT"
+  "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")
+		      (const_string "alu_shift_reg")))]
+)
+

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH,ARM][2/n] Split subdi patterns
  2013-02-18 18:30 [PATCH, ARM][0/n] Split patterns that output multiple assembly instruction Greta Yorsh
  2013-02-18 18:35 ` [PATCH,ARM][1/n] New patterns for subtract with carry Greta Yorsh
@ 2013-02-18 18:37 ` Greta Yorsh
  2013-02-22 16:33   ` Richard Earnshaw
  2013-02-18 18:39 ` [PATCH,ARM][3/n] Split various patterns Greta Yorsh
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Greta Yorsh @ 2013-02-18 18:37 UTC (permalink / raw)
  To: Greta Yorsh, GCC Patches
  Cc: Richard Earnshaw, Ramana Radhakrishnan, nickc, paul

[-- Attachment #1: Type: text/plain, Size: 406 bytes --]

Convert define_insn into define_insn_and_split for various subdi patterns
that output multiple assembly instructions.

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

          * config/arm/arm.md (arm_subdi3): Convert define_insn into
          define_insn_and_split.
          (subdi_di_zesidi,subdi_di_sesidi): Likewise.
          (subdi_zesidi_di,subdi_sesidi_di,subdi_zesidi_zesidi): Likewise.

[-- Attachment #2: 2-split-subdi.patch.txt --]
[-- Type: text/plain, Size: 7374 bytes --]

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index c708af4d78df9a92ac1c441138b57f6f18178607..0000000000000000000000000000000000000000 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -1149,13 +1149,27 @@ (define_expand "subdi3"
   "
 )
 
-(define_insn "*arm_subdi3"
+(define_insn_and_split "*arm_subdi3"
   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
 	(minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
 		  (match_operand:DI 2 "s_register_operand" "r,0,0")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_32BIT && !TARGET_NEON"
-  "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
+  "#"  ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
+  "&& reload_completed"
+  [(parallel [(set (reg:CC CC_REGNUM)
+		   (compare:CC (match_dup 1) (match_dup 2)))
+	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
+   (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
+			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  {
+    operands[3] = gen_highpart (SImode, operands[0]);
+    operands[0] = gen_lowpart (SImode, operands[0]);
+    operands[4] = gen_highpart (SImode, operands[1]);
+    operands[1] = gen_lowpart (SImode, operands[1]);
+    operands[5] = gen_highpart (SImode, operands[2]);
+    operands[2] = gen_lowpart (SImode, operands[2]);
+   }
   [(set_attr "conds" "clob")
    (set_attr "length" "8")]
 )
@@ -1170,55 +1184,113 @@ (define_insn "*thumb_subdi3"
   [(set_attr "length" "4")]
 )
 
-(define_insn "*subdi_di_zesidi"
+(define_insn_and_split "*subdi_di_zesidi"
   [(set (match_operand:DI           0 "s_register_operand" "=&r,&r")
 	(minus:DI (match_operand:DI 1 "s_register_operand"  "0,r")
 		  (zero_extend:DI
 		   (match_operand:SI 2 "s_register_operand"  "r,r"))))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_32BIT"
-  "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
+  "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
+  "&& reload_completed"
+  [(parallel [(set (reg:CC CC_REGNUM)
+		   (compare:CC (match_dup 1) (match_dup 2)))
+	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
+   (set (match_dup 3) (minus: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]);
+    operands[0] = gen_lowpart (SImode, operands[0]);
+    operands[4] = gen_highpart (SImode, operands[1]);
+    operands[1] = gen_lowpart (SImode, operands[1]);
+    operands[5] = GEN_INT (~0);
+   }
   [(set_attr "conds" "clob")
    (set_attr "length" "8")]
 )
 
-(define_insn "*subdi_di_sesidi"
+(define_insn_and_split "*subdi_di_sesidi"
   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
 	(minus:DI (match_operand:DI  1 "s_register_operand"  "0,r")
 		  (sign_extend:DI
 		   (match_operand:SI 2 "s_register_operand"  "r,r"))))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_32BIT"
-  "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
+  "#"   ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
+  "&& reload_completed"
+  [(parallel [(set (reg:CC CC_REGNUM)
+		   (compare:CC (match_dup 1) (match_dup 2)))
+	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
+   (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
+                                         (ashiftrt:SI (match_dup 2)
+                                                      (const_int 31)))
+                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  {
+    operands[3] = gen_highpart (SImode, operands[0]);
+    operands[0] = gen_lowpart (SImode, operands[0]);
+    operands[4] = gen_highpart (SImode, operands[1]);
+    operands[1] = gen_lowpart (SImode, operands[1]);
+  }
   [(set_attr "conds" "clob")
    (set_attr "length" "8")]
 )
 
-(define_insn "*subdi_zesidi_di"
+(define_insn_and_split "*subdi_zesidi_di"
   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
 	(minus:DI (zero_extend:DI
 		   (match_operand:SI 2 "s_register_operand"  "r,r"))
 		  (match_operand:DI  1 "s_register_operand" "0,r")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM"
-  "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
+  "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
+        ; is equivalent to:
+        ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
+  "&& reload_completed"
+  [(parallel [(set (reg:CC CC_REGNUM)
+		   (compare:CC (match_dup 2) (match_dup 1)))
+	      (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
+   (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
+			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  {
+    operands[3] = gen_highpart (SImode, operands[0]);
+    operands[0] = gen_lowpart (SImode, operands[0]);
+    operands[4] = gen_highpart (SImode, operands[1]);
+    operands[1] = gen_lowpart (SImode, operands[1]);
+  }
   [(set_attr "conds" "clob")
    (set_attr "length" "8")]
 )
 
-(define_insn "*subdi_sesidi_di"
+(define_insn_and_split "*subdi_sesidi_di"
   [(set (match_operand:DI            0 "s_register_operand" "=&r,&r")
 	(minus:DI (sign_extend:DI
 		   (match_operand:SI 2 "s_register_operand"   "r,r"))
 		  (match_operand:DI  1 "s_register_operand"  "0,r")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM"
-  "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
+  "#"   ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
+        ; is equivalent to:
+        ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
+  "&& reload_completed"
+  [(parallel [(set (reg:CC CC_REGNUM)
+		   (compare:CC (match_dup 2) (match_dup 1)))
+	      (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
+   (set (match_dup 3) (minus:SI (minus:SI
+                                (ashiftrt:SI (match_dup 2)
+                                             (const_int 31))
+                                (match_dup 4))
+			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  {
+    operands[3] = gen_highpart (SImode, operands[0]);
+    operands[0] = gen_lowpart (SImode, operands[0]);
+    operands[4] = gen_highpart (SImode, operands[1]);
+    operands[1] = gen_lowpart (SImode, operands[1]);
+  }
   [(set_attr "conds" "clob")
    (set_attr "length" "8")]
 )
 
-(define_insn "*subdi_zesidi_zesidi"
+(define_insn_and_split "*subdi_zesidi_zesidi"
   [(set (match_operand:DI            0 "s_register_operand" "=r")
 	(minus:DI (zero_extend:DI
 		   (match_operand:SI 1 "s_register_operand"  "r"))
@@ -1226,7 +1298,17 @@ (define_insn "*subdi_zesidi_zesidi"
 		   (match_operand:SI 2 "s_register_operand"  "r"))))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_32BIT"
-  "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
+  "#"   ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
+  "&& reload_completed"
+  [(parallel [(set (reg:CC CC_REGNUM)
+		   (compare:CC (match_dup 1) (match_dup 2)))
+	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
+   (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
+			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  {
+       operands[3] = gen_highpart (SImode, operands[0]);
+       operands[0] = gen_lowpart (SImode, operands[0]);
+  }
   [(set_attr "conds" "clob")
    (set_attr "length" "8")]
 )

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH,ARM][3/n] Split various patterns
  2013-02-18 18:30 [PATCH, ARM][0/n] Split patterns that output multiple assembly instruction Greta Yorsh
  2013-02-18 18:35 ` [PATCH,ARM][1/n] New patterns for subtract with carry Greta Yorsh
  2013-02-18 18:37 ` [PATCH,ARM][2/n] Split subdi patterns Greta Yorsh
@ 2013-02-18 18:39 ` Greta Yorsh
  2013-04-09 18:13   ` Richard Earnshaw
  2013-02-18 18:41 ` [PATCH,ARM][4/n] Add negdi_extend patterns Greta Yorsh
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Greta Yorsh @ 2013-02-18 18:39 UTC (permalink / raw)
  To: Greta Yorsh, GCC Patches
  Cc: Richard Earnshaw, Ramana Radhakrishnan, nickc, paul

[-- Attachment #1: Type: text/plain, Size: 625 bytes --]

Convert define_insn into define_insn_and_split for various patterns that
output multiple assembly instructions.

It appears that preparation statements in define_insn_and_split sometimes
are called with which_alternative set to -1 even after reload. Therefore,
preparation statements use conditions on the operands instead of
which_alternative.

gcc/

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

      * config/arm/arm.md (andsi_iorsi3_notsi): Convert define_insn into
      define_insn_and_split.
      (arm_negdi2,arm_abssi2,arm_neg_abssi2): Likewise.
      (arm_cmpdi_insn,arm_cmpdi_unsigned): Likewise.

[-- Attachment #2: 3-split-various.v4.patch.txt --]
[-- Type: text/plain, Size: 10943 bytes --]

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 282d460f928f9f1a58230a4f3f3e8960e3357c1a..0000000000000000000000000000000000000000 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -3276,13 +3276,17 @@ (define_split
   ""
 )
 
-(define_insn "*andsi_iorsi3_notsi"
+(define_insn_and_split "*andsi_iorsi3_notsi"
   [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
 	(and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
 			(match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
 		(not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
   "TARGET_32BIT"
-  "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
+  "#"   ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
+  "&& reload_completed"
+  [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
+  ""
   [(set_attr "length" "8")
    (set_attr "ce_count" "2")
    (set_attr "predicable" "yes")]
@@ -4350,12 +4354,24 @@ (define_expand "negdi2"
 
 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
 ;; The first alternative allows the common case of a *full* overlap.
-(define_insn "*arm_negdi2"
+(define_insn_and_split "*arm_negdi2"
   [(set (match_operand:DI         0 "s_register_operand" "=r,&r")
 	(neg:DI (match_operand:DI 1 "s_register_operand"  "0,r")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM"
-  "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
+  "#"   ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
+  "&& reload_completed"
+  [(parallel [(set (reg:CC CC_REGNUM)
+		   (compare:CC (const_int 0) (match_dup 1)))
+	      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
+   (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
+                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  {
+    operands[2] = gen_highpart (SImode, operands[0]);
+    operands[0] = gen_lowpart (SImode, operands[0]);
+    operands[3] = gen_highpart (SImode, operands[1]);
+    operands[1] = gen_lowpart (SImode, operands[1]);
+  }
   [(set_attr "conds" "clob")
    (set_attr "length" "8")]
 )
@@ -4425,14 +4441,67 @@ (define_expand "abssi2"
     operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
 ")
 
-(define_insn "*arm_abssi2"
+(define_insn_and_split "*arm_abssi2"
   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
 	(abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM"
-  "@
-   cmp\\t%0, #0\;rsblt\\t%0, %0, #0
-   eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+  {
+   /* if (which_alternative == 0) */
+   if (REGNO(operands[0]) == REGNO(operands[1]))
+     {
+      /* Emit the pattern:
+         cmp\\t%0, #0\;rsblt\\t%0, %0, #0
+         [(set (reg:CC CC_REGNUM)
+               (compare:CC (match_dup 0) (const_int 0)))
+          (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
+                     (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
+      */
+      emit_insn (gen_rtx_SET (VOIDmode,
+                              gen_rtx_REG (CCmode, CC_REGNUM),
+                              gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
+      emit_insn (gen_rtx_COND_EXEC (VOIDmode,
+                                    (gen_rtx_LT (SImode,
+                                                 gen_rtx_REG (CCmode, CC_REGNUM),
+                                                 const0_rtx)),
+                                    (gen_rtx_SET (VOIDmode,
+                                                  operands[0],
+                                                  (gen_rtx_MINUS (SImode,
+                                                                  const0_rtx,
+                                                                  operands[1]))))));
+      DONE;
+     }
+   else
+     {
+      /* Emit the pattern:
+         alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
+         [(set (match_dup 0)
+               (xor:SI (match_dup 1)
+                       (ashiftrt:SI (match_dup 1) (const_int 31))))
+          (set (match_dup 0)
+               (minus:SI (match_dup 0)
+                      (ashiftrt:SI (match_dup 1) (const_int 31))))]
+      */
+      emit_insn (gen_rtx_SET (VOIDmode,
+                              operands[0],
+                              gen_rtx_XOR (SImode,
+                                           gen_rtx_ASHIFTRT (SImode,
+                                                             operands[1],
+                                                             GEN_INT (31)),
+                                           operands[1])));
+      emit_insn (gen_rtx_SET (VOIDmode,
+                              operands[0],
+                              gen_rtx_MINUS (SImode,
+                                             operands[0],
+                                             gen_rtx_ASHIFTRT (SImode,
+                                                               operands[1],
+                                                               GEN_INT (31)))));
+      DONE;
+     }
+  }
   [(set_attr "conds" "clob,*")
    (set_attr "shift" "1")
    (set_attr "predicable" "no, yes")
@@ -4453,14 +4522,57 @@ (define_insn_and_split "*thumb1_abssi2"
   [(set_attr "length" "6")]
 )
 
-(define_insn "*arm_neg_abssi2"
+(define_insn_and_split "*arm_neg_abssi2"
   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
 	(neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM"
-  "@
-   cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
-   eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
+  "#"
+  "&& reload_completed"
+  [(const_int 0)]
+  {
+   /* if (which_alternative == 0) */
+   if (REGNO (operands[0]) == REGNO (operands[1]))
+     {
+      /* Emit the pattern:
+         cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
+      */
+      emit_insn (gen_rtx_SET (VOIDmode,
+                              gen_rtx_REG (CCmode, CC_REGNUM),
+                              gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
+      emit_insn (gen_rtx_COND_EXEC (VOIDmode,
+                                    gen_rtx_GT (SImode,
+                                                gen_rtx_REG (CCmode, CC_REGNUM),
+                                                const0_rtx),
+                                    gen_rtx_SET (VOIDmode,
+                                                 operands[0],
+                                                 (gen_rtx_MINUS (SImode,
+                                                                 const0_rtx,
+                                                                 operands[1])))));
+      DONE;
+     }
+   else
+     {
+      /* Emit the pattern:
+         eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
+      */
+      emit_insn (gen_rtx_SET (VOIDmode,
+                              operands[0],
+                              gen_rtx_XOR (SImode,                                           
+                                           gen_rtx_ASHIFTRT (SImode,
+                                                             operands[1],
+                                                             GEN_INT (31)),
+                                           operands[1])));
+      emit_insn (gen_rtx_SET (VOIDmode,
+                              operands[0],
+                              gen_rtx_MINUS (SImode,                                             
+                                             gen_rtx_ASHIFTRT (SImode,
+                                                               operands[1],
+                                                               GEN_INT (31)),
+                                             operands[0])));
+      DONE;
+     }
+  }
   [(set_attr "conds" "clob,*")
    (set_attr "shift" "1")
    (set_attr "predicable" "no, yes")
@@ -7828,23 +7940,64 @@ (define_insn "*arm_cmpsi_negshiftsi_si"
 ;; if-conversion can not reduce to a conditional compare, so we do
 ;; that directly.
 
-(define_insn "*arm_cmpdi_insn"
+(define_insn_and_split "*arm_cmpdi_insn"
   [(set (reg:CC_NCV CC_REGNUM)
 	(compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
 			(match_operand:DI 1 "arm_di_operand"	   "rDi")))
    (clobber (match_scratch:SI 2 "=r"))]
   "TARGET_32BIT"
-  "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
+  "#"   ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
+  "&& reload_completed"
+  [(set (reg:CC CC_REGNUM)
+        (compare:CC (match_dup 0) (match_dup 1)))
+   (parallel [(set (reg:CC CC_REGNUM)
+                   (compare:CC (match_dup 3) (match_dup 4)))
+              (set (match_dup 2)
+                   (minus:SI (match_dup 5)
+                            (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
+  {
+    operands[3] = gen_highpart (SImode, operands[0]);
+    operands[0] = gen_lowpart (SImode, operands[0]);
+    if (CONST_INT_P (operands[1]))
+      {
+        operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
+                                                           DImode,
+                                                           operands[1])));
+        operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
+      }
+    else
+      {
+        operands[4] = gen_highpart (SImode, operands[1]);
+        operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
+      }
+    operands[1] = gen_lowpart (SImode, operands[1]);
+    operands[2] = gen_lowpart (SImode, operands[2]);
+  }
   [(set_attr "conds" "set")
    (set_attr "length" "8")]
 )
 
-(define_insn "*arm_cmpdi_unsigned"
+(define_insn_and_split "*arm_cmpdi_unsigned"
   [(set (reg:CC_CZ CC_REGNUM)
 	(compare:CC_CZ (match_operand:DI 0 "s_register_operand" "r,r,l")
 		       (match_operand:DI 1 "arm_di_operand"	"rDi,l,Py")))]
   "TARGET_32BIT"
-  "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
+  "#"   ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
+  "&& reload_completed"
+  [(set (reg:CC CC_REGNUM)
+        (compare:CC (match_dup 2) (match_dup 3)))
+   (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
+              (set (reg:CC CC_REGNUM)
+                   (compare:CC (match_dup 0) (match_dup 1))))]
+  {
+    operands[2] = gen_highpart (SImode, operands[0]);
+    operands[0] = gen_lowpart (SImode, operands[0]);
+    if (CONST_INT_P (operands[1]))
+      operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
+    else
+      operands[3] = gen_highpart (SImode, operands[1]);
+    operands[1] = gen_lowpart (SImode, operands[1]);
+  }
   [(set_attr "conds" "set")
    (set_attr "enabled_for_depr_it" "no,yes,yes")
    (set_attr "length" "8,6,6")]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH,ARM][4/n] Add negdi_extend patterns
  2013-02-18 18:30 [PATCH, ARM][0/n] Split patterns that output multiple assembly instruction Greta Yorsh
                   ` (2 preceding siblings ...)
  2013-02-18 18:39 ` [PATCH,ARM][3/n] Split various patterns Greta Yorsh
@ 2013-02-18 18:41 ` Greta Yorsh
  2013-02-18 18:43 ` [PATCH,ARM][5/n] Split shift di patterns Greta Yorsh
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Greta Yorsh @ 2013-02-18 18:41 UTC (permalink / raw)
  To: Greta Yorsh, GCC Patches
  Cc: Richard Earnshaw, Ramana Radhakrishnan, nickc, paul

[-- Attachment #1: Type: text/plain, Size: 1398 bytes --]

This patch adds patterns to handle negation of an extended 32-bit value more
efficiently.

For example,

(set (reg:DI r0) (neg:DI (sign_extend:DI (reg:SI r0)))

The compiler currently generates
        mov     r1, r0, asr #31
        rsbs    r0, r0, #0
        rsc     r1, r1, #0
and after the patch it generates:
      rsb     r0, r0, #0
      mov     r1, r0, asr #31

(set (reg:DI r0) (neg:DI (zero_extend:DI (reg:SI r0)))

The compiler currently generates
        mov     r1, #0
        rsbs    r0, r0, #0
        rsc     r1, r1, #0
and after the patch it generates:
      rsbs    r0, r0, #0
      sbc     r1, r1, r1

The following examples are not affected by the patch:

(set (reg:DI r0) (sign_extend:DI (neg:SI (reg:SI r0)))
      rsb       r0, r0, #0
      mov     r1, r0, asr #31

(set (reg:DI r0) (zero_extend:DI (neg:SI (reg:SI r0)))
      rsb     r0, r0, #0
      mov     r1, #0

The patch also adds the appropriate test cases.

gcc/

2013-01-10  Greta Yorsh  <Greta.Yorsh@arm.com>

        * config/arm/arm.md (negdi_extendsidi): New pattern.
        (negdi_zero_extendsidi): Likewise.

gcc/testsuite

2013-01-10  Greta Yorsh  <Greta.Yorsh@arm.com>

        * gcc.target/arm/negdi-1.c: New test.
        * gcc.target/arm/negdi-2.c: Likewise.
        * gcc.target/arm/negdi-3.c: Likewise.
        * gcc.target/arm/negdi-4.c: Likewise.

[-- Attachment #2: 4-negdi-extend.patch.txt --]
[-- Type: text/plain, Size: 6352 bytes --]

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index de57f40c20ad89a71dc9b3b172b9d5666afde9f8..0000000000000000000000000000000000000000 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -4207,6 +4207,72 @@ (define_expand "negdf2"
   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
   "")
 
+;; Negate an extended 32-bit value.
+(define_insn_and_split "*negdi_extendsidi"
+  [(set (match_operand:DI 0 "s_register_operand" "=r,&r,l,&l")
+	(neg:DI (sign_extend:DI (match_operand:SI 1 "s_register_operand" "0,r,0,l"))))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_32BIT"
+  "#" ; rsb\\t%Q0, %1, #0\;asr\\t%R0, %Q0, #31
+  "&& reload_completed"
+  [(const_int 0)]
+  {
+     operands[2] = gen_highpart (SImode, operands[0]);
+     operands[0] = gen_lowpart (SImode, operands[0]);
+     rtx tmp = gen_rtx_SET (VOIDmode,
+                            operands[0],
+                            gen_rtx_MINUS (SImode,
+                                           const0_rtx,
+                                           operands[1]));
+     if (TARGET_ARM)
+       {
+         emit_insn (tmp);
+       }
+     else
+       {
+         /* Set the flags, to emit the short encoding in Thumb2.  */
+         rtx flags = gen_rtx_SET (VOIDmode,
+                                  gen_rtx_REG (CCmode, CC_REGNUM),
+                                  gen_rtx_COMPARE (CCmode,
+                                                   const0_rtx,
+                                                   operands[1]));
+         emit_insn (gen_rtx_PARALLEL (VOIDmode,
+                                      gen_rtvec (2,
+                                                 flags,
+                                                 tmp)));
+       }
+       emit_insn (gen_rtx_SET (VOIDmode,
+                              operands[2],
+                              gen_rtx_ASHIFTRT (SImode,
+                                                operands[0],
+                                                GEN_INT (31))));
+  }
+  [(set_attr "length" "8,8,4,4")
+   (set_attr "arch" "a,a,t2,t2")]
+)
+
+(define_insn_and_split "*negdi_zero_extendsidi"
+  [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
+	(neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_32BIT"
+  "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
+      ;; Don't care what register is input to sbc,
+      ;; since we just just need to propagate the carry.
+  "&& reload_completed"
+  [(parallel [(set (reg:CC CC_REGNUM)
+                   (compare:CC (const_int 0) (match_dup 1)))
+              (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
+   (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
+                                (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  {
+    operands[2] = gen_highpart (SImode, operands[0]);
+    operands[0] = gen_lowpart (SImode, operands[0]);
+  }
+  [(set_attr "conds" "clob")
+   (set_attr "length" "8")]   ;; length in thumb is 4
+)
+
 ;; abssi2 doesn't really clobber the condition codes if a different register
 ;; is being set.  To keep things simple, assume during rtl manipulations that
 ;; it does, but tell the final scan operator the truth.  Similarly for
diff --git a/gcc/testsuite/gcc.target/arm/negdi-1.c b/gcc/testsuite/gcc.target/arm/negdi-1.c
index ...7cd80ea3dc397f4c0eee688de5d6b49c685e869f 100644
--- a/gcc/testsuite/gcc.target/arm/negdi-1.c
+++ b/gcc/testsuite/gcc.target/arm/negdi-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm32 } */
+/* { dg-options "-O2" } */
+
+signed long long extendsidi_negsi (signed int x)
+{
+  return -x;
+}
+
+/*
+Expected output:
+	rsb	r0, r0, #0
+	mov	r1, r0, asr #31
+*/
+/* { dg-final { scan-assembler-times "rsb\\tr0, r0, #0" 1 { target { arm_nothumb } } } } */
+/* { dg-final { scan-assembler-times "negs\\tr0" 1 { target { ! arm_nothumb } } } } */
+/* { dg-final { scan-assembler-times "asr" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/negdi-2.c b/gcc/testsuite/gcc.target/arm/negdi-2.c
index ...96bbcab337e54cdb072fc11f19cf412b56b463a5 100644
--- a/gcc/testsuite/gcc.target/arm/negdi-2.c
+++ b/gcc/testsuite/gcc.target/arm/negdi-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm32 } */
+/* { dg-options "-O2" } */
+
+signed long long zero_extendsidi_negsi (unsigned int x)
+{
+  return -x;
+}
+/*
+Expected output:
+	rsb	r0, r0, #0
+	mov	r1, #0
+*/
+/* { dg-final { scan-assembler-times "rsb\\tr0, r0, #0" 1 { target { arm_nothumb } } } } */
+/* { dg-final { scan-assembler-times "negs\\tr0, r0" 1 { target { ! arm_nothumb } } } } */
+/* { dg-final { scan-assembler-times "mov" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/negdi-3.c b/gcc/testsuite/gcc.target/arm/negdi-3.c
index ...76ddf49fc0ddb8b0287b8e30f72962ea25d12438 100644
--- a/gcc/testsuite/gcc.target/arm/negdi-3.c
+++ b/gcc/testsuite/gcc.target/arm/negdi-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm32 } */
+/* { dg-options "-O2" } */
+
+signed long long negdi_zero_extendsidi (unsigned int x)
+{
+  return -((signed long long) x);
+}
+/*
+Expected output:
+        rsbs    r0, r0, #0
+        sbc     r1, r1, r1
+*/
+/* { 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 } } */
diff --git a/gcc/testsuite/gcc.target/arm/negdi-4.c b/gcc/testsuite/gcc.target/arm/negdi-4.c
index ...981b1a955a6547049864b3379e9fe595ebb47f2f 100644
--- a/gcc/testsuite/gcc.target/arm/negdi-4.c
+++ b/gcc/testsuite/gcc.target/arm/negdi-4.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm32 } */
+/* { dg-options "-O2" } */
+
+signed long long negdi_extendsidi (signed int x)
+{
+  return -((signed long long) x);
+}
+/*
+Expected output:
+        rsbs    r0, r0, #0
+        mov     r1, r0, asr #31
+*/
+/* { dg-final { scan-assembler-times "rsb" 1 } } */
+/* { dg-final { scan-assembler-times "asr" 1 } } */
+/* { dg-final { scan-assembler-times "rsc" 0 } } */

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH,ARM][5/n] Split shift di patterns
  2013-02-18 18:30 [PATCH, ARM][0/n] Split patterns that output multiple assembly instruction Greta Yorsh
                   ` (3 preceding siblings ...)
  2013-02-18 18:41 ` [PATCH,ARM][4/n] Add negdi_extend patterns Greta Yorsh
@ 2013-02-18 18:43 ` Greta Yorsh
  2013-02-18 18:45 ` [PATCH,ARM][6/n] Split min and max patterns Greta Yorsh
  2013-02-18 18:46 ` [PATCH, ARM][7/n] Comment on splitting THUMB1 patterns Greta Yorsh
  6 siblings, 0 replies; 14+ messages in thread
From: Greta Yorsh @ 2013-02-18 18:43 UTC (permalink / raw)
  To: Greta Yorsh, GCC Patches
  Cc: Richard Earnshaw, Ramana Radhakrishnan, nickc, paul

[-- Attachment #1: Type: text/plain, Size: 676 bytes --]

Convert define_insn into define_insn_and_split for various DImode shift
operations that output multiple assembly instructions.

This patch also adds a new pattern for RRX using a new UNSPEC. This pattern
matches RTL insns emitted by arm_ashrdi3_1bit and arm_lshrdi3_1bit
splitters. This patch also adds a new pattern shiftsi3_compare.

gcc/

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

      * config/arm/arm.md (arm_ashldi3_1bit): Convert define_insn into
      define_insn_and_split.
        (arm_ashrdi3_1bit,arm_lshrdi3_1bit): Likewise.
      (shiftsi3_compare): New pattern.
      (rrx): New pattern.
      * config/arm/unspecs.md (UNSPEC_RRX): New.

[-- Attachment #2: 5-split-shiftdi.patch.txt --]
[-- Type: text/plain, Size: 5963 bytes --]

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index cbd0faf636d264dd4e46db9c8a1fe226b431a97e..0000000000000000000000000000000000000000 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -3806,13 +3806,26 @@ (define_expand "ashldi3"
   "
 )
 
-(define_insn "arm_ashldi3_1bit"
+(define_insn_and_split "arm_ashldi3_1bit"
   [(set (match_operand:DI            0 "s_register_operand" "=r,&r")
         (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
                    (const_int 1)))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_32BIT"
-  "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
+  "#"   ; "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
+  "&& reload_completed"
+  [(parallel [(set (reg:CC CC_REGNUM)
+		   (compare:CC (ashift:SI (match_dup 1) (const_int 1))
+                               (const_int 0)))
+	      (set (match_dup 0) (ashift:SI (match_dup 1) (const_int 1)))])
+   (set (match_dup 2) (plus:SI (plus:SI (match_dup 3) (match_dup 3))
+			       (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+  {
+    operands[2] = gen_highpart (SImode, operands[0]);
+    operands[0] = gen_lowpart (SImode, operands[0]);
+    operands[3] = gen_highpart (SImode, operands[1]);
+    operands[1] = gen_lowpart (SImode, operands[1]);
+  }
   [(set_attr "conds" "clob")
    (set_attr "length" "8")]
 )
@@ -3888,18 +3901,43 @@ (define_expand "ashrdi3"
   "
 )
 
-(define_insn "arm_ashrdi3_1bit"
+(define_insn_and_split "arm_ashrdi3_1bit"
   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
                      (const_int 1)))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_32BIT"
-  "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
+  "#"   ; "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
+  "&& reload_completed"
+  [(parallel [(set (reg:CC CC_REGNUM)
+                   (compare:CC (ashiftrt:SI (match_dup 3) (const_int 1))
+                               (const_int 0)))
+              (set (match_dup 2) (ashiftrt:SI (match_dup 3) (const_int 1)))])
+   (set (match_dup 0) (unspec:SI [(match_dup 1)
+                                  (reg:CC_C CC_REGNUM)]
+                                 UNSPEC_RRX))]
+  {
+    operands[2] = gen_highpart (SImode, operands[0]);
+    operands[0] = gen_lowpart (SImode, operands[0]);
+    operands[3] = gen_highpart (SImode, operands[1]);
+    operands[1] = gen_lowpart (SImode, operands[1]);
+  }
   [(set_attr "conds" "clob")
-   (set_attr "insn" "mov")
    (set_attr "length" "8")]
 )
 
+(define_insn "*rrx"
+  [(set (match_operand:SI 0 "s_register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
+                    (reg:CC_C CC_REGNUM)]
+                   UNSPEC_RRX))]
+  "TARGET_32BIT"
+  "mov\\t%0, %1, rrx"
+  [(set_attr "conds" "use")
+   (set_attr "insn" "mov")
+   (set_attr "type" "alu_shift")]
+)
+
 (define_expand "ashrsi3"
   [(set (match_operand:SI              0 "s_register_operand" "")
 	(ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
@@ -3968,15 +4006,28 @@ (define_expand "lshrdi3"
   "
 )
 
-(define_insn "arm_lshrdi3_1bit"
+(define_insn_and_split "arm_lshrdi3_1bit"
   [(set (match_operand:DI              0 "s_register_operand" "=r,&r")
         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
                      (const_int 1)))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_32BIT"
-  "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
+  "#"   ;  "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
+  "&& reload_completed"
+  [(parallel [(set (reg:CC CC_REGNUM)
+                   (compare:CC (lshiftrt:SI (match_dup 3) (const_int 1))
+                               (const_int 0)))
+              (set (match_dup 2) (lshiftrt:SI (match_dup 3) (const_int 1)))])
+   (set (match_dup 0) (unspec:SI [(match_dup 1)
+                                  (reg:CC_C CC_REGNUM)]
+                                 UNSPEC_RRX))]
+  {
+    operands[2] = gen_highpart (SImode, operands[0]);
+    operands[0] = gen_lowpart (SImode, operands[0]);
+    operands[3] = gen_highpart (SImode, operands[1]);
+    operands[1] = gen_lowpart (SImode, operands[1]);
+  }
   [(set_attr "conds" "clob")
-   (set_attr "insn" "mov")
    (set_attr "length" "8")]
 )
 
@@ -4064,6 +4115,23 @@ (define_insn "*arm_shiftsi3"
 		      (const_string "alu_shift_reg")))]
 )
 
+(define_insn "*shiftsi3_compare"
+  [(set (reg:CC CC_REGNUM)
+	(compare:CC (match_operator:SI 3 "shift_operator"
+			  [(match_operand:SI 1 "s_register_operand" "r")
+			   (match_operand:SI 2 "arm_rhs_operand" "rM")])
+                    (const_int 0)))
+   (set (match_operand:SI 0 "s_register_operand" "=r")
+	(match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
+  "TARGET_32BIT"
+  "* return arm_output_shift(operands, 1);"
+  [(set_attr "conds" "set")
+   (set_attr "shift" "1")
+   (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
+		      (const_string "alu_shift")
+		      (const_string "alu_shift_reg")))]
+)
+
 (define_insn "*shiftsi3_compare0"
   [(set (reg:CC_NOOV CC_REGNUM)
 	(compare:CC_NOOV (match_operator:SI 3 "shift_operator"
diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md
index c3fb03256ceb1049d3cbb55d89075abb803f97c3..0000000000000000000000000000000000000000 100644
--- a/gcc/config/arm/unspecs.md
+++ b/gcc/config/arm/unspecs.md
@@ -83,6 +83,8 @@ (define_c_enum "unspec" [
                         ; FPSCR rounding mode and signal inexactness.
   UNSPEC_VRINTA         ; Represent a float to integral float rounding
                         ; towards nearest, ties away from zero.
+  UNSPEC_RRX            ; Rotate Right with Extend shifts register right
+                        ; by one place, with Carry flag shifted into bit[31].
 ])
 
 (define_c_enum "unspec" [

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH,ARM][6/n] Split min and max patterns
  2013-02-18 18:30 [PATCH, ARM][0/n] Split patterns that output multiple assembly instruction Greta Yorsh
                   ` (4 preceding siblings ...)
  2013-02-18 18:43 ` [PATCH,ARM][5/n] Split shift di patterns Greta Yorsh
@ 2013-02-18 18:45 ` Greta Yorsh
  2013-04-09 18:02   ` Richard Earnshaw
  2013-02-18 18:46 ` [PATCH, ARM][7/n] Comment on splitting THUMB1 patterns Greta Yorsh
  6 siblings, 1 reply; 14+ messages in thread
From: Greta Yorsh @ 2013-02-18 18:45 UTC (permalink / raw)
  To: Greta Yorsh, GCC Patches
  Cc: Richard Earnshaw, Ramana Radhakrishnan, nickc, paul

[-- Attachment #1: Type: text/plain, Size: 406 bytes --]

Convert define_insn into define_insn_and_split for various min and max
patterns that output multiple assembly instructions. Use movsicc to emit
RTL. A separate patch will split movsicc.

gcc/

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

        * config/arm/arm.md (arm_smax_insn): Convert define_insn into
      define_insn_and_split.
      (arm_smin_insn,arm_umaxsi3,arm_uminsi3): Likewise.

[-- Attachment #2: 6-split-min-max.v4.patch.txt --]
[-- Type: text/plain, Size: 4049 bytes --]

commit 068f9449536fca959fd687ac8b7e0bdae898f8bd
Author: Greta <Greta.Yorsh@arm.com>
Date:   Fri Feb 15 14:41:48 2013 +0000

    8-split-min-max.v2.patch

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 7c04840..5f5af3c 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -3443,15 +3443,23 @@
   [(set_attr "predicable" "yes")]
 )
 
-(define_insn "*arm_smax_insn"
+(define_insn_and_split "*arm_smax_insn"
   [(set (match_operand:SI          0 "s_register_operand" "=r,r")
 	(smax:SI (match_operand:SI 1 "s_register_operand"  "%0,?r")
 		 (match_operand:SI 2 "arm_rhs_operand"    "rI,rI")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM"
-  "@
-   cmp\\t%1, %2\;movlt\\t%0, %2
-   cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
+  "#"
+   ; cmp\\t%1, %2\;movlt\\t%0, %2
+   ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
+  "TARGET_ARM"
+  [(set (reg:CC CC_REGNUM)
+        (compare:CC (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+        (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
+                         (match_dup 1)
+                         (match_dup 2)))]
+  ""
   [(set_attr "conds" "clob")
    (set_attr "length" "8,12")]
 )
@@ -3483,15 +3491,23 @@
   [(set_attr "predicable" "yes")]
 )
 
-(define_insn "*arm_smin_insn"
+(define_insn_and_split "*arm_smin_insn"
   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
 	(smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
 		 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM"
-  "@
-   cmp\\t%1, %2\;movge\\t%0, %2
-   cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
+  "#"
+    ; cmp\\t%1, %2\;movge\\t%0, %2
+    ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
+  "TARGET_ARM"
+  [(set (reg:CC CC_REGNUM)
+        (compare:CC (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+        (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
+                         (match_dup 1)
+                         (match_dup 2)))]
+  ""
   [(set_attr "conds" "clob")
    (set_attr "length" "8,12")]
 )
@@ -3506,16 +3522,24 @@
   ""
 )
 
-(define_insn "*arm_umaxsi3"
+(define_insn_and_split "*arm_umaxsi3"
   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
 	(umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
 		 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM"
-  "@
-   cmp\\t%1, %2\;movcc\\t%0, %2
-   cmp\\t%1, %2\;movcs\\t%0, %1
-   cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
+  "#"
+    ; cmp\\t%1, %2\;movcc\\t%0, %2
+    ; cmp\\t%1, %2\;movcs\\t%0, %1
+    ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
+  "TARGET_ARM"
+  [(set (reg:CC CC_REGNUM)
+        (compare:CC (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+        (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
+                         (match_dup 1)
+                         (match_dup 2)))]
+  ""
   [(set_attr "conds" "clob")
    (set_attr "length" "8,8,12")]
 )
@@ -3530,16 +3554,24 @@
   ""
 )
 
-(define_insn "*arm_uminsi3"
+(define_insn_and_split "*arm_uminsi3"
   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
 	(umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
 		 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM"
-  "@
-   cmp\\t%1, %2\;movcs\\t%0, %2
-   cmp\\t%1, %2\;movcc\\t%0, %1
-   cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
+  "#"
+   ; cmp\\t%1, %2\;movcs\\t%0, %2
+   ; cmp\\t%1, %2\;movcc\\t%0, %1
+   ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
+  "TARGET_ARM"
+  [(set (reg:CC CC_REGNUM)
+        (compare:CC (match_dup 1) (match_dup 2)))
+   (set (match_dup 0)
+        (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
+                         (match_dup 1)
+                         (match_dup 2)))]
+  ""
   [(set_attr "conds" "clob")
    (set_attr "length" "8,8,12")]
 )

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH, ARM][7/n] Comment on splitting THUMB1 patterns
  2013-02-18 18:30 [PATCH, ARM][0/n] Split patterns that output multiple assembly instruction Greta Yorsh
                   ` (5 preceding siblings ...)
  2013-02-18 18:45 ` [PATCH,ARM][6/n] Split min and max patterns Greta Yorsh
@ 2013-02-18 18:46 ` Greta Yorsh
  6 siblings, 0 replies; 14+ messages in thread
From: Greta Yorsh @ 2013-02-18 18:46 UTC (permalink / raw)
  To: Greta Yorsh, GCC Patches
  Cc: Richard Earnshaw, Ramana Radhakrishnan, nickc, paul

[-- Attachment #1: Type: text/plain, Size: 206 bytes --]

This patch adds a comment explaining why it is difficult to split Thumb1
patterns.

gcc/

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

   * config/arm/arm.md: Comment on splitting Thumb1 patterns.

[-- Attachment #2: 7-comment-split-thumb1.patch.txt --]
[-- Type: text/plain, Size: 1564 bytes --]

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 64888f9..ce98013 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -22,6 +22,25 @@
 
 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
 
+;; Beware of splitting Thumb1 patterns that output multiple
+;; assembly instructions, in particular instruction such as SBC and
+;; ADC which consume flags.  For example, in the pattern thumb_subdi3
+;; below, the output SUB implicitly sets the flags (assembled to SUBS)
+;; and then the Carry flag is used by SBC to compute the correct
+;; result.  If we split thumb_subdi3 pattern into two separate RTL
+;; insns (using define_insn_and_split), the scheduler might place
+;; other RTL insns between SUB and SBC, possibly modifying the Carry
+;; flag used by SBC.  This might happen because most Thumb1 patterns
+;; for flag-setting instructions do not have explicit RTL for setting
+;; or clobbering the flags.  Instead, they have the attribute "conds"
+;; with value "set" or "clob".  However, this attribute is not used to
+;; identify dependencies and therefore the scheduler might reorder
+;; these instruction.  Currenly, this problem cannot happen because
+;; there are no separate Thumb1 patterns for individual instruction
+;; that consume flags (except conditional execution, which is treated
+;; differently).  In particular there is no Thumb1 armv6-m pattern for
+;; sbc or adc.
+
 \f
 ;;---------------------------------------------------------------------------
 ;; Constants

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH,ARM][1/n] New patterns for subtract with carry
  2013-02-18 18:35 ` [PATCH,ARM][1/n] New patterns for subtract with carry Greta Yorsh
@ 2013-02-22 16:29   ` Richard Earnshaw
       [not found]     ` <B393A6715F47FC43935D96EA15105EFF3F95D287B4@GEORGE.Emea.Arm.com>
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Earnshaw @ 2013-02-22 16:29 UTC (permalink / raw)
  To: Greta Yorsh; +Cc: GCC Patches, Ramana Radhakrishnan, nickc, paul

On 18/02/13 18:35, Greta Yorsh wrote:
> Add patterns to handle various subtract with carry operations.
>
> These patterns match RTL insns emitted by splitters
> for DImode operations such as subdi, negdi, and cmpdi.
>
> gcc/
>
> 2013-02-14  Greta Yorsh  <Greta.Yorsh@arm.com>
>
>          * config/arm/arm.md (subsi3_carryin, subsi3_carryin_const): New
> patterns.
>          (subsi3_carryin_compare,subsi3_carryin_compare_const): Likewise.
>          (subsi3_carryin_shift,rsbsi3_carryin_shift): Likewise.
>
>

Not ok.  RSC does not exist in Thumb state.

R.

> 1-patterns-subtract-with-carry.patch.txt
>
>
> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
> index 35294dd6560ac63279d95eca6cf774257e06bd93..0000000000000000000000000000000000000000 100644
> --- a/gcc/config/arm/arm.md
> +++ b/gcc/config/arm/arm.md
> @@ -1019,3 +1019,86 @@ (define_insn "*addsi3_carryin_clobercc_<
>      [(set_attr "conds" "set")]
>   )
>
> +(define_insn "*subsi3_carryin"
> +  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
> +        (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
> +                            (match_operand:SI 2 "s_register_operand" "r,r"))
> +                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
> +  "TARGET_32BIT"
> +  "@
> +   sbc%?\\t%0, %1, %2
> +   rsc%?\\t%0, %2, %1"
> +  [(set_attr "conds" "use")
> +   (set_attr "predicable" "yes")]
> +)
> +
> +(define_insn "*subsi3_carryin_const"
> +  [(set (match_operand:SI 0 "s_register_operand" "=r")
> +        (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
> +                           (match_operand:SI 2 "arm_not_operand" "K"))
> +                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
> +  "TARGET_32BIT"
> +  "sbc\\t%0, %1, #%B2"
> +  [(set_attr "conds" "use")]
> +)
> +
> +(define_insn "*subsi3_carryin_compare"
> +  [(set (reg:CC CC_REGNUM)
> +        (compare:CC (match_operand:SI 1 "s_register_operand" "r")
> +                    (match_operand:SI 2 "s_register_operand" "r")))
> +   (set (match_operand:SI 0 "s_register_operand" "=r")
> +        (minus:SI (minus:SI (match_dup 1)
> +                            (match_dup 2))
> +                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
> +  "TARGET_32BIT"
> +  "sbcs\\t%0, %1, %2"
> +  [(set_attr "conds" "set")]
> +)
> +
> +(define_insn "*subsi3_carryin_compare_const"
> +  [(set (reg:CC CC_REGNUM)
> +        (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
> +                    (match_operand:SI 2 "arm_not_operand" "K")))
> +   (set (match_operand:SI 0 "s_register_operand" "=r")
> +        (minus:SI (plus:SI (match_dup 1)
> +                           (match_dup 2))
> +                  (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
> +  "TARGET_32BIT"
> +  "sbcs\\t%0, %1, #%B2"
> +  [(set_attr "conds" "set")]
> +)
> +
> +(define_insn "*subsi3_carryin_shift"
> +  [(set (match_operand:SI 0 "s_register_operand" "=r")
> +	(minus:SI (minus:SI
> +		  (match_operand:SI 1 "s_register_operand" "r")
> +                  (match_operator:SI 2 "shift_operator"
> +                   [(match_operand:SI 3 "s_register_operand" "r")
> +                    (match_operand:SI 4 "reg_or_int_operand" "rM")]))
> +                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
> +  "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")
> +                     (const_string "alu_shift_reg")))]
> +)
> +
> +(define_insn "*rsbsi3_carryin_shift"
> +  [(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 1 "s_register_operand" "r"))
> +                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
> +  "TARGET_32BIT"
> +  "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")
> +		      (const_string "alu_shift_reg")))]
> +)
> +
>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH,ARM][2/n] Split subdi patterns
  2013-02-18 18:37 ` [PATCH,ARM][2/n] Split subdi patterns Greta Yorsh
@ 2013-02-22 16:33   ` Richard Earnshaw
  0 siblings, 0 replies; 14+ messages in thread
From: Richard Earnshaw @ 2013-02-22 16:33 UTC (permalink / raw)
  To: Greta Yorsh; +Cc: GCC Patches, Ramana Radhakrishnan, nickc, paul

On 18/02/13 18:36, Greta Yorsh wrote:
> Convert define_insn into define_insn_and_split for various subdi patterns
> that output multiple assembly instructions.
>
> 2013-02-14  Greta Yorsh  <Greta.Yorsh@arm.com>
>
>            * config/arm/arm.md (arm_subdi3): Convert define_insn into
>            define_insn_and_split.
>            (subdi_di_zesidi,subdi_di_sesidi): Likewise.
>            (subdi_zesidi_di,subdi_sesidi_di,subdi_zesidi_zesidi): Likewise.
>
>
> 2-split-subdi.patch.txt
>

OK for stage 1.

R.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH,ARM][1/n] New patterns for subtract with carry
       [not found]     ` <B393A6715F47FC43935D96EA15105EFF3F95D287B4@GEORGE.Emea.Arm.com>
@ 2013-04-05 18:59       ` Ramana Radhakrishnan
  0 siblings, 0 replies; 14+ messages in thread
From: Ramana Radhakrishnan @ 2013-04-05 18:59 UTC (permalink / raw)
  To: Greta Yorsh; +Cc: GCC Patches, nickc, paul, Richard Earnshaw

On 04/05/13 16:26, Greta Yorsh wrote:
>
>> -----Original Message-----
>> From: Richard Earnshaw
>> Sent: 22 February 2013 16:30
>> To: Greta Yorsh
>> Cc: GCC Patches; Ramana Radhakrishnan; nickc@redhat.com;
>> paul@codesourcery.com
>> Subject: Re: [PATCH,ARM][1/n] New patterns for subtract with carry
>>
>> On 18/02/13 18:35, Greta Yorsh wrote:
>>> Add patterns to handle various subtract with carry operations.
>>>
>>> These patterns match RTL insns emitted by splitters
>>> for DImode operations such as subdi, negdi, and cmpdi.
>>>
>>> gcc/
>>>
>>> 2013-02-14  Greta Yorsh  <Greta.Yorsh@arm.com>
>>>
>>>           * config/arm/arm.md (subsi3_carryin, subsi3_carryin_const):
>> New
>>> patterns.
>>>           (subsi3_carryin_compare,subsi3_carryin_compare_const):
>> Likewise.
>>>           (subsi3_carryin_shift,rsbsi3_carryin_shift): Likewise.
>>>
>>>
>>
>> Not ok.  RSC does not exist in Thumb state.
>>
>> R.
>
> I'm attaching an updated patch. I changed the condition of rsbsi3_carryin_shift pattern and added "arch" attribute to subsi3_carryin as appropriate.
>
> I have also tested the patch again on the recent trunk along with all other patching in this series, which have already been approved. No regressions.
>
> Ok for trunk?
>

Ok

ramana


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH,ARM][6/n] Split min and max patterns
  2013-02-18 18:45 ` [PATCH,ARM][6/n] Split min and max patterns Greta Yorsh
@ 2013-04-09 18:02   ` Richard Earnshaw
  0 siblings, 0 replies; 14+ messages in thread
From: Richard Earnshaw @ 2013-04-09 18:02 UTC (permalink / raw)
  To: Greta Yorsh; +Cc: GCC Patches, Ramana Radhakrishnan, nickc, paul

On 18/02/13 18:44, Greta Yorsh wrote:
> Convert define_insn into define_insn_and_split for various min and max
> patterns that output multiple assembly instructions. Use movsicc to emit
> RTL. A separate patch will split movsicc.
>
> gcc/
>
> 2013-02-14  Greta Yorsh  <Greta.Yorsh@arm.com>
>
>          * config/arm/arm.md (arm_smax_insn): Convert define_insn into
>        define_insn_and_split.
>        (arm_smin_insn,arm_umaxsi3,arm_uminsi3): Likewise.
>
>

OK.

R.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH,ARM][3/n] Split various patterns
  2013-02-18 18:39 ` [PATCH,ARM][3/n] Split various patterns Greta Yorsh
@ 2013-04-09 18:13   ` Richard Earnshaw
  0 siblings, 0 replies; 14+ messages in thread
From: Richard Earnshaw @ 2013-04-09 18:13 UTC (permalink / raw)
  To: Greta Yorsh; +Cc: GCC Patches, Ramana Radhakrishnan, nickc, paul

On 18/02/13 18:38, Greta Yorsh wrote:
> Convert define_insn into define_insn_and_split for various patterns that
> output multiple assembly instructions.
>
> It appears that preparation statements in define_insn_and_split sometimes
> are called with which_alternative set to -1 even after reload. Therefore,
> preparation statements use conditions on the operands instead of
> which_alternative.
>
> gcc/
>
> 2013-02-14  Greta Yorsh  <Greta.Yorsh@arm.com>
>
>        * config/arm/arm.md (andsi_iorsi3_notsi): Convert define_insn into
>        define_insn_and_split.
>        (arm_negdi2,arm_abssi2,arm_neg_abssi2): Likewise.
>        (arm_cmpdi_insn,arm_cmpdi_unsigned): Likewise.
>

OK.

R.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH,ARM][3/n] Split various patterns
       [not found] <51227561.45d5440a.4d62.54fbSMTPIN_ADDED_BROKEN@mx.google.com>
@ 2013-03-26 13:33 ` Ramana Radhakrishnan
  0 siblings, 0 replies; 14+ messages in thread
From: Ramana Radhakrishnan @ 2013-03-26 13:33 UTC (permalink / raw)
  To: Greta Yorsh
  Cc: GCC Patches, Richard Earnshaw, Ramana Radhakrishnan, nickc, paul

On Mon, Feb 18, 2013 at 6:38 PM, Greta Yorsh <greta.yorsh@arm.com> wrote:
> Convert define_insn into define_insn_and_split for various patterns that
> output multiple assembly instructions.
>
> It appears that preparation statements in define_insn_and_split sometimes
> are called with which_alternative set to -1 even after reload. Therefore,
> preparation statements use conditions on the operands instead of
> which_alternative.
>
> gcc/
>
> 2013-02-14  Greta Yorsh  <Greta.Yorsh@arm.com>
>
>       * config/arm/arm.md (andsi_iorsi3_notsi): Convert define_insn into
>       define_insn_and_split.
>       (arm_negdi2,arm_abssi2,arm_neg_abssi2): Likewise.
>       (arm_cmpdi_insn,arm_cmpdi_unsigned): Likewise.

>-(define_insn "*arm_neg_abssi2"
>+(define_insn_and_split "*arm_neg_abssi2"
>   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
> 	(neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
>    (clobber (reg:CC CC_REGNUM))]
>   "TARGET_ARM"
>-  "@
>-   cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
>-   eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
>+  "#"
> +  {
> +   /* if (which_alternative == 0) */
> +   if (REGNO(operands[0]) == REGNO(operands[1]))
> +     {
> +      /* Emit the pattern:
> +         cmp\\t%0, #0\;rsblt\\t%0, %0, #0
> +         [(set (reg:CC CC_REGNUM)
> +               (compare:CC (match_dup 0) (const_int 0)))
> +          (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
> +                     (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
> +      */
> +      emit_insn (gen_rtx_SET (VOIDmode,
> +                              gen_rtx_REG (CCmode, CC_REGNUM),
> +                              gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
> +      emit_insn (gen_rtx_COND_EXEC (VOIDmode,
> +                                    (gen_rtx_LT (SImode,
> +                                                 gen_rtx_REG (CCmode, CC_REGNUM),
> +                                                 const0_rtx)),
> +                                    (gen_rtx_SET (VOIDmode,
> +                                                  operands[0],
> +                                                  (gen_rtx_MINUS (SImode,
> +                                                                  const0_rtx,
> +                                                                  operands[1]))))));
> +      DONE;
> +     }
> +   else
> +     {
> +      /* Emit the pattern:
> +         alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
> +         [(set (match_dup 0)
> +               (xor:SI (match_dup 1)
> +                       (ashiftrt:SI (match_dup 1) (const_int 31))))
> +          (set (match_dup 0)
> +               (minus:SI (match_dup 0)
> +                      (ashiftrt:SI (match_dup 1) (const_int 31))))]
> +      */
> +      emit_insn (gen_rtx_SET (VOIDmode,
> +                              operands[0],
> +                              gen_rtx_XOR (SImode,
> +                                           gen_rtx_ASHIFTRT (SImode,
> +                                                             operands[1],
> +                                                             GEN_INT (31)),
> +                                           operands[1])));
> +      emit_insn (gen_rtx_SET (VOIDmode,
> +                              operands[0],
> +                              gen_rtx_MINUS (SImode,
> +                                             operands[0],
> +                                             gen_rtx_ASHIFTRT (SImode,
> +                                                               operands[1],
> +                                                               GEN_INT (31)))));
> +      DONE;
> +     }
> +  }

Sink the DONE to the common part.

Ok with that change.

regards
Ramana

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2013-04-09 15:48 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-18 18:30 [PATCH, ARM][0/n] Split patterns that output multiple assembly instruction Greta Yorsh
2013-02-18 18:35 ` [PATCH,ARM][1/n] New patterns for subtract with carry Greta Yorsh
2013-02-22 16:29   ` Richard Earnshaw
     [not found]     ` <B393A6715F47FC43935D96EA15105EFF3F95D287B4@GEORGE.Emea.Arm.com>
2013-04-05 18:59       ` Ramana Radhakrishnan
2013-02-18 18:37 ` [PATCH,ARM][2/n] Split subdi patterns Greta Yorsh
2013-02-22 16:33   ` Richard Earnshaw
2013-02-18 18:39 ` [PATCH,ARM][3/n] Split various patterns Greta Yorsh
2013-04-09 18:13   ` Richard Earnshaw
2013-02-18 18:41 ` [PATCH,ARM][4/n] Add negdi_extend patterns Greta Yorsh
2013-02-18 18:43 ` [PATCH,ARM][5/n] Split shift di patterns Greta Yorsh
2013-02-18 18:45 ` [PATCH,ARM][6/n] Split min and max patterns Greta Yorsh
2013-04-09 18:02   ` Richard Earnshaw
2013-02-18 18:46 ` [PATCH, ARM][7/n] Comment on splitting THUMB1 patterns Greta Yorsh
     [not found] <51227561.45d5440a.4d62.54fbSMTPIN_ADDED_BROKEN@mx.google.com>
2013-03-26 13:33 ` [PATCH,ARM][3/n] Split various patterns Ramana Radhakrishnan

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