OSDN Git Service

ChangeLog
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 27 Nov 2000 16:29:52 +0000 (16:29 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 27 Nov 2000 16:29:52 +0000 (16:29 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@37798 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/arm/arm.c
gcc/config/arm/arm.md

index ac339dd..5fc13de 100644 (file)
@@ -4126,6 +4126,13 @@ arm_gen_rotated_half_load (memref)
   return gen_rtx_ROTATE (SImode, base, GEN_INT (16));
 }
 
+/* Select a dominance comparison mode if possible.  We support three forms.
+   COND_OR == 0 => (X && Y) 
+   COND_OR == 1 => ((! X( || Y)
+   COND_OR == 2 => (X || Y) 
+   If we are unable to support a dominance comparsison we return CC mode.  
+   This will then fail to match for the RTL expressions that generate this
+   call.  */
 static enum machine_mode
 select_dominance_cc_mode (x, y, cond_or)
      rtx x;
@@ -4144,7 +4151,10 @@ select_dominance_cc_mode (x, y, cond_or)
          != CCmode))
     return CCmode;
 
-  if (cond_or)
+  /* The if_then_else variant of this tests the second condition if the
+     first passes, but is true if the first fails.  Reverse the first
+     condition to get a true "inclusive-or" expression.  */
+  if (cond_or == 1)
     cond1 = reverse_condition (cond1);
 
   /* If the comparisons are not equal, and one doesn't dominate the other,
@@ -4296,6 +4306,29 @@ arm_select_cc_mode (op, x, y)
       && GET_CODE (y) == CONST_INT)
     return CC_Zmode;
 
+  /* A construct for a conditional compare, if the false arm contains
+     0, then both conditions must be true, otherwise either condition
+     must be true.  Not all conditions are possible, so CCmode is
+     returned if it can't be done.  */
+  if (GET_CODE (x) == IF_THEN_ELSE
+      && (XEXP (x, 2) == const0_rtx
+         || XEXP (x, 2) == const1_rtx)
+      && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
+      && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
+    return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), 
+                                    INTVAL (XEXP (x, 2)));
+
+  /* Alternate canonicalizations of the above.  These are somewhat cleaner.  */
+  if (GET_CODE (x) == AND
+      && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
+      && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
+    return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), 0);
+
+  if (GET_CODE (x) == IOR
+      && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
+      && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
+    return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), 2);
+
   /* An operation that sets the condition codes as a side-effect, the
      V flag is not set correctly, so we can only use comparisons where
      this doesn't matter.  (For LT and GE we can use "mi" and "pl"
@@ -4312,18 +4345,6 @@ arm_select_cc_mode (op, x, y)
          || GET_CODE (x) == ROTATERT || GET_CODE (x) == ZERO_EXTRACT))
     return CC_NOOVmode;
 
-  /* A construct for a conditional compare, if the false arm contains
-     0, then both conditions must be true, otherwise either condition
-     must be true.  Not all conditions are possible, so CCmode is
-     returned if it can't be done.  */
-  if (GET_CODE (x) == IF_THEN_ELSE
-      && (XEXP (x, 2) == const0_rtx
-         || XEXP (x, 2) == const1_rtx)
-      && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
-      && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
-    return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), 
-                                    INTVAL (XEXP (x, 2)));
-
   if (GET_MODE (x) == QImode && (op == EQ || op == NE))
     return CC_Zmode;
 
index ddb2640..15c2cd9 100644 (file)
    (set_attr "length" "8")]
 )
 
+(define_insn "*cmp_and"
+  [(set (match_operand 6 "dominant_cc_register" "")
+       (compare
+        (and:SI
+         (match_operator 4 "arm_comparison_operator"
+          [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
+           (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
+         (match_operator:SI 5 "arm_comparison_operator"
+          [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
+           (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
+        (const_int 0)))]
+  "TARGET_ARM"
+  "*
+  {
+    const char * opcodes[4][2] =
+    {
+      {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\",
+       \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"},
+      {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\",
+       \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"},
+      {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\",
+       \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"},
+      {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\",
+       \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"}
+    };
+    int swap =
+      comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
+
+    return opcodes[which_alternative][swap];
+  }"
+  [(set_attr "conds" "set")
+   (set_attr "predicable" "no")
+   (set_attr "length" "8")]
+)
+
+(define_insn "*cmp_ior"
+  [(set (match_operand 6 "dominant_cc_register" "")
+       (compare
+        (ior:SI
+         (match_operator 4 "arm_comparison_operator"
+          [(match_operand:SI 0 "s_register_operand" "r,r,r,r")
+           (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")])
+         (match_operator:SI 5 "arm_comparison_operator"
+          [(match_operand:SI 2 "s_register_operand" "r,r,r,r")
+           (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]))
+        (const_int 0)))]
+  "TARGET_ARM"
+  "*
+{
+  const char * opcodes[4][2] =
+  {
+    {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\",
+     \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"},
+    {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\",
+     \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"},
+    {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\",
+     \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"},
+    {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\",
+     \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"}
+  };
+  int swap =
+    comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
+
+  return opcodes[which_alternative][swap];
+}
+"
+  [(set_attr "conds" "set")
+   (set_attr "length" "8")]
+)
+
 (define_insn "*negscc"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
        (neg:SI (match_operator 3 "arm_comparison_operator"
 (define_split
   [(set (match_operand:SI 0 "s_register_operand" "")
        (if_then_else:SI (match_operator 1 "arm_comparison_operator"
-                         [(match_operand 2 "" "") (match_operand 3 "" "")])
-                        (match_operand 4 "" "")
-                        (match_operand 5 "" "")))
-   (clobber (reg:CC CC_REGNUM))]
-  "TARGET_ARM && reload_completed && 0"
-  [(set (match_dup 6) (match_dup 7))
-   (set (match_dup 0) 
-       (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
-                        (match_dup 4)
-                        (match_dup 5)))]
-  "
-  {
-    enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
-                                            operands[2], operands[3]);
-
-    operands[6] = gen_rtx_REG (mode, CC_REGNUM);
-    operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
-  }"
-)
-
-(define_split
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (if_then_else:SI (match_operator 1 "arm_comparison_operator"
                          [(match_operand:SI 2 "s_register_operand" "")
                           (match_operand:SI 3 "arm_add_operand" "")])
                         (match_operand:SI 4 "arm_rhs_operand" "")
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_ARM && reload_completed"
   [(set (match_dup 6) (match_dup 7))
-   (set (match_dup 0) 
-       (if_then_else:SI (match_op_dup 1 [(match_dup 6) (const_int 0)])
-                        (match_dup 4)
-                        (not:SI (match_dup 5))))]
+   (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
+             (set (match_dup 0) (match_dup 4)))
+   (cond_exec (match_dup 8)
+             (set (match_dup 0) (not:SI (match_dup 5))))]
   "
   {
     enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
                                             operands[2], operands[3]);
+    enum rtx_code rc = GET_CODE (operands[1]);
 
     operands[6] = gen_rtx_REG (mode, CC_REGNUM);
     operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]);
+    if (mode == CCFPmode || mode == CCFPEmode)
+      rc = reverse_condition_maybe_unordered (rc);
+    else
+      rc = reverse_condition (rc);
+
+    operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
   }"
 )