diff options
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/m68k/m68k.c | 7 | ||||
-rw-r--r-- | gcc/config/m68k/m68k.md | 77 | ||||
-rw-r--r-- | gcc/config/m68k/predicates.md | 13 |
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)); +}) |