[PATCH/m68k]

Roman Zippel zippel@linux-m68k.org
Wed Sep 19 20:08:00 GMT 2007


cleanup fp compare

Hi,

This is another patch which originally addressed a reload problem by
avoiding to generate a load from the constant pool in the first place.
It cleans up the predicate handling and rejects certain constants (that
we want in registers) early, but allows them again during reload for the
case that reload has no register left and it tries the immediate
argument first, before generating a memory reference. 
The fp compare pattern are now much closer to the real instructions, so
that the main work is done by combine and avoids unneccessary reloads.

This patch has been previously discussed here:
http://gcc.gnu.org/ml/gcc-patches/2007-02/threads.html#00467

bye, Roman

200x-xx-xx  Roman Zippel <zippel@linux-m68k.org> 

	* config/m68k/m68k.c (notice_update_cc): Recognize fp compare
	(moved from fp compare patterns).
	* config/m68k/m68k.md (cmp<mode>, cmp<mode>_68881, cmp<mode>_cf):
	Cleanup predicates to relieve reload.
	(conditional_trap): Reject conditional trap with fp condition.
	* gcc/config/m68k/predicates.md (fp_src_operand): New, reject
	certain constants early.

---
 gcc/config/m68k/m68k.c        |    7 +++
 gcc/config/m68k/m68k.md       |   77 ++++++++++++++++++++----------------------
 gcc/config/m68k/predicates.md |   13 +++++++
 3 files changed, 57 insertions(+), 40 deletions(-)

Index: gcc/gcc/config/m68k/m68k.c
===================================================================
--- gcc.orig/gcc/config/m68k/m68k.c
+++ gcc/gcc/config/m68k/m68k.c
@@ -3516,6 +3516,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: gcc/gcc/config/m68k/m68k.md
===================================================================
--- gcc.orig/gcc/config/m68k/m68k.md
+++ gcc/gcc/config/m68k/m68k.md
@@ -632,51 +632,35 @@
 
 (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"
   [(set_attr "type" "fcmp")])
 
-(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"
   [(set_attr "type" "fcmp")])
 
 ;; Recognizers for btst instructions.
@@ -7702,7 +7686,20 @@
   "trap #7"
   [(set_attr "type" "trap")])
 
-(define_insn "conditional_trap"
+(define_expand "conditional_trap"
+  [(trap_if (match_operator 0 "valid_dbcc_comparison_p"
+			    [(cc0) (const_int 0)])
+	    (match_operand:SI 1 "const_int_operand" "I"))]
+  "TARGET_68020"
+{
+  if (m68k_last_compare_had_fp_operands)
+    {
+      m68k_last_compare_had_fp_operands = 0;
+      FAIL;
+    }
+})
+
+(define_insn "*conditional_trap"
   [(trap_if (match_operator 0 "valid_dbcc_comparison_p"
 			    [(cc0) (const_int 0)])
 	    (match_operand:SI 1 "const_int_operand" "I"))]
Index: gcc/gcc/config/m68k/predicates.md
===================================================================
--- gcc.orig/gcc/config/m68k/predicates.md
+++ gcc/gcc/config/m68k/predicates.md
@@ -206,3 +206,16 @@
        (ior (and (match_code "const_int")
  		 (match_test "!symbolic_operand (op, mode)"))
  	    (match_test "!symbolic_operand (op,mode)"))))
+
+;; 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_68881
+	     && (!standard_68881_constant_p (op)
+		 || reload_in_progress
+		 || reload_completed));
+})



More information about the Gcc-patches mailing list