arm.md (split for eq(reg, 0)): Add variants for ARMv5 and Thumb2.
authorRichard Earnshaw <rearnsha@arm.com>
Wed, 19 Jun 2013 12:25:26 +0000 (12:25 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Wed, 19 Jun 2013 12:25:26 +0000 (12:25 +0000)
(peepholes for eq(reg, not-0)): Ensure condition register is dead after
pattern.  Use more efficient sequences on ARMv5 and Thumb2.

From-SVN: r200197

gcc/ChangeLog
gcc/config/arm/arm.md

index 08f40a3b24d216e3d7713ac1c8f513a954143658..3d89e3e6834f3d60264140f892a74ff1b9bc3228 100644 (file)
@@ -1,3 +1,9 @@
+2013-06-19  Richard Earnshaw  <rearnsha@arm.com>
+
+       arm.md (split for eq(reg, 0)): Add variants for ARMv5 and Thumb2.
+       (peepholes for eq(reg, not-0)): Ensure condition register is dead after
+       pattern.  Use more efficient sequences on ARMv5 and Thumb2.
+
 2013-06-19  Steven Bosscher  <steven@gcc.gnu.org>
 
        PR target/57609
index 048a154e73cc0c913cb63102ef2a2486d040fba9..42c21098db83f663b9a5f0326454c509f1c67fdf 100644 (file)
   [(set (match_dup 0) (not:SI (match_dup 1)))
    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
 
+(define_split
+  [(set (match_operand:SI 0 "s_register_operand" "")
+       (eq:SI (match_operand:SI 1 "s_register_operand" "")
+              (const_int 0)))
+   (clobber (reg:CC CC_REGNUM))]
+  "arm_arch5 && TARGET_32BIT"
+  [(set (match_dup 0) (clz:SI (match_dup 1)))
+   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
+)
+
 (define_split
   [(set (match_operand:SI 0 "s_register_operand" "")
        (eq:SI (match_operand:SI 1 "s_register_operand" "")
 
 ;; Attempt to improve the sequence generated by the compare_scc splitters
 ;; not to use conditional execution.
+
+;; Rd = (eq (reg1) (const_int0))  // ARMv5
+;;     clz Rd, reg1
+;;     lsr Rd, Rd, #5
 (define_peephole2
   [(set (reg:CC CC_REGNUM)
        (compare:CC (match_operand:SI 1 "register_operand" "")
-                   (match_operand:SI 2 "arm_rhs_operand" "")))
+                   (const_int 0)))
+   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
+             (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
+   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
+             (set (match_dup 0) (const_int 1)))]
+  "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
+  [(set (match_dup 0) (clz:SI (match_dup 1)))
+   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
+)
+
+;; Rd = (eq (reg1) (const_int0))  // !ARMv5
+;;     negs Rd, reg1
+;;     adc  Rd, Rd, reg1
+(define_peephole2
+  [(set (reg:CC CC_REGNUM)
+       (compare:CC (match_operand:SI 1 "register_operand" "")
+                   (const_int 0)))
    (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
              (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
    (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
              (set (match_dup 0) (const_int 1)))
-   (match_scratch:SI 3 "r")]
-  "TARGET_32BIT"
+   (match_scratch:SI 2 "r")]
+  "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
   [(parallel
     [(set (reg:CC CC_REGNUM)
-         (compare:CC (match_dup 1) (match_dup 2)))
-     (set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))])
+         (compare:CC (const_int 0) (match_dup 1)))
+     (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
+   (set (match_dup 0)
+       (plus:SI (plus:SI (match_dup 1) (match_dup 2))
+                (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
+)
+
+;; Rd = (eq (reg1) (reg2/imm)) // ARMv5
+;;     sub  Rd, Reg1, reg2
+;;     clz  Rd, Rd
+;;     lsr  Rd, Rd, #5
+(define_peephole2
+  [(set (reg:CC CC_REGNUM)
+       (compare:CC (match_operand:SI 1 "register_operand" "")
+                   (match_operand:SI 2 "arm_rhs_operand" "")))
+   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
+             (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
+   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
+             (set (match_dup 0) (const_int 1)))]
+  "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
+  [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
+   (set (match_dup 0) (clz:SI (match_dup 0)))
+   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
+)
+
+
+;; Rd = (eq (reg1) (reg2/imm)) // ! ARMv5
+;;     sub  T1, Reg1, reg2
+;;     negs Rd, T1
+;;     adc  Rd, Rd, T1
+(define_peephole2
+  [(set (reg:CC CC_REGNUM)
+       (compare:CC (match_operand:SI 1 "register_operand" "")
+                   (match_operand:SI 2 "arm_rhs_operand" "")))
+   (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
+             (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
+   (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
+             (set (match_dup 0) (const_int 1)))
+   (match_scratch:SI 3 "r")]
+  "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
+  [(set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))
    (parallel
     [(set (reg:CC CC_REGNUM)
          (compare:CC (const_int 0) (match_dup 3)))
      (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
-   (parallel
-    [(set (match_dup 0)
-         (plus:SI (plus:SI (match_dup 0) (match_dup 3))
-                  (geu:SI (reg:CC CC_REGNUM) (const_int 0))))
-     (clobber (reg:CC CC_REGNUM))])])
+   (set (match_dup 0)
+       (plus:SI (plus:SI (match_dup 0) (match_dup 3))
+                (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
+)
 
 (define_insn "*cond_move"
   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")