This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[m68k 10/13] cleanup fp compare
- From: zippel at linux-m68k dot org
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 30 Jan 2007 12:26:25 +0100
- Subject: [m68k 10/13] cleanup fp compare
- References: <20070130112615.782382000@linux-m68k.org>
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.
2007-01-30 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?f): cleanup predicates to relieve
reload.
* gcc/config/m68k/predicates.md (fp_src_operand): New, reject
certain constants early.
---
gcc/config/m68k/m68k.c | 3 ++
gcc/config/m68k/m68k.md | 52 ++++++++++++------------------------------
gcc/config/m68k/predicates.md | 10 ++++++++
3 files changed, 28 insertions(+), 37 deletions(-)
Index: egcs/gcc/config/m68k/m68k.c
===================================================================
--- egcs.orig/gcc/config/m68k/m68k.c
+++ egcs/gcc/config/m68k/m68k.c
@@ -2872,6 +2872,9 @@ 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;
}
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,28 @@
(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")))]
+ (compare (match_operand:FP 0 "register_operand" "f,f")
+ (match_operand:FP 1 "fp_src_operand" "f,<FP:dreg>mF")))]
"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";
-})
+ "@
+ fcmp%.x %1,%0
+ fcmp%.<FP:prec> %f1,%0")
-(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")))]
+ (compare (match_operand:FP 0 "register_operand" "f,f")
+ (match_operand:FP 1 "fp_src_operand" "f,f<FP:dreg><Q>U")))]
"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";
-})
+ "@
+ fcmp%.d %1,%0
+ fcmp%.<FP:prec> %f1,%0")
;; 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,13 @@
(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) || !standard_68881_constant_p (op)
+ || reload_in_progress || reload_completed;
+})
--