OSDN Git Service

* arm.md (compare_scc): Use shorter sequence for EQ case.
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 May 2003 10:32:04 +0000 (10:32 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 May 2003 10:32:04 +0000 (10:32 +0000)
(ior_scc_scc_cmp, and_scc_scc_cmp): New insn-and-split patterns.
(and_scc_scc): Ensure split only applies when there is a dominance
of the comparisons.
(and_scc_scc_nodom): New insn-and-split pattern.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@66757 138bc75d-0d04-0410-961f-82ee72b054a4

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

index e9af201..1dcd80d 100644 (file)
@@ -1,3 +1,11 @@
+2003-05-13  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm.md (compare_scc): Use shorter sequence for EQ case.
+       (ior_scc_scc_cmp, and_scc_scc_cmp): New insn-and-split patterns.
+       (and_scc_scc): Ensure split only applies when there is a dominance
+       of the comparisons.
+       (and_scc_scc_nodom): New insn-and-split pattern.
+
 2003-05-13  Richard Sandiford  <rsandifo@redhat.com>
 
        * unwind-dw2.c (uw_init_context_1): Don't pass &outer_cfa directly
index 85bd146..6fb75d0 100644 (file)
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM"
   "*
-    if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
-      return \"mov\\t%0, %2, lsr #31\";
+    if (operands[3] == const0_rtx)
+      {
+       if (GET_CODE (operands[1]) == LT)
+         return \"mov\\t%0, %2, lsr #31\";
+
+       if (GET_CODE (operands[1]) == GE)
+         return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
 
-    if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
-      return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
+       if (GET_CODE (operands[1]) == EQ)
+         return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
+      }
 
     if (GET_CODE (operands[1]) == NE)
       {
   "operands[7]
      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
                                                  DOM_CC_X_OR_Y),
-                   CC_REGNUM);")
+                   CC_REGNUM);"
+  [(set_attr "conds" "clob")
+   (set_attr "length" "16")])
+
+; If the above pattern is followed by a CMP insn, then the compare is 
+; redundant, since we can rework the conditional instruction that follows.
+(define_insn_and_split "*ior_scc_scc_cmp"
+  [(set (match_operand 0 "dominant_cc_register" "")
+       (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
+                         [(match_operand:SI 1 "s_register_operand" "r")
+                          (match_operand:SI 2 "arm_add_operand" "rIL")])
+                        (match_operator:SI 6 "arm_comparison_operator"
+                         [(match_operand:SI 4 "s_register_operand" "r")
+                          (match_operand:SI 5 "arm_add_operand" "rIL")]))
+                (const_int 0)))
+   (set (match_operand:SI 7 "s_register_operand" "=r")
+       (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+               (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
+  "TARGET_ARM"
+  "#"
+  "TARGET_ARM && reload_completed"
+  [(set (match_dup 0)
+       (compare
+        (ior:SI
+         (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+         (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
+        (const_int 0)))
+   (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
+  ""
+  [(set_attr "conds" "set")
+   (set_attr "length" "16")])
 
 (define_insn_and_split "*and_scc_scc"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
    && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
        != CCmode)"
   "#"
-  "TARGET_ARM && reload_completed"
+  "TARGET_ARM && reload_completed
+   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
+       != CCmode)"
   [(set (match_dup 7)
        (compare
         (and:SI
   "operands[7]
      = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
                                                  DOM_CC_X_AND_Y),
-                   CC_REGNUM);")
+                   CC_REGNUM);"
+  [(set_attr "conds" "clob")
+   (set_attr "length" "16")])
+
+; If the above pattern is followed by a CMP insn, then the compare is 
+; redundant, since we can rework the conditional instruction that follows.
+(define_insn_and_split "*and_scc_scc_cmp"
+  [(set (match_operand 0 "dominant_cc_register" "")
+       (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
+                         [(match_operand:SI 1 "s_register_operand" "r")
+                          (match_operand:SI 2 "arm_add_operand" "rIL")])
+                        (match_operator:SI 6 "arm_comparison_operator"
+                         [(match_operand:SI 4 "s_register_operand" "r")
+                          (match_operand:SI 5 "arm_add_operand" "rIL")]))
+                (const_int 0)))
+   (set (match_operand:SI 7 "s_register_operand" "=r")
+       (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+               (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
+  "TARGET_ARM"
+  "#"
+  "TARGET_ARM && reload_completed"
+  [(set (match_dup 0)
+       (compare
+        (and:SI
+         (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+         (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
+        (const_int 0)))
+   (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
+  ""
+  [(set_attr "conds" "set")
+   (set_attr "length" "16")])
+
+;; If there is no dominance in the comparison, then we can still save an
+;; instruction in the AND case, since we can know that the second compare
+;; need only zero the value if false (if true, then the value is already
+;; correct).
+(define_insn_and_split "*and_scc_scc_nodom"
+  [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
+       (and:SI (match_operator:SI 3 "arm_comparison_operator"
+                [(match_operand:SI 1 "s_register_operand" "r,r,0")
+                 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
+               (match_operator:SI 6 "arm_comparison_operator"
+                [(match_operand:SI 4 "s_register_operand" "r,r,r")
+                 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_ARM
+   && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
+       == CCmode)"
+  "#"
+  "TARGET_ARM && reload_completed"
+  [(parallel [(set (match_dup 0)
+                  (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+             (clobber (reg:CC CC_REGNUM))])
+   (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
+   (set (match_dup 0)
+       (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
+                        (match_dup 0)
+                        (const_int 0)))]
+  "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
+                                             operands[4], operands[5]),
+                             CC_REGNUM);
+   operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
+                                 operands[5]);"
+  [(set_attr "conds" "clob")
+   (set_attr "length" "20")])
 
 (define_insn "*negscc"
   [(set (match_operand:SI 0 "s_register_operand" "=r")