aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Zippel <zippel@linux-m68k.org>2007-09-24 21:00:22 +0000
committerRoman Zippel <zippel@gcc.gnu.org>2007-09-24 21:00:22 +0000
commit67595cbb21ce2cd419dcc390e811e4cdb2ef25af (patch)
treeb12c268d3ca97c1c3fc26e082610c65867cd1276
parentd5aa0eb1c46a81b4daa9d6107504e4464a05116e (diff)
downloadgcc-67595cbb21ce2cd419dcc390e811e4cdb2ef25af.zip
gcc-67595cbb21ce2cd419dcc390e811e4cdb2ef25af.tar.gz
gcc-67595cbb21ce2cd419dcc390e811e4cdb2ef25af.tar.bz2
m68k.c (notice_update_cc): Recognize fp compare (moved from fp compare patterns).
* 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. From-SVN: r128727
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/m68k/m68k.c7
-rw-r--r--gcc/config/m68k/m68k.md77
-rw-r--r--gcc/config/m68k/predicates.md13
4 files changed, 67 insertions, 40 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7283412..c092fec 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2007-09-24 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.
+
2007-09-24 Roman Zippel <zippel@linux-m68k.org>
* gcc/final.c (final_scan_insn): Remove accidentally duplicated code.
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index c8e5a6f..1f6b4f9 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -3513,6 +3513,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 *
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index b3f12d8..b6ce6a8 100644
--- a/gcc/config/m68k/m68k.md
+++ b/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.
@@ -7683,7 +7667,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"))]
diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md
index bf96863..b43e55b 100644
--- a/gcc/config/m68k/predicates.md
+++ b/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));
+})