This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [m68k 10/13] cleanup fp compare


Hi,

On Mon, 5 Feb 2007, Richard Sandiford wrote:

> > What difference does it make at this point?
> 
> The difference is that conditions are AIUI canonicalised at the tree level
> in such a way that the second operand is likely to the non-constant once.

Ah, I forgot about this.

> >> is in fp_src_operand.  All I'm really saying is that fp_src_operand
> >> should reject constants if TARGET_COLDFIRE_FPU.
> >
> > Any constants? Why?
> 
> Yes, and because the ColdFire FPU's comparison insns don't allow
> constant operands.  They're not as rich as the 68881 insns.

Then it makes sense of course.

> I don't think it has to be "one or the other".  The standard idiom,
> as used in the move patterns on most RISC targets, is to use the most
> permissive applicable predicate for both operands, then use both the
> constraints _and_ the insn condition to force one of the operands to be
> a register.  That way you get the desired restrictions before, during,
> and after reload.  E.g.:
> 
> ---------------------------------------------------------------------------
> (define_insn "*cmp<mode>_cf"
>   [(set (cc0)
>         (compare (match_operand:FP 0 "fp_src_operand" "f,<FP:dreg><Q>U")
>                  (match_operand:FP 1 "fp_src_operand" "f<FP:dreg><Q>U,f")))]
>   "TARGET_COLDFIRE_FPU
>    && (register_operand (operands[0], VOIDmode)
>        || register_operand (operands[1], VOIDmode))"
> {
>   cc_status.flags = CC_IN_68881;
>   if (FP_REG_P (operands[0]))
>     {
>       if (FP_REG_P (operands[1]))
>         return "fcmp%.d %1,%0";
>       else
>         return "fcmp%.<FP:prec> %f1,%0";
>     }
>   cc_status.flags |= CC_REVERSED;
>   return "fcmp%.<FP:prec> %f0,%1";
> })
> ---------------------------------------------------------------------------
> 
> and similar for the m68k.  (Untested.)

Ok, below is an updated patch, which also rejects all constants for 
ColdFire. (Ligthly tested.)

bye, Roman

---
 gcc/config/m68k/m68k.c        |    7 ++++
 gcc/config/m68k/m68k.md       |   62 +++++++++++++++---------------------------
 gcc/config/m68k/predicates.md |   11 +++++++
 3 files changed, 41 insertions(+), 39 deletions(-)

Index: egcs/gcc/config/m68k/m68k.c
===================================================================
--- egcs.orig/gcc/config/m68k/m68k.c
+++ egcs/gcc/config/m68k/m68k.c
@@ -2875,6 +2875,13 @@ notice_update_cc (rtx exp, rtx insn)
   if (((cc_status.value1 && FP_REG_P (cc_status.value1))
        || (cc_status.value2 && FP_REG_P (cc_status.value2))))
     cc_status.flags = CC_IN_68881;
+  if (cc_status.value2 && GET_CODE (cc_status.value2) == COMPARE
+      && GET_MODE_CLASS (GET_MODE (XEXP (cc_status.value2, 0))) == MODE_FLOAT)
+    {
+      cc_status.flags = CC_IN_68881;
+      if (!FP_REG_P (XEXP (cc_status.value2, 0)))
+	cc_status.flags |= CC_REVERSED;
+    }
 }
 
 const char *
Index: egcs/gcc/config/m68k/m68k.md
===================================================================
--- egcs.orig/gcc/config/m68k/m68k.md
+++ egcs/gcc/config/m68k/m68k.md
@@ -406,50 +406,34 @@
 
 (define_expand "cmp<mode>"
   [(set (cc0)
-	(compare (match_operand:FP 0 "general_operand" "")
-		 (match_operand:FP 1 "general_operand" "")))]
+	(compare (match_operand:FP 0 "register_operand" "")
+		 (match_operand:FP 1 "fp_src_operand" "")))]
   "TARGET_HARD_FLOAT"
-{
-  m68k_last_compare_had_fp_operands = 1;
-  if (TARGET_COLDFIRE && !reload_completed)
-    operands[1] = force_reg (<MODE>mode, operands[1]);
-})
+  "m68k_last_compare_had_fp_operands = 1;")
 
-(define_insn "cmp<mode>_68881"
+(define_insn "*cmp<mode>_68881"
   [(set (cc0)
-	(compare (match_operand:FP 0 "general_operand" "f,m<FP:const>")
-		 (match_operand:FP 1 "general_operand" "f<FP:dreg>m<FP:const>,f")))]
-  "TARGET_68881"
-{
-  cc_status.flags = CC_IN_68881;
-  if (FP_REG_P (operands[0]))
-    {
-      if (FP_REG_P (operands[1]))
-	return "fcmp%.x %1,%0";
-      else
-        return "fcmp%.<FP:prec> %f1,%0";
-    }
-  cc_status.flags |= CC_REVERSED;
-  return "fcmp%.<FP:prec> %f0,%1";
-})
+	(compare (match_operand:FP 0 "fp_src_operand" "f,f,<FP:dreg>mF")
+		 (match_operand:FP 1 "fp_src_operand" "f,<FP:dreg>mF,f")))]
+  "TARGET_68881
+   && (register_operand (operands[0], <MODE>mode)
+       || register_operand (operands[1], <MODE>mode))"
+  "@
+   fcmp%.x %1,%0
+   fcmp%.<FP:prec> %f1,%0
+   fcmp%.<FP:prec> %0,%f1")
 
-(define_insn "cmp<mode>_cf"
+(define_insn "*cmp<mode>_cf"
   [(set (cc0)
-	(compare (match_operand:FP 0 "general_operand" "f,<FP:dreg><Q>U")
-		 (match_operand:FP 1 "general_operand" "f<FP:dreg><Q>U,f")))]
-  "TARGET_COLDFIRE_FPU"
-{
-  cc_status.flags = CC_IN_68881;
-  if (FP_REG_P (operands[0]))
-    {
-      if (FP_REG_P (operands[1]))
-	return "fcmp%.d %1,%0";
-      else
-	return "fcmp%.<FP:prec> %f1,%0";
-    }
-  cc_status.flags |= CC_REVERSED;
-  return "fcmp%.<FP:prec> %f0,%1";
-})
+	(compare (match_operand:FP 0 "fp_src_operand" "f,f,<FP:dreg><Q>U")
+		 (match_operand:FP 1 "fp_src_operand" "f,<FP:dreg><Q>U,f")))]
+  "TARGET_COLDFIRE_FPU
+   && (register_operand (operands[0], <MODE>mode)
+       || register_operand (operands[1], <MODE>mode))"
+  "@
+   fcmp%.d %1,%0
+   fcmp%.<FP:prec> %f1,%0
+   fcmp%.<FP:prec> %0,%f1")
 
 ;; Recognizers for btst instructions.
 
Index: egcs/gcc/config/m68k/predicates.md
===================================================================
--- egcs.orig/gcc/config/m68k/predicates.md
+++ egcs/gcc/config/m68k/predicates.md
@@ -181,3 +181,14 @@
 (define_predicate "pre_dec_operand"
   (and (match_code "mem")
        (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC")))
+
+;; Special case of general_src_operand, which rejects a few fp
+;; constants (which we prefer in registers) before reload.
+
+(define_predicate "fp_src_operand"
+  (match_operand 0 "general_src_operand")
+{
+  return !CONSTANT_P (op) || (!TARGET_COLDFIRE_FPU
+			      && !standard_68881_constant_p (op))
+	 || reload_in_progress || reload_completed;
+})


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]