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: [PATCH 2/4] The main m68k cc0 conversion


Once more with patch.


Bernd
            PR target/91851
            * config/m68k/m68k-protos.h (output-dbcc_and_branch): Adjust
            declaration.
            (m68k_init_cc): New declaration.
            (m68k_output_compare_di, m68k_output_compare_si,
            m68k_output_compare_hi, m68k_output_compare_qi,
            m68k_output_compare_fp, m68k_output_btst, m68k_output_bftst,
            m68k_find_flags_value, m68k_output_scc, m68k_output_scc_float,
            m68k_output_branch_integer, m68k_output_branch_integer_rev.
            m68k_output_branch_float, m68k_output_branch_float_rev):
            Likewise.
            (valid_dbcc_comparison_p_2, flags_in_68881,
            output_btst): Remove declaration.
            * config/m68k/m68k.c (INCLDUE_STRING): Define.
            (TARGET_ASM_FINAL_POSTSCAN_INSN): Define.
            (valid_dbcc_comparison_p_2, flags_in_68881): Delete functions.
            (flags_compare_op0, flags_compare_op1, flags_operand1,
            flags_operand2, flags_valid): New static variables.
            (m68k_find_flags_value, m68k_init_cc): New functions.
            (handle_flags_for_move, m68k_asm_final_postscan_insn,
            remember_compare_flags): New static functions.
            (output_dbcc_and_branch): New argument CODE.  Use it, and add
            PLUS and MINUS to the possible codes.  All callers changed.
            (m68k_output_btst): Renamed from output_btst.  Remove OPERANDS
            and INSN arguments, add CODE arg.  Return the comparison code
            to use.  All callers changed.  Use CODE instead of
            next_insn_tests_no_inequality, and replace cc_status management
            with changing the return code.
            (m68k_rtx_costs): Instead of testing for COMPARE, test for
            RTX_COMPARE or RTX_COMM_COMPARE.
            (output_move_simode, output_move_qimode): Call
            handle_flags_for_move.
            (notice_update_cc): Delete function.
            (m68k_output_bftst, m68k_output_compare_di, m68k_output_compare_si,
            m68k_output_compare_hi, m68k_output_compare_qi,
            m68k_output_compare_fp, m68k_output_branch_integer,
            m68k_output_branch_integer_rev, m68k_output_scc,
            m68k_output_branch_float, m68k_output_branch_float_rev,
            m68k_output_scc_float): New functions.
            (output_andsi3, output_iorsi3, output_xorsi3): Call CC_STATUS_INIT
            once at the start, and set flags_valid and flags_operand1 if the
            flags are usable.
            * config/m68k/m68k.h (CC_IN_68881, NOTICE_UPDATE_CC,
            CC_OVERFLOW_UNUSABLE, CC_NO_CARRY, OUTPUT_JUMP): Remove
            definitions.
            (CC_STATUS_INIT): Define.
            * config/m68k/m68k.md (flags_valid): New define_attr.
            (tstdi, tstsi_internal_68020_cf, tstsi_internal, tsthi_internal,
            tstqi_internal, tst<mode>_68881, tst<mode>_cf, cmpdi_internal,
            cmpdi, unnamed cmpsi/cmphi/cmpqi patterns, cmpsi_cf,
            cmp<mode>_68881, cmp<mode>_cf, unnamed btst patterns,
            tst_bftst_reg, tst_bftst_reg, unnamed scc patterns, scc,
            sls, sordered_1, sunordered_1, suneq_1, sunge_1, sungt_1,
            sunle_1, sunlt_1, sltgt_1, fsogt_1, fsoge_1, fsolt_1, fsole_1,
            bge0_di, blt0_di, beq, bne, bgt, bgtu, blt, bltu, bge, bgeu,
            ble, bleu, bordered, bunordered, buneq, bunge, bungt, bunle,
            bunlt, bltgt, beq_rev, bne_rev, bgt_rev, bgtu_rev,
            blt_rev, bltu_rev, bge_rev, bgeu_rev, ble_rev, bleu_rev,
            bordered_rev, bunordered_rev, buneq_rev, bunge_rv, bungt_rev,
            bunle_rev, bunlt_rev, bltgt_rev, ctrapdi4, ctrapsi4, ctraphi4,
            ctrapqi4, conditional_trap): Delete patterns.
            (cbranchdi4_insn): New pattern.
            (cbranchdi4): Don't generate cc0 patterns.  When testing LT or GE,
            test high part only.  When testing EQ or NE, generate beq0_di
            and bne0_di patterns directly.
            (cstoredi4): When testing LT or GE, test high part only.
            (both sets of cbranch<mode>4, cstore<mode>4): Don't generate cc0
            patterns.
            (scc0_constraints, cmp1_constraints, cmp2_constraints,
            scc0_cf_constraints, cmp1_cf_constraints, cmp2_cf_constraints,
            cmp2_cf_predicate): New define_mode_attrs.
            (cbranch<mode>4_insn, cbranch<mode>4_insn_rev,
            cbranch<mode>4_insn_cf, cbranch<mode>4_insn_cf_rev,
            cstore<mode>4_insn, cstore<mode>4_insn_cf for integer modes)
            New patterns.
            (cbranch<mode>4_insn_68881, cbranch<mode>4_insn_rev_68881):
            (cbranch<mode>4_insn_cf, cbranch<mode>4_insn_rev_cf,
            cstore<mode>4_insn_68881, cstore<mode>4_insn_cf for FP):
            New patterns.
            (cbranchsi4_btst_mem_insn, cbranchsi4_btst_reg_insn,
            cbranchsi4_btst_mem_insn_1, cbranchsi4_btst_reg_insn_1):
            Likewise.
            (BTST): New define_mode_iterator.
            (btst_predicate, btst_constraint, btst_range): New
            define_mode_attrs.
            (cbranch_bftst<mode>_insn, cstore_bftst<mode>_insn): New
            patterns.
            (movsi_m68k_movsi_m68k2, movsi_cf, unnamed movstrict patterns,
            unnamed movhi and movqi patterns, unnamed movsf, movdf and movxf
            patterns): Set attr "flags_valid".
            (truncsiqi2, trunchiqi2, truncsihi2): Remove manual CC_STATUS
            management.  Set attr "flags_valid".
            (extendsidi2, extendplussidi, unnamed float_extendsfdf pattern,
            extendsfdf2_cf, fix_truncdfsi2, fix_truncdfhi2, fix_truncdfqi2,
            addi_sexthishl32, adddi_dilshr32, adddi_dilshr32_cf,
            addi_dishl32, subdi_sexthishl32, subdi_dishl32, subdi3): Remove
            manual CC_STATUS management.
            (addsi3_internal, addhi3, addqi3, subsi3, subhi3, subqi3,
            unnamed strict_lowpart subhi and subqi patterns): Set attr
            "flags_valid".
            (unnamed strict_lowpart addhi3 and addqi3 patterns): Likewise.
            Remove code to operate on address regs and assert the case
            does not occur.
            (unnamed mulsidi patterns, divmodhi4, udivmodhi4): Remove
            manual CC_STATUS_INIT.
            (andsi3_internal, andhi3, andqi3, iorsi3_internal, iorhi3, iorqi3,
            xorsi3_internal, xorhi3, xorqi3, negsi2_internal,
            negsi2_5200, neghi2, negqi2, one_cmplsi2_internal, one_cmplhi2,
            one_cmplqi2, unnamed strict_lowpart patterns
            for andhi, andqi, iorhi, iorqi, xorhi, xorqi, neghi, negqi,
            one_cmplhi and one_cmplqi): Set attr "flags_valid".
            (iorsi_zext_ashl16, iorsi_zext): Remove manual CC_STATUS_INIT.
            (ashldi_sexthi, ashlsi_16, ashlsi_17_24): Remove manual
            CC_STATUS_INIT.
            (ashlsi3, ashlhi3, ashlqi3, ashrsi3, ashrhi3, ashrqi3, lshrsi3,
            lshrhi3, shrqi3, rotlsi3, rotlhi3, rotlhi3_lowpart, rotlqi3,
            rotlqi3_lowpart, rotrsi3, rotrhi3, rotrhi_lowpart, rotrqi3,
            unnamed strict_low_part patterns for HI and
            QI versions): Set attr "flags_valid".
            (bsetmemqi, bsetmemqi_ext, bsetdreg, bchgdreg, bclrdreg,
            bclrmemqi, extzv_8_16_reg, extzv_bfextu_mem, insv_bfchg_mem,
            insv_bfclr_mem, insv_bfset_mem, extv_bfextu_reg,
            insv_bfclr_reg, insv_bfset_reg, dbne_hi, dbne_si, dbge_hi,
            dbge_si, extendsfxf2, extenddfxf2, ): Remove manual cc_status management.
            (various unnamed peepholes): Adjust compare/branch sequences
            for new cbranch patterns.
            (dbcc peepholes): Likewise, and output the comparison here
            as well.
            * config/m68k/predicates.md (valid_dbcc_comparison_p): Delete.
            (fp_src_operand): Allow constant zero.
            (address_reg_operand): New predicate.
    
            * rtl.h (inequality_comparisons_p): Remove declaration.
            * recog.h (next_insn_tests_no_inequality): Likewise.
            * rtlanal.c (inequality_comparisons_p): Delete function.
            * recog.c (next_insn_tests_no_inequality): Likewise.

diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h
index abd920e70f3..634adcfc23a 100644
--- a/gcc/config/m68k/m68k-protos.h
+++ b/gcc/config/m68k/m68k-protos.h
@@ -34,7 +34,6 @@ extern const char *output_move_strictqi (rtx *);
 extern const char *output_move_double (rtx *);
 extern const char *output_move_const_single (rtx *);
 extern const char *output_move_const_double (rtx *);
-extern const char *output_btst (rtx *, rtx, rtx, rtx_insn *, int);
 extern const char *output_scc_di (rtx, rtx, rtx, rtx);
 extern const char *output_addsi3 (rtx *);
 extern const char *output_andsi3 (rtx *);
@@ -42,7 +41,23 @@ extern const char *output_iorsi3 (rtx *);
 extern const char *output_xorsi3 (rtx *);
 extern const char *output_call (rtx);
 extern const char *output_sibcall (rtx);
-extern void output_dbcc_and_branch (rtx *);
+extern void m68k_init_cc ();
+extern void output_dbcc_and_branch (rtx *, rtx_code);
+extern rtx_code m68k_output_compare_di (rtx, rtx, rtx, rtx, rtx_insn *, rtx_code);
+extern rtx_code m68k_output_compare_si (rtx, rtx, rtx_code);
+extern rtx_code m68k_output_compare_hi (rtx, rtx, rtx_code);
+extern rtx_code m68k_output_compare_qi (rtx, rtx, rtx_code);
+extern rtx_code m68k_output_compare_fp (rtx, rtx, rtx_code);
+extern rtx_code m68k_output_btst (rtx, rtx, rtx_code, int);
+extern rtx_code m68k_output_bftst (rtx, rtx, rtx, rtx_code);
+extern rtx_code m68k_find_flags_value (rtx, rtx, rtx_code);
+
+extern const char *m68k_output_scc (rtx_code);
+extern const char *m68k_output_scc_float (rtx_code);
+extern const char *m68k_output_branch_integer (rtx_code);
+extern const char *m68k_output_branch_integer_rev (rtx_code);
+extern const char *m68k_output_branch_float (rtx_code);
+extern const char *m68k_output_branch_float_rev (rtx_code);
 extern int floating_exact_log2 (rtx);
 extern bool strict_low_part_peephole_ok (machine_mode mode,
 					 rtx_insn *first_insn, rtx target);
@@ -61,7 +76,6 @@ extern bool m68k_matches_u_p (rtx);
 extern rtx legitimize_pic_address (rtx, machine_mode, rtx);
 extern rtx m68k_legitimize_tls_address (rtx);
 extern bool m68k_tls_reference_p (rtx, bool);
-extern int valid_dbcc_comparison_p_2 (rtx, machine_mode);
 extern rtx m68k_libcall_value (machine_mode);
 extern rtx m68k_function_value (const_tree, const_tree);
 extern int emit_move_sequence (rtx *, machine_mode, rtx);
@@ -88,7 +102,6 @@ extern enum attr_op_mem m68k_sched_attr_op_mem (rtx_insn *);
 extern enum reg_class m68k_secondary_reload_class (enum reg_class,
 						   machine_mode, rtx);
 extern enum reg_class m68k_preferred_reload_class (rtx, enum reg_class);
-extern int flags_in_68881 (void);
 extern void m68k_expand_prologue (void);
 extern bool m68k_use_return_insn (void);
 extern void m68k_expand_epilogue (bool);
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 4f3503b9118..c72325fa4ab 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3.  If not see
 #define IN_TARGET_CODE 1
 
 #include "config.h"
+#define INCLUDE_STRING
 #include "system.h"
 #include "coretypes.h"
 #include "backend.h"
@@ -194,6 +195,7 @@ static bool m68k_hard_regno_mode_ok (unsigned int, machine_mode);
 static bool m68k_modes_tieable_p (machine_mode, machine_mode);
 static machine_mode m68k_promote_function_mode (const_tree, machine_mode,
 						int *, const_tree, int);
+static void m68k_asm_final_postscan_insn (FILE *, rtx_insn *insn, rtx [], int);
 
 /* Initialize the GCC target structure.  */
 
@@ -355,6 +357,9 @@ static machine_mode m68k_promote_function_mode (const_tree, machine_mode,
 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
 
+#undef TARGET_ASM_FINAL_POSTSCAN_INSN
+#define TARGET_ASM_FINAL_POSTSCAN_INSN m68k_asm_final_postscan_insn
+
 static const struct attribute_spec m68k_attribute_table[] =
 {
   /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
@@ -1356,40 +1361,6 @@ m68k_expand_epilogue (bool sibcall_p)
     emit_jump_insn (ret_rtx);
 }
 
-/* Return true if X is a valid comparison operator for the dbcc 
-   instruction.  
-
-   Note it rejects floating point comparison operators.
-   (In the future we could use Fdbcc).
-
-   It also rejects some comparisons when CC_NO_OVERFLOW is set.  */
-   
-int
-valid_dbcc_comparison_p_2 (rtx x, machine_mode mode ATTRIBUTE_UNUSED)
-{
-  switch (GET_CODE (x))
-    {
-      case EQ: case NE: case GTU: case LTU:
-      case GEU: case LEU:
-        return 1;
-
-      /* Reject some when CC_NO_OVERFLOW is set.  This may be over
-         conservative */
-      case GT: case LT: case GE: case LE:
-        return ! (cc_prev_status.flags & CC_NO_OVERFLOW);
-      default:
-        return 0;
-    }
-}
-
-/* Return nonzero if flags are currently in the 68881 flag register.  */
-int
-flags_in_68881 (void)
-{
-  /* We could add support for these in the future */
-  return cc_status.flags & CC_IN_68881;
-}
-
 /* Return true if PARALLEL contains register REGNO.  */
 static bool
 m68k_reg_present_p (const_rtx parallel, unsigned int regno)
@@ -1580,18 +1551,186 @@ m68k_legitimize_address (rtx x, rtx oldx, machine_mode mode)
 
   return x;
 }
+
+/* For eliding comparisons, we remember how the flags were set.
+   FLAGS_COMPARE_OP0 and FLAGS_COMPARE_OP1 are remembered for a direct
+   comparison, they take priority.  FLAGS_OPERAND1 and FLAGS_OPERAND2
+   are used in more cases, they are a fallback for comparisons against
+   zero after a move or arithmetic insn.
+   FLAGS_VALID is set to FLAGS_VALID_NO if we should not use any of
+   these values.  */
+
+static rtx flags_compare_op0, flags_compare_op1;
+static rtx flags_operand1, flags_operand2;
+static attr_flags_valid flags_valid = FLAGS_VALID_NO;
+
+/* Return a code other than UNKNOWN if we can elide a CODE comparison of
+   OP0 with OP1.  */
+
+rtx_code
+m68k_find_flags_value (rtx op0, rtx op1, rtx_code code)
+{
+  if (flags_compare_op0 != NULL_RTX)
+    {
+      if (rtx_equal_p (op0, flags_compare_op0)
+	  && rtx_equal_p (op1, flags_compare_op1))
+	return code;
+      if (rtx_equal_p (op0, flags_compare_op1)
+	  && rtx_equal_p (op1, flags_compare_op0))
+	return swap_condition (code);
+      return UNKNOWN;
+    }
+
+  machine_mode mode = GET_MODE (op0);
+  if (op1 != CONST0_RTX (mode))
+    return UNKNOWN;
+  /* Comparisons against 0 with these two should have been optimized out.  */
+  gcc_assert (code != LTU && code != GEU);
+  if (flags_valid == FLAGS_VALID_NOOV && (code == GT || code == LE))
+    return UNKNOWN;
+  if (rtx_equal_p (flags_operand1, op0) || rtx_equal_p (flags_operand2, op0))
+    return (FLOAT_MODE_P (mode) ? code
+	    : code == GE ? PLUS : code == LT ? MINUS : code);
+  /* See if we are testing whether the high part of a DImode value is
+     positive or negative and we have the full value as a remembered
+     operand.  */
+  if (code != GE && code != LT)
+    return UNKNOWN;
+  if (mode == SImode
+      && flags_operand1 != NULL_RTX && GET_MODE (flags_operand1) == DImode
+      && REG_P (flags_operand1) && REG_P (op0)
+      && hard_regno_nregs (REGNO (flags_operand1), DImode) == 2
+      && REGNO (flags_operand1) == REGNO (op0))
+    return code == GE ? PLUS : MINUS;
+  if (mode == SImode
+      && flags_operand2 != NULL_RTX && GET_MODE (flags_operand2) == DImode
+      && REG_P (flags_operand2) && REG_P (op0)
+      && hard_regno_nregs (REGNO (flags_operand2), DImode) == 2
+      && REGNO (flags_operand2) == REGNO (op0))
+    return code == GE ? PLUS : MINUS;
+  return UNKNOWN;
+}
+
+/* Called through CC_STATUS_INIT, which is invoked by final whenever a
+   label is encountered.  */
+
+void
+m68k_init_cc ()
+{
+  flags_compare_op0 = flags_compare_op1 = NULL_RTX;
+  flags_operand1 = flags_operand2 = NULL_RTX;
+  flags_valid = FLAGS_VALID_NO;
+}
+
+/* Update flags for a move operation with OPERANDS.  Called for move
+   operations where attr_flags_valid returns "set".  */
+
+static void
+handle_flags_for_move (rtx *operands)
+{
+  flags_compare_op0 = flags_compare_op1 = NULL_RTX;
+  if (!ADDRESS_REG_P (operands[0]))
+    {
+      flags_valid = FLAGS_VALID_MOVE;
+      flags_operand1 = side_effects_p (operands[0]) ? NULL_RTX : operands[0];
+      if (side_effects_p (operands[1])
+	  /* ??? For mem->mem moves, this can discard the source as a
+	     valid compare operand.  If you assume aligned moves, this
+	     is unnecessary, but in theory, we could have an unaligned
+	     move overwriting parts of its source.  */
+	  || modified_in_p (operands[1], current_output_insn))
+	flags_operand2 = NULL_RTX;
+      else
+	flags_operand2 = operands[1];
+      return;
+    }
+  if (flags_operand1 != NULL_RTX
+      && modified_in_p (flags_operand1, current_output_insn))
+    flags_operand1 = NULL_RTX;
+  if (flags_operand2 != NULL_RTX
+      && modified_in_p (flags_operand2, current_output_insn))
+    flags_operand2 = NULL_RTX;
+}
+
+/* Process INSN to remember flag operands if possible.  */
+
+static void
+m68k_asm_final_postscan_insn (FILE *, rtx_insn *insn, rtx [], int)
+{
+  enum attr_flags_valid v = get_attr_flags_valid (insn);
+  if (v == FLAGS_VALID_SET)
+    return;
+  /* Comparisons use FLAGS_VALID_SET, so we can be sure we need to clear these
+     now.  */
+  flags_compare_op0 = flags_compare_op1 = NULL_RTX;
+
+  if (v == FLAGS_VALID_NO)
+    {
+      flags_operand1 = flags_operand2 = NULL_RTX;
+      return;
+    }
+  else if (v == FLAGS_VALID_UNCHANGED)
+    {
+      if (flags_operand1 != NULL_RTX && modified_in_p (flags_operand1, insn))
+	flags_operand1 = NULL_RTX;
+      if (flags_operand2 != NULL_RTX && modified_in_p (flags_operand2, insn))
+	flags_operand2 = NULL_RTX;
+      return;
+    }
+
+  flags_valid = v;
+  rtx set = single_set (insn);
+  rtx dest = SET_DEST (set);
+  rtx src = SET_SRC (set);
+  if (side_effects_p (dest))
+      dest = NULL_RTX;
+
+  switch (v)
+    {
+    case FLAGS_VALID_YES:
+    case FLAGS_VALID_NOOV:
+      flags_operand1 = dest;
+      flags_operand2 = NULL_RTX;
+      break;
+    case FLAGS_VALID_MOVE:
+      /* fmoves to memory or data registers do not set the condition
+	 codes.  Normal moves _do_ set the condition codes, but not in
+	 a way that is appropriate for comparison with 0, because -0.0
+	 would be treated as a negative nonzero number.  Note that it
+	 isn't appropriate to conditionalize this restriction on
+	 HONOR_SIGNED_ZEROS because that macro merely indicates whether
+	 we care about the difference between -0.0 and +0.0.  */
+      if (dest != NULL_RTX
+	  && !FP_REG_P (dest)
+	  && (FP_REG_P (src)
+	      || GET_CODE (src) == FIX
+	      || FLOAT_MODE_P (GET_MODE (dest))))
+	flags_operand1 = flags_operand2 = NULL_RTX;
+      else
+	{
+	  flags_operand1 = dest;
+	  if (GET_MODE (src) != VOIDmode && !side_effects_p (src)
+	      && !modified_in_p (src, insn))
+	    flags_operand2 = src;
+	  else
+	    flags_operand2 = NULL_RTX;
+	}
+      break;
+    default:
+      gcc_unreachable ();
+    }
+  return;
+}
 
- 
 /* Output a dbCC; jCC sequence.  Note we do not handle the 
-   floating point version of this sequence (Fdbcc).  We also
-   do not handle alternative conditions when CC_NO_OVERFLOW is
-   set.  It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
-   kick those out before we get here.  */
+   floating point version of this sequence (Fdbcc).
+   OPERANDS are as in the two peepholes.  CODE is the code
+   returned by m68k_output_branch_<mode>.  */
 
 void
-output_dbcc_and_branch (rtx *operands)
+output_dbcc_and_branch (rtx *operands, rtx_code code)
 {
-  switch (GET_CODE (operands[3]))
+  switch (code)
     {
       case EQ:
 	output_asm_insn ("dbeq %0,%l1\n\tjeq %l2", operands);
@@ -1633,6 +1772,14 @@ output_dbcc_and_branch (rtx *operands)
 	output_asm_insn ("dbls %0,%l1\n\tjls %l2", operands);
 	break;
 
+      case PLUS:
+	output_asm_insn ("dbpl %0,%l1\n\tjle %l2", operands);
+	break;
+
+      case MINUS:
+	output_asm_insn ("dbmi %0,%l1\n\tjle %l2", operands);
+	break;
+
       default:
 	gcc_unreachable ();
     }
@@ -1790,11 +1937,12 @@ output_scc_di (rtx op, rtx operand1, rtx operand2, rtx dest)
   return "";
 }
 
-const char *
-output_btst (rtx *operands, rtx countop, rtx dataop, rtx_insn *insn, int signpos)
+rtx_code
+m68k_output_btst (rtx countop, rtx dataop, rtx_code code, int signpos)
 {
-  operands[0] = countop;
-  operands[1] = dataop;
+  rtx ops[2];
+  ops[0] = countop;
+  ops[1] = dataop;
 
   if (GET_CODE (countop) == CONST_INT)
     {
@@ -1805,40 +1953,41 @@ output_btst (rtx *operands, rtx countop, rtx dataop, rtx_insn *insn, int signpos
 	{
 	  int offset = (count & ~signpos) / 8;
 	  count = count & signpos;
-	  operands[1] = dataop = adjust_address (dataop, QImode, offset);
+	  ops[1] = dataop = adjust_address (dataop, QImode, offset);
+	}
+
+      if (code == EQ || code == NE)
+	{
+	  if (count == 31)
+	    {
+	      output_asm_insn ("tst%.l %1", ops);
+	      return code == EQ ? PLUS : MINUS;
+	    }
+	  if (count == 15)
+	    {
+	      output_asm_insn ("tst%.w %1", ops);
+	      return code == EQ ? PLUS : MINUS;
+	    }
+	  if (count == 7)
+	    {
+	      output_asm_insn ("tst%.b %1", ops);
+	      return code == EQ ? PLUS : MINUS;
+	    }
 	}
-      if (count == signpos)
-	cc_status.flags = CC_NOT_POSITIVE | CC_Z_IN_NOT_N;
-      else
-	cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N;
-
-      /* These three statements used to use next_insns_test_no...
-	 but it appears that this should do the same job.  */
-      if (count == 31
-	  && next_insn_tests_no_inequality (insn))
-	return "tst%.l %1";
-      if (count == 15
-	  && next_insn_tests_no_inequality (insn))
-	return "tst%.w %1";
-      if (count == 7
-	  && next_insn_tests_no_inequality (insn))
-	return "tst%.b %1";
       /* Try to use `movew to ccr' followed by the appropriate branch insn.
          On some m68k variants unfortunately that's slower than btst.
          On 68000 and higher, that should also work for all HImode operands. */
       if (TUNE_CPU32 || TARGET_COLDFIRE || optimize_size)
 	{
-	  if (count == 3 && DATA_REG_P (operands[1])
-	      && next_insn_tests_no_inequality (insn))
+	  if (count == 3 && DATA_REG_P (ops[1]) && (code == EQ || code == NE))
 	    {
-	    cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N | CC_NO_OVERFLOW;
-	    return "move%.w %1,%%ccr";
+	      output_asm_insn ("move%.w %1,%%ccr", ops);
+	      return code == EQ ? PLUS : MINUS;
 	    }
-	  if (count == 2 && DATA_REG_P (operands[1])
-	      && next_insn_tests_no_inequality (insn))
+	  if (count == 2 && DATA_REG_P (ops[1]) && (code == EQ || code == NE))
 	    {
-	    cc_status.flags = CC_NOT_NEGATIVE | CC_INVERTED | CC_NO_OVERFLOW;
-	    return "move%.w %1,%%ccr";
+	      output_asm_insn ("move%.w %1,%%ccr", ops);
+	      return code == EQ ? NE : EQ;
 	    }
 	  /* count == 1 followed by bvc/bvs and
 	     count == 0 followed by bcc/bcs are also possible, but need
@@ -1847,7 +1996,28 @@ output_btst (rtx *operands, rtx countop, rtx dataop, rtx_insn *insn, int signpos
 
       cc_status.flags = CC_NOT_NEGATIVE;
     }
-  return "btst %0,%1";
+  output_asm_insn ("btst %0,%1", ops);
+  return code;
+}
+
+/* Output a bftst instruction for a zero_extract with ZXOP0, ZXOP1 and ZXOP2
+   operands.  CODE is the code of the comparison, and we return the code to
+   be actually used in the jump.  */
+
+rtx_code
+m68k_output_bftst (rtx zxop0, rtx zxop1, rtx zxop2, rtx_code code)
+{
+  if (zxop1 == const1_rtx && GET_CODE (zxop2) == CONST_INT)
+    {
+      int width = GET_CODE (zxop0) == REG ? 31 : 7;
+      /* Pass 1000 as SIGNPOS argument so that btst will
+	 not think we are testing the sign bit for an `and'
+	 and assume that nonzero implies a negative result.  */
+      return m68k_output_btst (GEN_INT (width - INTVAL (zxop2)), zxop0, code, 1000);
+    }
+  rtx ops[3] = { zxop0, zxop1, zxop2 };
+  output_asm_insn ("bftst %0{%b2:%b1}", ops);
+  return code;
 }
 
 /* Return true if X is a legitimate base register.  STRICT_P says
@@ -2839,7 +3009,8 @@ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
     case CONST_DOUBLE:
       /* Make 0.0 cheaper than other floating constants to
          encourage creating tstsf and tstdf insns.  */
-      if (outer_code == COMPARE
+      if ((GET_RTX_CLASS (outer_code) == RTX_COMPARE
+	   || GET_RTX_CLASS (outer_code) == RTX_COMM_COMPARE)
           && (x == CONST0_RTX (SFmode) || x == CONST0_RTX (DFmode)))
 	*total = 4;
       else
@@ -2953,7 +3124,8 @@ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
       return true;
 
     case ZERO_EXTRACT:
-      if (outer_code == COMPARE)
+      if (GET_RTX_CLASS (outer_code) == RTX_COMPARE
+	  || GET_RTX_CLASS (outer_code) == RTX_COMM_COMPARE)
         *total = 0;
       return false;
 
@@ -3056,6 +3228,8 @@ output_move_simode_const (rtx *operands)
 const char *
 output_move_simode (rtx *operands)
 {
+  handle_flags_for_move (operands);
+
   if (GET_CODE (operands[1]) == CONST_INT)
     return output_move_simode_const (operands);
   else if ((GET_CODE (operands[1]) == SYMBOL_REF
@@ -3101,6 +3275,8 @@ output_move_himode (rtx *operands)
 const char *
 output_move_qimode (rtx *operands)
 {
+  handle_flags_for_move (operands);
+
   /* 68k family always modifies the stack pointer by at least 2, even for
      byte pushes.  The 5200 (ColdFire) does not do this.  */
 
@@ -4136,125 +4312,440 @@ output_addsi3 (rtx *operands)
     }
   return "add%.l %2,%0";
 }
-
-/* Store in cc_status the expressions that the condition codes will
-   describe after execution of an instruction whose pattern is EXP.
-   Do not alter them if the instruction would not alter the cc's.  */
 
-/* On the 68000, all the insns to store in an address register fail to
-   set the cc's.  However, in some cases these instructions can make it
-   possibly invalid to use the saved cc's.  In those cases we clear out
-   some or all of the saved cc's so they won't be used.  */
-
-void
-notice_update_cc (rtx exp, rtx insn)
+/* Emit a comparison between OP0 and OP1.  Return true iff the comparison
+   was reversed.  SC1 is an SImode scratch reg, and SC2 a DImode scratch reg,
+   as needed.  CODE is the code of the comparison, we return it unchanged or
+   swapped, as necessary.  */
+rtx_code
+m68k_output_compare_di (rtx op0, rtx op1, rtx sc1, rtx sc2, rtx_insn *insn,
+			rtx_code code)
 {
-  if (GET_CODE (exp) == SET)
+  rtx ops[4];
+  ops[0] = op0;
+  ops[1] = op1;
+  ops[2] = sc1;
+  ops[3] = sc2;
+  if (op1 == const0_rtx)
     {
-      if (GET_CODE (SET_SRC (exp)) == CALL)
-	CC_STATUS_INIT; 
-      else if (ADDRESS_REG_P (SET_DEST (exp)))
+      if (!REG_P (op0) || ADDRESS_REG_P (op0))
 	{
-	  if (cc_status.value1 && modified_in_p (cc_status.value1, insn))
-	    cc_status.value1 = 0;
-	  if (cc_status.value2 && modified_in_p (cc_status.value2, insn))
-	    cc_status.value2 = 0; 
+	  rtx xoperands[2];
+
+	  xoperands[0] = sc2;
+	  xoperands[1] = op0;
+	  output_move_double (xoperands);
+	  output_asm_insn ("neg%.l %R0\n\tnegx%.l %0", xoperands);
+	  return swap_condition (code);
 	}
-      /* fmoves to memory or data registers do not set the condition
-	 codes.  Normal moves _do_ set the condition codes, but not in
-	 a way that is appropriate for comparison with 0, because -0.0
-	 would be treated as a negative nonzero number.  Note that it
-	 isn't appropriate to conditionalize this restriction on
-	 HONOR_SIGNED_ZEROS because that macro merely indicates whether
-	 we care about the difference between -0.0 and +0.0.  */
-      else if (!FP_REG_P (SET_DEST (exp))
-	       && SET_DEST (exp) != cc0_rtx
-	       && (FP_REG_P (SET_SRC (exp))
-		   || GET_CODE (SET_SRC (exp)) == FIX
-		   || FLOAT_MODE_P (GET_MODE (SET_DEST (exp)))))
-	CC_STATUS_INIT; 
-      /* A pair of move insns doesn't produce a useful overall cc.  */
-      else if (!FP_REG_P (SET_DEST (exp))
-	       && !FP_REG_P (SET_SRC (exp))
-	       && GET_MODE_SIZE (GET_MODE (SET_SRC (exp))) > 4
-	       && (GET_CODE (SET_SRC (exp)) == REG
-		   || GET_CODE (SET_SRC (exp)) == MEM
-		   || GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
-	CC_STATUS_INIT; 
-      else if (SET_DEST (exp) != pc_rtx)
+      if (find_reg_note (insn, REG_DEAD, op0))
 	{
-	  cc_status.flags = 0;
-	  cc_status.value1 = SET_DEST (exp);
-	  cc_status.value2 = SET_SRC (exp);
+	  output_asm_insn ("neg%.l %R0\n\tnegx%.l %0", ops);
+	  return swap_condition (code);
 	}
-    }
-  else if (GET_CODE (exp) == PARALLEL
-	   && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
-    {
-      rtx dest = SET_DEST (XVECEXP (exp, 0, 0));
-      rtx src  = SET_SRC  (XVECEXP (exp, 0, 0));
-
-      if (ADDRESS_REG_P (dest))
-	CC_STATUS_INIT;
-      else if (dest != pc_rtx)
+      else
 	{
-	  cc_status.flags = 0;
-	  cc_status.value1 = dest;
-	  cc_status.value2 = src;
+	  /* 'sub' clears %1, and also clears the X cc bit.
+	     'tst' sets the Z cc bit according to the low part of the DImode
+	     operand.
+	     'subx %1' (i.e. subx #0) acts as a (non-existent) tstx on the high
+	     part.  */
+	  output_asm_insn ("sub%.l %2,%2\n\ttst%.l %R0\n\tsubx%.l %2,%0", ops);
+	  return code;
 	}
     }
+
+  if (rtx_equal_p (sc2, op0))
+    {
+      output_asm_insn ("sub%.l %R1,%R3\n\tsubx%.l %1,%3", ops);
+      return code;
+    }
   else
+    {
+      output_asm_insn ("sub%.l %R0,%R3\n\tsubx%.l %0,%3", ops);
+      return swap_condition (code);
+    }
+}
+
+static void
+remember_compare_flags (rtx op0, rtx op1)
+{
+  if (side_effects_p (op0) || side_effects_p (op1))
     CC_STATUS_INIT;
-  if (cc_status.value2 != 0
-      && ADDRESS_REG_P (cc_status.value2)
-      && GET_MODE (cc_status.value2) == QImode)
-    CC_STATUS_INIT;
-  if (cc_status.value2 != 0)
-    switch (GET_CODE (cc_status.value2))
-      {
-      case ASHIFT: case ASHIFTRT: case LSHIFTRT:
-      case ROTATE: case ROTATERT:
-	/* These instructions always clear the overflow bit, and set
-	   the carry to the bit shifted out.  */
-	cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
-	break;
+  else
+    {
+      flags_compare_op0 = op0;
+      flags_compare_op1 = op1;
+      flags_operand1 = flags_operand2 = NULL_RTX;
+      flags_valid = FLAGS_VALID_SET;
+    }
+}
 
-      case PLUS: case MINUS: case MULT:
-      case DIV: case UDIV: case MOD: case UMOD: case NEG:
-	if (GET_MODE (cc_status.value2) != VOIDmode)
-	  cc_status.flags |= CC_NO_OVERFLOW;
-	break;
-      case ZERO_EXTEND:
-	/* (SET r1 (ZERO_EXTEND r2)) on this machine
-	   ends with a move insn moving r2 in r2's mode.
-	   Thus, the cc's are set for r2.
-	   This can set N bit spuriously.  */
-	cc_status.flags |= CC_NOT_NEGATIVE; 
+/* Emit a comparison between OP0 and OP1.  CODE is the code of the
+   comparison.  It is returned, potentially modified if necessary.  */
+rtx_code
+m68k_output_compare_si (rtx op0, rtx op1, rtx_code code)
+{
+  rtx_code tmp = m68k_find_flags_value (op0, op1, code);
+  if (tmp != UNKNOWN)
+    return tmp;
 
-      default:
-	break;
-      }
-  if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
-      && cc_status.value2
-      && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
-    cc_status.value2 = 0;
-  /* Check for PRE_DEC in dest modifying a register used in src.  */
-  if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM
-      && GET_CODE (XEXP (cc_status.value1, 0)) == PRE_DEC
-      && cc_status.value2
-      && reg_overlap_mentioned_p (XEXP (XEXP (cc_status.value1, 0), 0),
-				  cc_status.value2))
-    cc_status.value2 = 0;
-  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))
-	  && FP_REG_P (XEXP (cc_status.value2, 1)))
-	cc_status.flags |= CC_REVERSED;
+  remember_compare_flags (op0, op1);
+
+  rtx ops[2];
+  ops[0] = op0;
+  ops[1] = op1;
+  if (op1 == const0_rtx && (TARGET_68020 || TARGET_COLDFIRE || !ADDRESS_REG_P (op0)))
+    output_asm_insn ("tst%.l %0", ops);
+  else if (GET_CODE (op0) == MEM && GET_CODE (op1) == MEM)
+    output_asm_insn ("cmpm%.l %1,%0", ops);
+  else if (REG_P (op1)
+      || (!REG_P (op0) && GET_CODE (op0) != MEM))
+    {
+      output_asm_insn ("cmp%.l %d0,%d1", ops);
+      std::swap (flags_compare_op0, flags_compare_op1);
+      return swap_condition (code);
+    }
+  else if (!TARGET_COLDFIRE
+	   && ADDRESS_REG_P (op0)
+	   && GET_CODE (op1) == CONST_INT
+	   && INTVAL (op1) < 0x8000
+	   && INTVAL (op1) >= -0x8000)
+    output_asm_insn ("cmp%.w %1,%0", ops);
+  else
+    output_asm_insn ("cmp%.l %d1,%d0", ops);
+  return code;
+}
+
+/* Emit a comparison between OP0 and OP1.  CODE is the code of the
+   comparison.  It is returned, potentially modified if necessary.  */
+rtx_code
+m68k_output_compare_hi (rtx op0, rtx op1, rtx_code code)
+{
+  rtx_code tmp = m68k_find_flags_value (op0, op1, code);
+  if (tmp != UNKNOWN)
+    return tmp;
+
+  remember_compare_flags (op0, op1);
+
+  rtx ops[2];
+  ops[0] = op0;
+  ops[1] = op1;
+  if (op1 == const0_rtx)
+    output_asm_insn ("tst%.w %d0", ops);
+  else if (GET_CODE (op0) == MEM && GET_CODE (op1) == MEM)
+    output_asm_insn ("cmpm%.w %1,%0", ops);
+  else if ((REG_P (op1) && !ADDRESS_REG_P (op1))
+	   || (!REG_P (op0) && GET_CODE (op0) != MEM))
+    {
+      output_asm_insn ("cmp%.w %d0,%d1", ops);
+      std::swap (flags_compare_op0, flags_compare_op1);
+      return swap_condition (code);
+    }
+  else
+    output_asm_insn ("cmp%.w %d1,%d0", ops);
+  return code;
+}
+
+/* Emit a comparison between OP0 and OP1.  CODE is the code of the
+   comparison.  It is returned, potentially modified if necessary.  */
+rtx_code
+m68k_output_compare_qi (rtx op0, rtx op1, rtx_code code)
+{
+  rtx_code tmp = m68k_find_flags_value (op0, op1, code);
+  if (tmp != UNKNOWN)
+    return tmp;
+
+  remember_compare_flags (op0, op1);
+
+  rtx ops[2];
+  ops[0] = op0;
+  ops[1] = op1;
+  if (op1 == const0_rtx)
+    output_asm_insn ("tst%.b %d0", ops);
+  else if (GET_CODE (op0) == MEM && GET_CODE (op1) == MEM)
+    output_asm_insn ("cmpm%.b %1,%0", ops);
+  else if (REG_P (op1) || (!REG_P (op0) && GET_CODE (op0) != MEM))
+    {
+      output_asm_insn ("cmp%.b %d0,%d1", ops);
+      std::swap (flags_compare_op0, flags_compare_op1);
+      return swap_condition (code);
+    }
+  else
+    output_asm_insn ("cmp%.b %d1,%d0", ops);
+  return code;
+}
+
+/* Emit a comparison between OP0 and OP1.  CODE is the code of the
+   comparison.  It is returned, potentially modified if necessary.  */
+rtx_code
+m68k_output_compare_fp (rtx op0, rtx op1, rtx_code code)
+{
+  rtx_code tmp = m68k_find_flags_value (op0, op1, code);
+  if (tmp != UNKNOWN)
+    return tmp;
+
+  rtx ops[2];
+  ops[0] = op0;
+  ops[1] = op1;
+
+  remember_compare_flags (op0, op1);
+
+  machine_mode mode = GET_MODE (op0);
+  std::string prec = mode == SFmode ? "s" : mode == DFmode ? "d" : "x";
+
+  if (op1 == CONST0_RTX (GET_MODE (op0)))
+    {
+      if (FP_REG_P (op0))
+	output_asm_insn ("ftst%.x %0", ops);
+      else
+	output_asm_insn (("ftst%." + prec + " %0").c_str (), ops);
+      return code;
+    }
+
+  switch (which_alternative)
+    {
+    case 0:
+      output_asm_insn ("fcmp%.x %1,%0", ops);
+      break;
+    case 1:
+      output_asm_insn (("fcmp%." + prec + " %f1,%0").c_str (), ops);
+      break;
+    case 2:
+      output_asm_insn (("fcmp%." + prec + " %0,%f1").c_str (), ops);
+      std::swap (flags_compare_op0, flags_compare_op1);
+      return swap_condition (code);
+    case 3:
+      /* This is the ftst case, handled earlier.  */
+      gcc_unreachable ();
+    }
+  return code;
+}
+
+/* Return an output template for a branch with CODE.  */
+const char *
+m68k_output_branch_integer (rtx_code code)
+{
+  switch (code)
+    {
+    case EQ:
+      return "jeq %l3";
+    case NE:
+      return "jne %l3";
+    case GT:
+      return "jgt %l3";
+    case GTU:
+      return "jhi %l3";
+    case LT:
+      return "jlt %l3";
+    case LTU:
+      return "jcs %l3";
+    case GE:
+      return "jge %l3";
+    case GEU:
+      return "jcc %l3";
+    case LE:
+      return "jle %l3";
+    case LEU:
+      return "jls %l3";
+    case PLUS:
+      return "jpl %l3";
+    case MINUS:
+      return "jmi %l3";
+    default:
+      gcc_unreachable ();
+    }
+}
+
+/* Return an output template for a reversed branch with CODE.  */
+const char *
+m68k_output_branch_integer_rev (rtx_code code)
+{
+  switch (code)
+    {
+    case EQ:
+      return "jne %l3";
+    case NE:
+      return "jeq %l3";
+    case GT:
+      return "jle %l3";
+    case GTU:
+      return "jls %l3";
+    case LT:
+      return "jge %l3";
+    case LTU:
+      return "jcc %l3";
+    case GE:
+      return "jlt %l3";
+    case GEU:
+      return "jcs %l3";
+    case LE:
+      return "jgt %l3";
+    case LEU:
+      return "jhi %l3";
+    case PLUS:
+      return "jmi %l3";
+    case MINUS:
+      return "jpl %l3";
+    default:
+      gcc_unreachable ();
+    }
+}
+
+/* Return an output template for a scc instruction with CODE.  */
+const char *
+m68k_output_scc (rtx_code code)
+{
+  switch (code)
+    {
+    case EQ:
+      return "seq %0";
+    case NE:
+      return "sne %0";
+    case GT:
+      return "sgt %0";
+    case GTU:
+      return "shi %0";
+    case LT:
+      return "slt %0";
+    case LTU:
+      return "scs %0";
+    case GE:
+      return "sge %0";
+    case GEU:
+      return "scc %0";
+    case LE:
+      return "sle %0";
+    case LEU:
+      return "sls %0";
+    case PLUS:
+      return "spl %0";
+    case MINUS:
+      return "smi %0";
+    default:
+      gcc_unreachable ();
+    }
+}
+
+/* Return an output template for a floating point branch
+   instruction with CODE.  */
+const char *
+m68k_output_branch_float (rtx_code code)
+{
+  switch (code)
+    {
+    case EQ:
+      return "fjeq %l3";
+    case NE:
+      return "fjne %l3";
+    case GT:
+      return "fjgt %l3";
+    case LT:
+      return "fjlt %l3";
+    case GE:
+      return "fjge %l3";
+    case LE:
+      return "fjle %l3";
+    case ORDERED:
+      return "fjor %l3";
+    case UNORDERED:
+      return "fjun %l3";
+    case UNEQ:
+      return "fjueq %l3";
+    case UNGE:
+      return "fjuge %l3";
+    case UNGT:
+      return "fjugt %l3";
+    case UNLE:
+      return "fjule %l3";
+    case UNLT:
+      return "fjult %l3";
+    case LTGT:
+      return "fjogl %l3";
+    default:
+      gcc_unreachable ();
+    }
+}
+
+/* Return an output template for a reversed floating point branch
+   instruction with CODE.  */
+const char *
+m68k_output_branch_float_rev (rtx_code code)
+{
+  switch (code)
+    {
+    case EQ:
+      return "fjne %l3";
+    case NE:
+      return "fjeq %l3";
+    case GT:
+      return "fjngt %l3";
+    case LT:
+      return "fjnlt %l3";
+    case GE:
+      return "fjnge %l3";
+    case LE:
+      return "fjnle %l3";
+    case ORDERED:
+      return "fjun %l3";
+    case UNORDERED:
+      return "fjor %l3";
+    case UNEQ:
+      return "fjogl %l3";
+    case UNGE:
+      return "fjolt %l3";
+    case UNGT:
+      return "fjole %l3";
+    case UNLE:
+      return "fjogt %l3";
+    case UNLT:
+      return "fjoge %l3";
+    case LTGT:
+      return "fjueq %l3";
+    default:
+      gcc_unreachable ();
+    }
+}
+
+/* Return an output template for a floating point scc
+   instruction with CODE.  */
+const char *
+m68k_output_scc_float (rtx_code code)
+{
+  switch (code)
+    {
+    case EQ:
+      return "fseq %0";
+    case NE:
+      return "fsne %0";
+    case GT:
+      return "fsgt %0";
+    case GTU:
+      return "fshi %0";
+    case LT:
+      return "fslt %0";
+    case GE:
+      return "fsge %0";
+    case LE:
+      return "fsle %0";
+    case ORDERED:
+      return "fsor %0";
+    case UNORDERED:
+      return "fsun %0";
+    case UNEQ:
+      return "fsueq %0";
+    case UNGE:
+      return "fsuge %0";
+    case UNGT:
+      return "fsugt %0";
+    case UNLE:
+      return "fsule %0";
+    case UNLT:
+      return "fsult %0";
+    case LTGT:
+      return "fsogl %0";
+    default:
+      gcc_unreachable ();
     }
 }
 
@@ -4932,6 +5423,7 @@ const char *
 output_andsi3 (rtx *operands)
 {
   int logval;
+  CC_STATUS_INIT;
   if (GET_CODE (operands[2]) == CONST_INT
       && (INTVAL (operands[2]) | 0xffff) == -1
       && (DATA_REG_P (operands[0])
@@ -4941,8 +5433,6 @@ output_andsi3 (rtx *operands)
       if (GET_CODE (operands[0]) != REG)
         operands[0] = adjust_address (operands[0], HImode, 2);
       operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff);
-      /* Do not delete a following tstl %0 insn; that would be incorrect.  */
-      CC_STATUS_INIT;
       if (operands[2] == const0_rtx)
         return "clr%.w %0";
       return "and%.w %2,%0";
@@ -4959,10 +5449,13 @@ output_andsi3 (rtx *operands)
 	  operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
 	  operands[1] = GEN_INT (logval % 8);
         }
-      /* This does not set condition codes in a standard way.  */
-      CC_STATUS_INIT;
       return "bclr %1,%0";
     }
+  /* Only a standard logical operation on the whole word sets the
+     condition codes in a way we can use.  */
+  if (!side_effects_p (operands[0]))
+    flags_operand1 = operands[0];
+  flags_valid = FLAGS_VALID_YES;
   return "and%.l %2,%0";
 }
 
@@ -4970,6 +5463,7 @@ const char *
 output_iorsi3 (rtx *operands)
 {
   register int logval;
+  CC_STATUS_INIT;
   if (GET_CODE (operands[2]) == CONST_INT
       && INTVAL (operands[2]) >> 16 == 0
       && (DATA_REG_P (operands[0])
@@ -4978,8 +5472,6 @@ output_iorsi3 (rtx *operands)
     {
       if (GET_CODE (operands[0]) != REG)
         operands[0] = adjust_address (operands[0], HImode, 2);
-      /* Do not delete a following tstl %0 insn; that would be incorrect.  */
-      CC_STATUS_INIT;
       if (INTVAL (operands[2]) == 0xffff)
 	return "mov%.w %2,%0";
       return "or%.w %2,%0";
@@ -4996,9 +5488,13 @@ output_iorsi3 (rtx *operands)
 	  operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
 	  operands[1] = GEN_INT (logval % 8);
 	}
-      CC_STATUS_INIT;
       return "bset %1,%0";
     }
+  /* Only a standard logical operation on the whole word sets the
+     condition codes in a way we can use.  */
+  if (!side_effects_p (operands[0]))
+    flags_operand1 = operands[0];
+  flags_valid = FLAGS_VALID_YES;
   return "or%.l %2,%0";
 }
 
@@ -5006,6 +5502,7 @@ const char *
 output_xorsi3 (rtx *operands)
 {
   register int logval;
+  CC_STATUS_INIT;
   if (GET_CODE (operands[2]) == CONST_INT
       && INTVAL (operands[2]) >> 16 == 0
       && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))
@@ -5013,8 +5510,6 @@ output_xorsi3 (rtx *operands)
     {
       if (! DATA_REG_P (operands[0]))
 	operands[0] = adjust_address (operands[0], HImode, 2);
-      /* Do not delete a following tstl %0 insn; that would be incorrect.  */
-      CC_STATUS_INIT;
       if (INTVAL (operands[2]) == 0xffff)
 	return "not%.w %0";
       return "eor%.w %2,%0";
@@ -5031,9 +5526,13 @@ output_xorsi3 (rtx *operands)
 	  operands[0] = adjust_address (operands[0], SImode, 3 - (logval / 8));
 	  operands[1] = GEN_INT (logval % 8);
 	}
-      CC_STATUS_INIT;
       return "bchg %1,%0";
     }
+  /* Only a standard logical operation on the whole word sets the
+     condition codes in a way we can use.  */
+  if (!side_effects_p (operands[0]))
+    flags_operand1 = operands[0];
+  flags_valid = FLAGS_VALID_YES;
   return "eor%.l %2,%0";
 }
 
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index fc65e524b13..39955b05f1d 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -670,36 +670,6 @@ __transfer_from_trampoline ()					\
 #define Pmode SImode
 #define FUNCTION_MODE QImode
 
-
-/* Tell final.c how to eliminate redundant test instructions.  */
-
-/* Here we define machine-dependent flags and fields in cc_status
-   (see `conditions.h').  */
-
-/* Set if the cc value is actually in the 68881, so a floating point
-   conditional branch must be output.  */
-#define CC_IN_68881 04000
-
-/* On the 68000, all the insns to store in an address register fail to
-   set the cc's.  However, in some cases these instructions can make it
-   possibly invalid to use the saved cc's.  In those cases we clear out
-   some or all of the saved cc's so they won't be used.  */
-#define NOTICE_UPDATE_CC(EXP,INSN) notice_update_cc (EXP, INSN)
-
-/* The shift instructions always clear the overflow bit.  */
-#define CC_OVERFLOW_UNUSABLE 01000
-
-/* The shift instructions use the carry bit in a way not compatible with
-   conditional branches.  conditions.h uses CC_NO_OVERFLOW for this purpose.
-   Rename it to something more understandable.  */
-#define CC_NO_CARRY CC_NO_OVERFLOW
-
-#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV)  \
-do { if (cc_prev_status.flags & CC_IN_68881)			\
-    return FLOAT;						\
-  if (cc_prev_status.flags & CC_NO_OVERFLOW)			\
-    return NO_OV;						\
-  return NORMAL; } while (0)
 
 /* Control the assembler format that we output.  */
 
@@ -900,6 +870,8 @@ do { if (cc_prev_status.flags & CC_IN_68881)			\
 
 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
 
+#define CC_STATUS_INIT m68k_init_cc ()
+
 #include "config/m68k/m68k-opts.h"
 
 enum fpu_type
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index e60978150d1..bb46e5880e2 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -250,6 +250,18 @@
 ;; Alternative is OK for ColdFire.
 (define_attr "ok_for_coldfire" "yes,no" (const_string "yes"))
 
+;; Instruction sets flags predictably to allow a following comparison to be
+;; elided.
+;; "no" means we should clear all flag state.  "yes" means the destination
+;; register is valid.  "noov" is similar but does not allow tests that rely
+;; on the overflow flag.  "unchanged" means the instruction does not set the
+;; flags (but we should still verify none of the remembered operands are
+;; clobbered).  "move" is a special case for which we remember both the
+;; destination and the source.  "set" is another special case where the
+;; instruction pattern already performs the update and no more work is
+;; required in postscan_insn.
+(define_attr "flags_valid" "no,yes,set,noov,move,unchanged" (const_string "no"))
+
 ;; Define 'enabled' attribute.
 (define_attr "enabled" ""
   (cond [(and (match_test "TARGET_COLDFIRE")
@@ -303,150 +315,129 @@
   DONE;
 })
 
-;; We don't want to allow a constant operand for test insns because
-;; (set (cc0) (const_int foo)) has no mode information.  Such insns will
-;; be folded while optimizing anyway.
-
-(define_insn "tstdi"
-  [(set (cc0)
-	(compare (match_operand:DI 0 "nonimmediate_operand" "am,d")
-		 (const_int 0)))
-   (clobber (match_scratch:SI 1 "=X,d"))
-   (clobber (match_scratch:DI 2 "=d,X"))]
+;; Compare instructions, combined with jumps or scc operations.
+
+(define_insn "beq0_di"
+  [(set (pc)
+    (if_then_else (eq (match_operand:DI 0 "general_operand" "d*a,o,<>")
+            (const_int 0))
+        (label_ref (match_operand 1 "" ",,"))
+        (pc)))
+   (clobber (match_scratch:SI 2 "=d,&d,d"))]
   ""
 {
-  if (which_alternative == 0)
-    {
-      rtx xoperands[2];
-
-      xoperands[0] = operands[2];
-      xoperands[1] = operands[0];
-      output_move_double (xoperands);
-      cc_status.flags |= CC_REVERSED; /*|*/
-      return "neg%.l %R2\;negx%.l %2";
-    }
-  if (find_reg_note (insn, REG_DEAD, operands[0]))
+  rtx_code code = m68k_find_flags_value (operands[0], const0_rtx, EQ);
+  if (code == EQ)
+    return "jeq %l1";
+  if (which_alternative == 2)
+    return "move%.l %0,%2\;or%.l %0,%2\;jeq %l1";
+  if (GET_CODE (operands[0]) == REG)
+    operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
+  else
+    operands[3] = adjust_address (operands[0], SImode, 4);
+  if (! ADDRESS_REG_P (operands[0]))
     {
-      cc_status.flags |= CC_REVERSED; /*|*/
-      return "neg%.l %R0\;negx%.l %0";
+      if (reg_overlap_mentioned_p (operands[2], operands[0]))
+	{
+	  if (reg_overlap_mentioned_p (operands[2], operands[3]))
+	    return "or%.l %0,%2\;jeq %l1";
+	  else
+	    return "or%.l %3,%2\;jeq %l1";
+	}
+      return "move%.l %0,%2\;or%.l %3,%2\;jeq %l1";
     }
+  operands[4] = gen_label_rtx();
+  if (TARGET_68020 || TARGET_COLDFIRE)
+    output_asm_insn ("tst%.l %0\;jne %l4\;tst%.l %3\;jeq %l1", operands);
   else
-    /*
-       'sub' clears %1, and also clears the X cc bit
-       'tst' sets the Z cc bit according to the low part of the DImode operand
-       'subx %1' (i.e. subx #0) acts as a (non-existent) tstx on the high part.
-    */
-    return "sub%.l %1,%1\;tst%.l %R0\;subx%.l %1,%0";
-})
-
-;; If you think that the 68020 does not support tstl a0,
-;; reread page B-167 of the 68020 manual more carefully.
-(define_insn "*tstsi_internal_68020_cf"
-  [(set (cc0)
-	(compare (match_operand:SI 0 "nonimmediate_operand" "rm")
-		 (const_int 0)))]
-  "TARGET_68020 || TARGET_COLDFIRE"
-  "tst%.l %0"
-  [(set_attr "type" "tst_l")])
-
-;; On an address reg, cmpw may replace cmpl.
-(define_insn "*tstsi_internal"
-  [(set (cc0)
-	(compare (match_operand:SI 0 "nonimmediate_operand" "dm,r")
-		 (const_int 0)))]
-  "!(TARGET_68020 || TARGET_COLDFIRE)"
-  "@
-   tst%.l %0
-   cmp%.w #0,%0"
-  [(set_attr "type" "tst_l,cmp")])
-
-;; This can't use an address register, because comparisons
-;; with address registers as second operand always test the whole word.
-(define_insn "*tsthi_internal"
-  [(set (cc0)
-	(compare (match_operand:HI 0 "nonimmediate_operand" "dm")
-		 (const_int 0)))]
-  ""
-  "tst%.w %0"
-  [(set_attr "type" "tst")])
-
-(define_insn "*tstqi_internal"
-  [(set (cc0)
-	(compare (match_operand:QI 0 "nonimmediate_operand" "dm")
-		 (const_int 0)))]
-  ""
-  "tst%.b %0"
-  [(set_attr "type" "tst")])
-
-(define_insn "tst<mode>_68881"
-  [(set (cc0)
-	(compare (match_operand:FP 0 "general_operand" "f<FP:dreg>m")
-		 (match_operand:FP 1 "const0_operand" "H")))]
-  "TARGET_68881"
-{
-  cc_status.flags = CC_IN_68881;
-  if (FP_REG_P (operands[0]))
-    return "ftst%.x %0";
-  return "ftst%.<FP:prec> %0";
-}
-  [(set_attr "type" "ftst")])
-
-(define_insn "tst<mode>_cf"
-  [(set (cc0)
-	(compare (match_operand:FP 0 "general_operand" "f<FP:dreg><Q>U")
-		 (match_operand:FP 1 "const0_operand" "H")))]
-  "TARGET_COLDFIRE_FPU"
-{
-  cc_status.flags = CC_IN_68881;
-  if (FP_REG_P (operands[0]))
-    return "ftst%.d %0";
-  return "ftst%.<FP:prec> %0";
-}
-  [(set_attr "type" "ftst")])
-
-
-;; compare instructions.
+    output_asm_insn ("cmp%.w #0,%0\;jne %l4\;cmp%.w #0,%3\;jeq %l1", operands);
+  (*targetm.asm_out.internal_label) (asm_out_file, "L",
+				CODE_LABEL_NUMBER (operands[4]));
+  return "";
+})
 
-(define_insn "*cmpdi_internal"
- [(set (cc0)
-       (compare (match_operand:DI 1 "nonimmediate_operand" "0,d")
-                (match_operand:DI 2 "general_operand" "d,0")))
-  (clobber (match_scratch:DI 0 "=d,d"))]
+(define_insn "bne0_di"
+  [(set (pc)
+    (if_then_else (ne (match_operand:DI 0 "general_operand" "d,o,*a")
+            (const_int 0))
+        (label_ref (match_operand 1 "" ",,"))
+        (pc)))
+   (clobber (match_scratch:SI 2 "=d,&d,X"))]
   ""
 {
-  if (rtx_equal_p (operands[0], operands[1]))
-    return "sub%.l %R2,%R0\;subx%.l %2,%0";
+  rtx_code code = m68k_find_flags_value (operands[0], const0_rtx, NE);
+  if (code == NE)
+    return "jne %l1";
+  if (GET_CODE (operands[0]) == REG)
+    operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
   else
+    operands[3] = adjust_address (operands[0], SImode, 4);
+  if (!ADDRESS_REG_P (operands[0]))
     {
-      cc_status.flags |= CC_REVERSED; /*|*/
-      return "sub%.l %R1,%R0\;subx%.l %1,%0";
+      if (reg_overlap_mentioned_p (operands[2], operands[0]))
+	{
+	  if (reg_overlap_mentioned_p (operands[2], operands[3]))
+	    return "or%.l %0,%2\;jne %l1";
+	  else
+	    return "or%.l %3,%2\;jne %l1";
+	}
+      return "move%.l %0,%2\;or%.l %3,%2\;jne %l1";
     }
+  if (TARGET_68020 || TARGET_COLDFIRE)
+    return "tst%.l %0\;jne %l1\;tst%.l %3\;jne %l1";
+  else
+    return "cmp%.w #0,%0\;jne %l1\;cmp%.w #0,%3\;jne %l1";
 })
 
-(define_insn "cmpdi"
- [(set (cc0)
-       (compare (match_operand:DI 0 "nonimmediate_operand")
-                (match_operand:DI 1 "general_operand")))
-  (clobber (match_scratch:DI 2))]
+(define_insn "cbranchdi4_insn"
+  [(set (pc)
+	(if_then_else (match_operator 1 "ordered_comparison_operator"
+		       [(match_operand:DI 2 "nonimmediate_operand" "0,d,am,d")
+			(match_operand:DI 3 "general_operand" "d,0,C0,C0")])
+		      (label_ref (match_operand 4 ""))
+		      (pc)))
+   (clobber (match_scratch:DI 0 "=d,d,d,X"))
+   (clobber (match_scratch:SI 5 "=X,X,X,d"))]
   ""
-  "")
-
+{
+  rtx_code code = GET_CODE (operands[1]);
+  code = m68k_output_compare_di (operands[2], operands[3], operands[5], operands[0], insn, code);
+  operands[3] = operands[4];
+  return m68k_output_branch_integer (code);
+})
 
 (define_expand "cbranchdi4"
-  [(set (pc)
-	(if_then_else (match_operator 0 "ordered_comparison_operator"
-		       [(match_operand:DI 1 "nonimmediate_operand")
-			(match_operand:DI 2 "general_operand")])
-		      (label_ref (match_operand 3 ""))
-		      (pc)))]
+  [(parallel
+    [(set (pc)
+	  (if_then_else (match_operator 0 "ordered_comparison_operator"
+			 [(match_operand:DI 1 "nonimmediate_operand")
+			  (match_operand:DI 2 "general_operand")])
+			(label_ref (match_operand 3 ""))
+			(pc)))
+     (clobber (match_scratch:DI 4 ""))
+     (clobber (match_scratch:SI 5 ""))])]
   ""
 {
-  if (operands[2] == const0_rtx)
-    emit_insn (gen_tstdi (operands[1]));
-  else
-    emit_insn (gen_cmpdi (operands[1], operands[2]));
-  operands[1] = cc0_rtx;
-  operands[2] = const0_rtx;
+  rtx_code code = GET_CODE (operands[0]);
+  if ((code == GE || code == LT) && operands[2] == const0_rtx)
+    {
+      rtx xop1 = operand_subword_force (operands[1], 0, DImode);
+      rtx xop2 = operand_subword_force (operands[2], 0, DImode);
+      /* gen_cbranchsi4 won't use anything from operands[0] other than the
+	 code.  */
+      emit_jump_insn (gen_cbranchsi4 (operands[0], xop1, xop2, operands[3]));
+      DONE;
+    }
+  if (code == EQ && operands[2] == const0_rtx)
+    {
+      emit_jump_insn (gen_beq0_di (operands[1], operands[3]));
+      DONE;
+    }
+  if (code == NE && operands[2] == const0_rtx)
+    {
+      emit_jump_insn (gen_bne0_di (operands[1], operands[3]));
+      DONE;
+    }
 })
 
 (define_expand "cstoredi4"
@@ -456,34 +447,38 @@
 	  (match_operand:DI 3 "general_operand")]))]
   ""
 {
+  rtx_code code = GET_CODE (operands[1]);
+  if ((code == GE || code == LT) && operands[3] == const0_rtx)
+    {
+      rtx xop2 = operand_subword_force (operands[2], 0, DImode);
+      rtx xop3 = operand_subword_force (operands[3], 0, DImode);
+      /* gen_cstoresi4 won't use anything from operands[1] other than the
+	 code.  */
+      emit_jump_insn (gen_cstoresi4 (operands[0], operands[1], xop2, xop3));
+      DONE;
+    }
 })
 
 (define_mode_iterator CMPMODE [QI HI SI])
 
 (define_expand "cbranch<mode>4"
-  [(set (cc0)
-	(compare (match_operand:CMPMODE 1 "nonimmediate_operand" "")
-		 (match_operand:CMPMODE 2 "m68k_comparison_operand" "")))
-   (set (pc)
+  [(set (pc)
 	(if_then_else (match_operator 0 "ordered_comparison_operator"
-                       [(cc0) (const_int 0)])
+		       [(match_operand:CMPMODE 1 "nonimmediate_operand" "")
+			(match_operand:CMPMODE 2 "m68k_comparison_operand" "")])
 		      (label_ref (match_operand 3 ""))
 		      (pc)))]
   ""
   "")
 
 (define_expand "cstore<mode>4"
-  [(set (cc0)
-	(compare (match_operand:CMPMODE 2 "nonimmediate_operand" "")
-		 (match_operand:CMPMODE 3 "m68k_comparison_operand" "")))
-   (set (match_operand:QI 0 "register_operand")
+  [(set (match_operand:QI 0 "register_operand")
 	(match_operator:QI 1 "ordered_comparison_operator"
-         [(cc0) (const_int 0)]))]
+         [(match_operand:CMPMODE 2 "nonimmediate_operand" "")
+	  (match_operand:CMPMODE 3 "m68k_comparison_operand" "")]))]
   ""
   "")
 
-;; A composite of the cmp, cmpa, cmpi & cmpm m68000 op codes.
-;;
 ;; In theory we ought to be able to use some 'S' constraints and
 ;; operand predicates that allow PC-rel addressing modes in the
 ;; comparison patterns and expanders below.   But we would have to be
@@ -491,86 +486,239 @@
 ;; both operands and determining whether or not we emit the operands in
 ;; order or reversed is not trivial to do just based on the constraints
 ;; and operand predicates.  So to be safe, just don't allow the PC-rel
-;; versions in the various comparison expanders, patterns, for comparisons.
-(define_insn ""
-  [(set (cc0)
-        (compare (match_operand:SI 0 "nonimmediate_operand" "rKT,rKs,mr,ma,>")
-                 (match_operand:SI 1 "general_operand" "mr,ma,KTr,Ksr,>")))]
+
+(define_mode_attr scc0_constraints [(QI "=d,d,d") (HI "=d,d,d,d,d") (SI "=d,d,d,d,d,d")])
+(define_mode_attr cmp1_constraints [(QI "dn,dm,>") (HI "rnm,d,n,m,>") (SI "r,rKT,rKs,mr,ma,>")])
+(define_mode_attr cmp2_constraints [(QI "dm,nd,>") (HI "d,rnm,m,n,>") (SI "mrC0,mr,ma,KTrC0,Ksr,>")])
+
+;; Note that operand 0 of an SCC insn is supported in the hardware as
+;; memory, but we cannot allow it to be in memory in case the address
+;; needs to be reloaded.
+
+(define_mode_attr scc0_cf_constraints [(QI "=d") (HI "=d") (SI "=d,d,d")])
+(define_mode_attr cmp1_cf_constraints [(QI "dm") (HI "dm") (SI "mrKs,r,rm")])
+(define_mode_attr cmp2_cf_constraints [(QI "C0") (HI "C0") (SI "r,mrKs,C0")])
+(define_mode_attr cmp2_cf_predicate [(QI "const0_operand") (HI "const0_operand") (SI "general_operand")])
+
+(define_insn "cbranch<mode>4_insn"
+  [(set (pc)
+	(if_then_else (match_operator 0 "ordered_comparison_operator"
+		       [(match_operand:CMPMODE 1 "nonimmediate_operand" "<cmp1_constraints>")
+			(match_operand:CMPMODE 2 "general_operand" "<cmp2_constraints>")])
+		      (label_ref (match_operand 3 ""))
+		      (pc)))]
   "!TARGET_COLDFIRE"
 {
-  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
-    return "cmpm%.l %1,%0";
-  if (REG_P (operands[1])
-      || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
-    {
-      cc_status.flags |= CC_REVERSED; /*|*/
-      return "cmp%.l %d0,%d1";
-    }
-  if (ADDRESS_REG_P (operands[0])
-      && GET_CODE (operands[1]) == CONST_INT
-      && INTVAL (operands[1]) < 0x8000
-      && INTVAL (operands[1]) >= -0x8000)
-    return "cmp%.w %1,%0";
-  return "cmp%.l %d1,%d0";
-})
-
-(define_insn "*cmpsi_cf"
-  [(set (cc0)
-	(compare (match_operand:SI 0 "nonimmediate_operand" "mrKs,r")
-		 (match_operand:SI 1 "general_operand" "r,mrKs")))]
+  rtx_code code = GET_CODE (operands[0]);
+  code = m68k_output_compare_<mode> (operands[1], operands[2], code);
+  return m68k_output_branch_integer (code);
+}
+  [(set_attr "flags_valid" "set")])
+
+(define_insn "cbranch<mode>4_insn_rev"
+  [(set (pc)
+	(if_then_else (match_operator 0 "ordered_comparison_operator"
+		       [(match_operand:CMPMODE 1 "nonimmediate_operand" "<cmp1_constraints>")
+			(match_operand:CMPMODE 2 "general_operand" "<cmp2_constraints>")])
+		      (pc)
+		      (label_ref (match_operand 3 ""))))]
+  "!TARGET_COLDFIRE"
+{
+  rtx_code code = GET_CODE (operands[0]);
+  code = m68k_output_compare_<mode> (operands[1], operands[2], code);
+  return m68k_output_branch_integer_rev (code);
+}
+  [(set_attr "flags_valid" "set")])
+
+(define_insn "cbranch<mode>4_insn_cf"
+  [(set (pc)
+	(if_then_else (match_operator 0 "ordered_comparison_operator"
+		       [(match_operand:CMPMODE 1 "nonimmediate_operand" "<cmp1_cf_constraints>")
+			(match_operand:CMPMODE 2 "<cmp2_cf_predicate>" "<cmp2_cf_constraints>")])
+		      (label_ref (match_operand 3 ""))
+		      (pc)))]
   "TARGET_COLDFIRE"
 {
-  if (REG_P (operands[1])
-      || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
-    {
-      cc_status.flags |= CC_REVERSED; /*|*/
-      return "cmp%.l %d0,%d1";
-    }
-  return "cmp%.l %d1,%d0";
+  rtx_code code = GET_CODE (operands[0]);
+  code = m68k_output_compare_<mode> (operands[1], operands[2], code);
+  return m68k_output_branch_integer (code);
 }
-  [(set_attr "type" "cmp_l")])
+  [(set_attr "flags_valid" "set")])
 
-(define_insn ""
-  [(set (cc0)
-        (compare (match_operand:HI 0 "nonimmediate_operand" "rnm,d,n,m,>")
-                 (match_operand:HI 1 "general_operand" "d,rnm,m,n,>")))]
+(define_insn "cbranch<mode>4_insn_cf_rev"
+  [(set (pc)
+	(if_then_else (match_operator 0 "ordered_comparison_operator"
+		       [(match_operand:CMPMODE 1 "nonimmediate_operand" "<cmp1_cf_constraints>")
+			(match_operand:CMPMODE 2 "<cmp2_cf_predicate>" "<cmp2_cf_constraints>")])
+		      (pc)
+		      (label_ref (match_operand 3 ""))))]
+  "TARGET_COLDFIRE"
+{
+  rtx_code code = GET_CODE (operands[0]);
+  code = m68k_output_compare_<mode> (operands[1], operands[2], code);
+  return m68k_output_branch_integer_rev (code);
+}
+  [(set_attr "flags_valid" "set")])
+
+(define_insn "cstore<mode>4_insn"
+  [(set (match_operand:QI 0 "register_operand" "<scc0_constraints>")
+	(match_operator:QI 1 "ordered_comparison_operator"
+	 [(match_operand:CMPMODE 2 "nonimmediate_operand" "<cmp1_constraints>")
+	  (match_operand:CMPMODE 3 "general_operand" "<cmp2_constraints>")]))]
   "!TARGET_COLDFIRE"
 {
-  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
-    return "cmpm%.w %1,%0";
-  if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1]))
-      || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
-    {
-      cc_status.flags |= CC_REVERSED; /*|*/
-      return "cmp%.w %d0,%d1";
-    }
-  return "cmp%.w %d1,%d0";
+  rtx_code code = GET_CODE (operands[1]);
+  code = m68k_output_compare_<mode> (operands[2], operands[3], code);
+  return m68k_output_scc (code);
+}
+  [(set_attr "flags_valid" "set")])
+
+(define_insn "cstore<mode>4_insn_cf"
+  [(set (match_operand:QI 0 "register_operand" "<scc0_cf_constraints>")
+	(match_operator:QI 1 "ordered_comparison_operator"
+	 [(match_operand:CMPMODE 2 "nonimmediate_operand" "<cmp1_cf_constraints>")
+	  (match_operand:CMPMODE 3 "<cmp2_cf_predicate>" "<cmp2_cf_constraints>")]))]
+  "TARGET_COLDFIRE"
+{
+  rtx_code code = GET_CODE (operands[1]);
+  code = m68k_output_compare_<mode> (operands[2], operands[3], code);
+  return m68k_output_scc (code);
+}
+  [(set_attr "flags_valid" "set")])
+
+;; ColdFire/5200 only allows "<Q>" type addresses when the bit position is
+;; specified as a constant, so we must disable all patterns that may extract
+;; from a MEM at a constant bit position if we can't use this as a constraint.
+
+(define_insn "cbranchsi4_btst_mem_insn"
+  [(set (pc)
+	(if_then_else (match_operator 0 "equality_comparison_operator"
+		       [(zero_extract:SI (match_operand:QI 1 "memory_src_operand" "oS,o")
+					 (const_int 1)
+					 (minus:SI (const_int 7)
+						   (match_operand:SI 2 "general_operand" "di,d")))
+			(const_int 0)])
+		      (label_ref (match_operand 3 ""))
+		      (pc)))]
+  ""
+{
+  rtx_code code = GET_CODE (operands[0]);
+  code = m68k_output_btst (operands[2], operands[1], code, 7);
+  return m68k_output_branch_integer (code);
+}
+  [(set_attr "ok_for_coldfire" "no,yes")])
+
+(define_insn "cbranchsi4_btst_reg_insn"
+  [(set (pc)
+	(if_then_else (match_operator 0 "equality_comparison_operator"
+		       [(zero_extract:SI (match_operand:SI 1 "register_operand" "d")
+					 (const_int 1)
+					 (minus:SI (const_int 31)
+						   (match_operand:SI 2 "general_operand" "di")))
+			(const_int 0)])
+		      (label_ref (match_operand 3 ""))
+		      (pc)))]
+  "!(CONST_INT_P (operands[1]) && !IN_RANGE (INTVAL (operands[1]), 0, 31))"
+{
+  rtx_code code = GET_CODE (operands[0]);
+  code = m68k_output_btst (operands[2], operands[1], code, 31);
+  return m68k_output_branch_integer (code);
 })
 
-(define_insn ""
-  [(set (cc0)
-        (compare (match_operand:QI 0 "nonimmediate_operand" "dn,dm,>")
-                 (match_operand:QI 1 "general_operand" "dm,nd,>")))]
-  "!TARGET_COLDFIRE"
+;; Nonoffsettable mem refs are ok in this one pattern
+;; since we don't try to adjust them.
+(define_insn "cbranchsi4_btst_mem_insn_1"
+  [(set (pc)
+	(if_then_else (match_operator 0 "equality_comparison_operator"
+		       [(zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
+					 (const_int 1)
+					 (match_operand:SI 2 "const_int_operand" "n"))
+			(const_int 0)])
+		      (label_ref (match_operand 3 ""))
+		      (pc)))]
+  "!TARGET_COLDFIRE && (unsigned) INTVAL (operands[2]) < 8"
+{
+  rtx_code code = GET_CODE (operands[0]);
+  operands[2] = GEN_INT (7 - INTVAL (operands[2]));
+  code = m68k_output_btst (operands[2], operands[1], code, 7);
+  return m68k_output_branch_integer (code);
+})
+
+(define_insn "cbranchsi4_btst_reg_insn_1"
+  [(set (pc)
+	(if_then_else (match_operator 0 "equality_comparison_operator"
+		       [(zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "do,dQ")
+					 (const_int 1)
+					 (match_operand:SI 2 "const_int_operand" "n,n"))
+			(const_int 0)])
+		      (label_ref (match_operand 3 ""))
+		      (pc)))]
+  "!(REG_P (operands[1]) && !IN_RANGE (INTVAL (operands[2]), 0, 31))"
 {
-  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
-    return "cmpm%.b %1,%0";
-  if (REG_P (operands[1])
-      || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))
+  rtx_code code = GET_CODE (operands[0]);
+  if (GET_CODE (operands[1]) == MEM)
     {
-      cc_status.flags |= CC_REVERSED; /*|*/
-      return "cmp%.b %d0,%d1";
+      operands[1] = adjust_address (operands[1], QImode,
+				    INTVAL (operands[2]) / 8);
+      operands[2] = GEN_INT (7 - INTVAL (operands[2]) % 8);
+      code = m68k_output_btst (operands[2], operands[1], code, 7);
     }
-  return "cmp%.b %d1,%d0";
+  else
+    {
+      operands[2] = GEN_INT (31 - INTVAL (operands[2]));
+      code = m68k_output_btst (operands[2], operands[1], code, 31);
+    }
+  return m68k_output_branch_integer (code);
+}
+  [(set_attr "ok_for_coldfire" "no,yes")])
+
+(define_mode_iterator BTST [QI SI])
+(define_mode_attr btst_predicate [(QI "memory_operand") (SI "register_operand")])
+(define_mode_attr btst_constraint [(QI "o") (SI "d")])
+(define_mode_attr btst_range [(QI "7") (SI "31")])
+
+;; Special patterns for optimizing bit-field instructions.
+(define_insn "cbranch_bftst<mode>_insn"
+  [(set (pc)
+	(if_then_else (match_operator 0 "ordered_comparison_operator"
+		       [(zero_extract:SI (match_operand:BTST 1 "<btst_predicate>" "<btst_constraint>")
+					 (match_operand:SI 2 "const_int_operand" "n")
+					 (match_operand:SI 3 "general_operand" "dn"))
+			(const_int 0)])
+		      (label_ref (match_operand 4 ""))
+		      (pc)))]
+  "TARGET_68020 && TARGET_BITFIELD
+   && (!REG_P (operands[1]) || !CONST_INT_P (operands[3])
+       || IN_RANGE (INTVAL (operands[3]), 0, 31))"
+{
+  rtx_code code = GET_CODE (operands[0]);
+  code = m68k_output_bftst (operands[1], operands[2], operands[3], code);
+  operands[3] = operands[4];
+  return m68k_output_branch_integer (code);
 })
 
+(define_insn "cstore_bftst<mode>_insn"
+  [(set (match_operand:QI 0 "register_operand")
+	(match_operator:QI 1 "ordered_comparison_operator"
+	 [(zero_extract:SI (match_operand:BTST 2 "<btst_predicate>" "<btst_constraint>")
+			   (match_operand:SI 3 "const_int_operand" "n")
+			   (match_operand:SI 4 "general_operand" "dn"))
+	  (const_int 0)]))]
+  "TARGET_68020 && TARGET_BITFIELD
+   && (!REG_P (operands[2]) || !CONST_INT_P (operands[4])
+       || IN_RANGE (INTVAL (operands[4]), 0, 31))"
+{
+  rtx_code code = GET_CODE (operands[1]);
+  code = m68k_output_bftst (operands[2], operands[3], operands[4], code);
+  return m68k_output_scc (code);
+})
+
+;; Floating point comparison patterns
 (define_expand "cbranch<mode>4"
-  [(set (cc0)
-	(compare (match_operand:FP 1 "register_operand" "")
-		 (match_operand:FP 2 "fp_src_operand" "")))
-   (set (pc)
+  [(set (pc)
 	(if_then_else (match_operator 0 "comparison_operator"
-                       [(cc0) (const_int 0)])
+		       [(match_operand:FP 1 "register_operand" "")
+			(match_operand:FP 2 "fp_src_operand" "")])
 		      (label_ref (match_operand 3 ""))
 		      (pc)))]
   "TARGET_HARD_FLOAT"
@@ -579,186 +727,117 @@
 ;; ??? This presumably tries to allow tests against zero for coldfire, but
 ;; it would have to test operands[3] and use CONST0_RTX (mode).
 (define_expand "cstore<mode>4"
-  [(set (cc0)
-	(compare (match_operand:FP 2 "register_operand" "")
-		 (match_operand:FP 3 "fp_src_operand" "")))
-   (set (match_operand:QI 0 "register_operand")
+  [(set (match_operand:QI 0 "register_operand")
 	(match_operator:QI 1 "m68k_cstore_comparison_operator"
-         [(cc0) (const_int 0)]))]
+         [(match_operand:FP 2 "register_operand" "")
+	  (match_operand:FP 3 "fp_src_operand" "")]))]
   "TARGET_HARD_FLOAT && !(TUNE_68060 || TARGET_COLDFIRE_FPU)"
   "if (TARGET_COLDFIRE && operands[2] != const0_rtx)
      FAIL;")
 
-(define_insn "*cmp<mode>_68881"
-  [(set (cc0)
-	(compare (match_operand:FP 0 "fp_src_operand" "f,f,<FP:dreg>m")
-		 (match_operand:FP 1 "fp_src_operand" "f,<FP:dreg>mF,f")))]
+(define_insn "cbranch<mode>4_insn_68881"
+  [(set (pc)
+	(if_then_else (match_operator 0 "comparison_operator"
+		       [(match_operand:FP 1 "fp_src_operand" "f,f,<FP:dreg>mF,f<FP:dreg>m")
+			(match_operand:FP 2 "fp_src_operand" "f,<FP:dreg>mF,f,H")])
+		      (label_ref (match_operand 3 ""))
+		      (pc)))]
   "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"
-  [(set (cc0)
-	(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.
-
-;; ColdFire/5200 only allows "<Q>" type addresses when the bit position is
-;; specified as a constant, so we must disable all patterns that may extract
-;; from a MEM at a constant bit position if we can't use this as a constraint.
-
-(define_insn ""
-  [(set
-    (cc0)
-    (compare (zero_extract:SI (match_operand:QI 0 "memory_src_operand" "oS")
-			       (const_int 1)
-			       (minus:SI (const_int 7)
-				         (match_operand:SI 1 "general_operand" "di")))
-	     (const_int 0)))]
-  "!TARGET_COLDFIRE"
+   && (register_operand (operands[1], <MODE>mode)
+       || register_operand (operands[2], <MODE>mode)
+       || const0_operand (operands[2], <MODE>mode))"
 {
-  return output_btst (operands, operands[1], operands[0], insn, 7);
-})
+  rtx_code code = GET_CODE (operands[0]);
+  code = m68k_output_compare_fp (operands[1], operands[2], code);
+  return m68k_output_branch_float (code);
+}
+  [(set_attr "flags_valid" "set")])
 
-;; This is the same as the above pattern except for the constraints.  The 'i'
-;; has been deleted.
+(define_insn "cbranch<mode>4_insn_cf"
+  [(set (pc)
+	(if_then_else (match_operator 0 "comparison_operator"
+		       [(match_operand:FP 1 "fp_src_operand" "f,f,<FP:dreg><Q>U,f<FP:dreg><Q>U")
+			(match_operand:FP 2 "fp_src_operand" "f,<FP:dreg><Q>U,f,H")])
+		      (label_ref (match_operand 3 ""))
+		      (pc)))]
+  "TARGET_COLDFIRE_FPU
+   && (register_operand (operands[1], <MODE>mode)
+       || register_operand (operands[2], <MODE>mode)
+       || const0_operand (operands[2], <MODE>mode))"
+{
+  rtx_code code = GET_CODE (operands[0]);
+  code = m68k_output_compare_fp (operands[1], operands[2], code);
+  return m68k_output_branch_float (code);
+}
+  [(set_attr "flags_valid" "set")])
 
-(define_insn ""
-  [(set
-    (cc0)
-    (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
-			       (const_int 1)
-			       (minus:SI (const_int 7)
-				         (match_operand:SI 1 "general_operand" "d")))
-	     (const_int 0)))]
-  "TARGET_COLDFIRE"
+(define_insn "cbranch<mode>4_insn_rev_68881"
+  [(set (pc)
+	(if_then_else (match_operator 0 "comparison_operator"
+		       [(match_operand:FP 1 "fp_src_operand" "f,f,<FP:dreg>mF,f<FP:dreg>m")
+			(match_operand:FP 2 "fp_src_operand" "f,<FP:dreg>mF,f,H")])
+		      (pc)
+		      (label_ref (match_operand 3 ""))))]
+  "TARGET_68881
+   && (register_operand (operands[1], <MODE>mode)
+       || register_operand (operands[2], <MODE>mode)
+       || const0_operand (operands[2], <MODE>mode))"
 {
-  return output_btst (operands, operands[1], operands[0], insn, 7);
-})
+  rtx_code code = GET_CODE (operands[0]);
+  code = m68k_output_compare_fp (operands[1], operands[2], code);
+  return m68k_output_branch_float_rev (code);
+}
+  [(set_attr "flags_valid" "set")])
 
-(define_insn ""
-  [(set
-    (cc0)
-    (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
-			       (const_int 1)
-			       (minus:SI (const_int 31)
-				         (match_operand:SI 1 "general_operand" "di")))
-	     (const_int 0)))]
-  "!(CONST_INT_P (operands[1]) && !IN_RANGE (INTVAL (operands[1]), 0, 31))"
+(define_insn "cbranch<mode>4_insn_rev_cf"
+  [(set (pc)
+	(if_then_else (match_operator 0 "comparison_operator"
+		       [(match_operand:FP 1 "fp_src_operand" "f,f,<FP:dreg><Q>U,f<FP:dreg><Q>U")
+			(match_operand:FP 2 "fp_src_operand" "f,<FP:dreg><Q>U,f,H")])
+		      (pc)
+		      (label_ref (match_operand 3 ""))))]
+  "TARGET_COLDFIRE_FPU
+   && (register_operand (operands[1], <MODE>mode)
+       || register_operand (operands[2], <MODE>mode)
+       || const0_operand (operands[2], <MODE>mode))"
 {
-  return output_btst (operands, operands[1], operands[0], insn, 31);
-})
+  rtx_code code = GET_CODE (operands[0]);
+  code = m68k_output_compare_fp (operands[1], operands[2], code);
+  return m68k_output_branch_float_rev (code);
+}
+  [(set_attr "flags_valid" "set")])
 
-;; The following two patterns are like the previous two
-;; except that they use the fact that bit-number operands
-;; are automatically masked to 3 or 5 bits.
+(define_insn "cstore<mode>4_insn_68881"
+  [(set (match_operand:QI 0 "register_operand" "=d,d,d,d")
+	(match_operator:QI 1 "m68k_cstore_comparison_operator"
+	 [(match_operand:FP 2 "fp_src_operand" "f,f,<FP:dreg>mF,f<FP:dreg>m")
+	  (match_operand:FP 3 "fp_src_operand" "f,<FP:dreg>mF,f,H")]))]
+  "TARGET_HARD_FLOAT && !(TUNE_68060 || TARGET_COLDFIRE_FPU)
+   && (register_operand (operands[2], <MODE>mode)
+       || register_operand (operands[3], <MODE>mode)
+       || const0_operand (operands[3], <MODE>mode))"
+{
+  rtx_code code = GET_CODE (operands[1]);
+  code = m68k_output_compare_fp (operands[2], operands[3], code);
+  return m68k_output_scc_float (code);
+}
+  [(set_attr "flags_valid" "set")])
 
-(define_insn ""
-  [(set
-    (cc0)
-    (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
-			       (const_int 1)
-			       (minus:SI (const_int 7)
-				         (and:SI
-				          (match_operand:SI 1 "register_operand" "d")
-				          (const_int 7))))
-	     (const_int 0)))]
-  ""
+;; Test against zero only for coldfire floating point cstore.
+(define_insn "cstore<mode>4_insn_cf"
+  [(set (match_operand:QI 0 "register_operand" "=d")
+	(match_operator:QI 1 "m68k_cstore_comparison_operator"
+	 [(match_operand:FP 2 "fp_src_operand" "f<FP:dreg><Q>U")
+	  (match_operand:FP 3 "const0_operand" "H")]))]
+  "TARGET_HARD_FLOAT && TARGET_COLDFIRE_FPU"
 {
-  return output_btst (operands, operands[1], operands[0], insn, 7);
-})
+  rtx_code code = GET_CODE (operands[1]);
+  code = m68k_output_compare_fp (operands[2], operands[3], code);
+  return m68k_output_scc_float (code);
+}
+  [(set_attr "flags_valid" "set")])
 
-(define_insn ""
-  [(set
-    (cc0)
-    (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
-			       (const_int 1)
-			       (minus:SI (const_int 31)
-				         (and:SI
-				          (match_operand:SI 1 "register_operand" "d")
-				          (const_int 31))))
-	     (const_int 0)))]
-  ""
-{
-  return output_btst (operands, operands[1], operands[0], insn, 31);
-})
-
-;; Nonoffsettable mem refs are ok in this one pattern
-;; since we don't try to adjust them.
-(define_insn ""
-  [(set
-    (cc0)
-    (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
-			      (const_int 1)
-			      (match_operand:SI 1 "const_int_operand" "n"))
-	     (const_int 0)))]
-  "(unsigned) INTVAL (operands[1]) < 8 && !TARGET_COLDFIRE"
-{
-  operands[1] = GEN_INT (7 - INTVAL (operands[1]));
-  return output_btst (operands, operands[1], operands[0], insn, 7);
-})
-
-(define_insn ""
-  [(set
-    (cc0)
-    (compare (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "do")
-			      (const_int 1)
-			      (match_operand:SI 1 "const_int_operand" "n"))
-	     (const_int 0)))]
-  "!TARGET_COLDFIRE
-   && !(REG_P (operands[0]) && !IN_RANGE (INTVAL (operands[1]), 0, 31))"
-{
-  if (GET_CODE (operands[0]) == MEM)
-    {
-      operands[0] = adjust_address (operands[0], QImode,
-				    INTVAL (operands[1]) / 8);
-      operands[1] = GEN_INT (7 - INTVAL (operands[1]) % 8);
-      return output_btst (operands, operands[1], operands[0], insn, 7);
-    }
-  operands[1] = GEN_INT (31 - INTVAL (operands[1]));
-  return output_btst (operands, operands[1], operands[0], insn, 31);
-})
-
-;; This is the same as the above pattern except for the constraints.
-;; The 'o' has been replaced with 'Q'.
-
-(define_insn ""
-  [(set
-    (cc0)
-    (compare (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "dQ")
-			      (const_int 1)
-			      (match_operand:SI 1 "const_int_operand" "n"))
-	     (const_int 0)))]
-  "TARGET_COLDFIRE
-   && !(REG_P (operands[0]) && !IN_RANGE (INTVAL (operands[1]), 0, 31))"
-{
-  if (GET_CODE (operands[0]) == MEM)
-    {
-      operands[0] = adjust_address (operands[0], QImode,
-				    INTVAL (operands[1]) / 8);
-      operands[1] = GEN_INT (7 - INTVAL (operands[1]) % 8);
-      return output_btst (operands, operands[1], operands[0], insn, 7);
-    }
-  operands[1] = GEN_INT (31 - INTVAL (operands[1]));
-  return output_btst (operands, operands[1], operands[0], insn, 31);
-})
-
-
-;; move instructions
+;; move instructions
 
 ;; A special case in which it is not desirable
 ;; to reload the constant into a data register.
@@ -916,7 +995,8 @@
   "!TARGET_COLDFIRE && reload_completed"
 {
   return output_move_simode (operands);
-})
+}
+  [(set_attr "flags_valid" "set")])
 
 ;; Before reload is completed the register constraints
 ;; force integer constants in range for a moveq to be reloaded
@@ -928,7 +1008,8 @@
   "!TARGET_COLDFIRE"
 {
   return output_move_simode (operands);
-})
+}
+  [(set_attr "flags_valid" "set")])
 
 ;; ColdFire move instructions can have at most one operand of mode >= 6.
 (define_insn "*movsi_cf"
@@ -1004,13 +1085,21 @@
   [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
         (match_operand:HI 1 "general_src_operand" "gS"))]
   "!TARGET_COLDFIRE"
-  "* return output_move_himode (operands);")
+  "* return output_move_himode (operands);"
+  [(set (attr "flags_valid")
+	(if_then_else (match_operand 0 "address_reg_operand")
+		      (const_string "unchanged")
+		      (const_string "move")))])
 
 (define_insn ""
   [(set (match_operand:HI 0 "nonimmediate_operand" "=r<Q>,g,U")
 	(match_operand:HI 1 "general_operand" "g,r<Q>,U"))]
   "TARGET_COLDFIRE"
-  "* return output_move_himode (operands);")
+  "* return output_move_himode (operands);"
+  [(set (attr "flags_valid")
+	(if_then_else (match_operand 0 "address_reg_operand")
+		      (const_string "unchanged")
+		      (const_string "move")))])
 
 (define_expand "movstricthi"
   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
@@ -1022,13 +1111,15 @@
   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
 	(match_operand:HI 1 "general_src_operand" "rmSn"))]
   "!TARGET_COLDFIRE"
-  "* return output_move_stricthi (operands);")
+  "* return output_move_stricthi (operands);"
+  [(set_attr "flags_valid" "move")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+d,m"))
 	(match_operand:HI 1 "general_src_operand" "rmn,r"))]
   "TARGET_COLDFIRE"
-  "* return output_move_stricthi (operands);")
+  "* return output_move_stricthi (operands);"
+  [(set_attr "flags_valid" "move")])
 
 (define_expand "movqi"
   [(set (match_operand:QI 0 "nonimmediate_operand" "")
@@ -1040,13 +1131,15 @@
   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,*a,m")
 	(match_operand:QI 1 "general_src_operand" "dmSi*a,di*a,dmSi"))]
   "!TARGET_COLDFIRE"
-  "* return output_move_qimode (operands);")
+  "* return output_move_qimode (operands);"
+  [(set_attr "flags_valid" "set")])
 
 (define_insn ""
   [(set (match_operand:QI 0 "nonimmediate_operand" "=d<Q>,dm,U,d*a")
 	(match_operand:QI 1 "general_src_operand" "dmi,d<Q>,U,di*a"))]
   "TARGET_COLDFIRE"
-  "* return output_move_qimode (operands);")
+  "* return output_move_qimode (operands);"
+  [(set_attr "flags_valid" "set")])
 
 (define_expand "movstrictqi"
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
@@ -1058,7 +1151,8 @@
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
 	(match_operand:QI 1 "general_src_operand" "dmSn"))]
   "!TARGET_COLDFIRE"
-  "* return output_move_strictqi (operands);")
+  "* return output_move_strictqi (operands);"
+  [(set_attr "flags_valid" "move")])
 
 (define_insn "*movstrictqi_cf"
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+d, Ac, d,m"))
@@ -1152,7 +1246,8 @@
       return "clr%.l %0";
     }
   return "move%.l %1,%0";
-})
+}
+  [(set_attr "flags_valid" "move")])
 
 (define_insn "movsf_cf_soft"
   [(set (match_operand:SF 0 "nonimmediate_operand" "=r<Q>,g,U")
@@ -1292,7 +1387,8 @@
         return "fmove%.d %f1,%0";
     }
   return output_move_double (operands);
-})
+}
+  [(set_attr "flags_valid" "move")])
 
 (define_insn_and_split "movdf_cf_soft"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,g")
@@ -1413,7 +1509,8 @@
       return "fmove%.x %f1,%0";
     }
   return output_move_double (operands);
-})
+}
+  [(set_attr "flags_valid" "move")])
 
 (define_insn ""
   [(set (match_operand:XF 0 "nonimmediate_operand" "=rm,rf,&rof<>")
@@ -1534,16 +1631,16 @@
   "!TARGET_COLDFIRE"
 {
   if (GET_CODE (operands[0]) == REG)
-    {
-      /* Must clear condition codes, since the move.l bases them on
-	 the entire 32 bits, not just the desired 8 bits.  */
-      CC_STATUS_INIT;
-      return "move%.l %1,%0";
-    }
+    return "move%.l %1,%0";
+
   if (GET_CODE (operands[1]) == MEM)
     operands[1] = adjust_address (operands[1], QImode, 3);
   return "move%.b %1,%0";
-})
+}
+  [(set (attr "flags_valid")
+	(if_then_else (match_operand 0 "register_operand")
+		      (const_string "no")
+		      (const_string "yes")))])
 
 (define_insn "trunchiqi2"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d")
@@ -1554,23 +1651,19 @@
   if (GET_CODE (operands[0]) == REG
       && (GET_CODE (operands[1]) == MEM
 	  || GET_CODE (operands[1]) == CONST_INT))
-    {
-      /* Must clear condition codes, since the move.w bases them on
-	 the entire 16 bits, not just the desired 8 bits.  */
-      CC_STATUS_INIT;
-      return "move%.w %1,%0";
-    }
+    return "move%.w %1,%0";
+
   if (GET_CODE (operands[0]) == REG)
-    {
-      /* Must clear condition codes, since the move.l bases them on
-	 the entire 32 bits, not just the desired 8 bits.  */
-      CC_STATUS_INIT;
-      return "move%.l %1,%0";
-    }
+    return "move%.l %1,%0";
+
   if (GET_CODE (operands[1]) == MEM)
     operands[1] = adjust_address (operands[1], QImode, 1);
   return "move%.b %1,%0";
-})
+}
+  [(set (attr "flags_valid")
+	(if_then_else (match_operand 0 "register_operand")
+		      (const_string "no")
+		      (const_string "yes")))])
 
 (define_insn "truncsihi2"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm,d")
@@ -1579,16 +1672,16 @@
   "!TARGET_COLDFIRE"
 {
   if (GET_CODE (operands[0]) == REG)
-    {
-      /* Must clear condition codes, since the move.l bases them on
-	 the entire 32 bits, not just the desired 8 bits.  */
-      CC_STATUS_INIT;
-      return "move%.l %1,%0";
-    }
+    return "move%.l %1,%0";
+
   if (GET_CODE (operands[1]) == MEM)
     operands[1] = adjust_address (operands[1], QImode, 2);
   return "move%.w %1,%0";
-})
+}
+  [(set (attr "flags_valid")
+	(if_then_else (match_operand 0 "register_operand")
+		      (const_string "no")
+		      (const_string "yes")))])
 
 ;; zero extension instructions
 
@@ -1756,7 +1849,6 @@
         (sign_extend:DI (match_operand:QI 1 "general_src_operand" "rmS")))]
   ""
 {
-  CC_STATUS_INIT;
   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
   if (ISA_HAS_MVS_MVZ)
     return "mvs%.b %1,%2\;smi %0\;extb%.l %0";
@@ -1782,7 +1874,6 @@
 	 (match_operand:HI 1 "general_src_operand" "rmS")))]
   ""
 {
-  CC_STATUS_INIT;
   operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
   if (ISA_HAS_MVS_MVZ)
     return "mvs%.w %1,%2\;smi %0\;extb%.l %0";
@@ -1799,8 +1890,6 @@
    (clobber (match_scratch:SI 2 "=X,d,d,d"))]
   ""
 {
-  CC_STATUS_INIT;
-
   if (which_alternative == 0)
     /* Handle alternative 0.  */
     {
@@ -1835,7 +1924,6 @@
             (match_operand:SI 2 "general_operand" "rmn"))))]
   ""
 {
-  CC_STATUS_INIT;
   operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
   if (GET_CODE (operands[1]) == CONST_INT
   && (unsigned) INTVAL (operands[1]) > 8)
@@ -1927,10 +2015,7 @@
     {
       if (REGNO (operands[0]) == REGNO (operands[1]))
 	{
-	  /* Extending float to double in an fp-reg is a no-op.
-	     NOTICE_UPDATE_CC has already assumed that the
-	     cc will be set.  So cancel what it did.  */
-	  cc_status = cc_prev_status;
+	  /* Extending float to double in an fp-reg is a no-op.  */
 	  return "";
 	}
       return "f%&move%.x %1,%0";
@@ -1956,10 +2041,7 @@
     {
       if (REGNO (operands[0]) == REGNO (operands[1]))
 	{
-	  /* Extending float to double in an fp-reg is a no-op.
-	     NOTICE_UPDATE_CC has already assumed that the
-	     cc will be set.  So cancel what it did.  */
-	  cc_status = cc_prev_status;
+	  /* Extending float to double in an fp-reg is a no-op.  */
 	  return "";
 	}
       return "fdmove%.d %1,%0";
@@ -2089,7 +2171,6 @@
    (clobber (match_scratch:SI 3 "=d"))]
   "TARGET_68881 && TUNE_68040"
 {
-  CC_STATUS_INIT;
   return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.l %1,%0\;fmovem%.l %2,%!";
 })
 
@@ -2100,7 +2181,6 @@
    (clobber (match_scratch:SI 3 "=d"))]
   "TARGET_68881 && TUNE_68040"
 {
-  CC_STATUS_INIT;
   return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.w %1,%0\;fmovem%.l %2,%!";
 })
 
@@ -2111,7 +2191,6 @@
    (clobber (match_scratch:SI 3 "=d"))]
   "TARGET_68881 && TUNE_68040"
 {
-  CC_STATUS_INIT;
   return "fmovem%.l %!,%2\;moveq #16,%3\;or%.l %2,%3\;and%.w #-33,%3\;fmovem%.l %3,%!\;fmove%.b %1,%0\;fmovem%.l %2,%!";
 })
 
@@ -2253,7 +2332,6 @@
    (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
   "!TARGET_COLDFIRE"
 {
-  CC_STATUS_INIT;
   if (ADDRESS_REG_P (operands[0]))
     return "add%.w %1,%0";
   else if (ADDRESS_REG_P (operands[3]))
@@ -2269,7 +2347,6 @@
 		 (match_operand:DI 2 "general_operand" "0,0")))]
   "!TARGET_COLDFIRE"
 {
-  CC_STATUS_INIT;
   if (GET_CODE (operands[0]) == REG)
     operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
   else
@@ -2284,7 +2361,6 @@
 		 (match_operand:DI 2 "register_operand" "0")))]
   "TARGET_COLDFIRE"
 {
-  CC_STATUS_INIT;
   return "add%.l %1,%R0\;negx%.l %0\;neg%.l %0";
 })
 
@@ -2298,7 +2374,6 @@
         (match_operand:DI 2 "general_operand" "0,0")))]
   ""
 {
-  CC_STATUS_INIT;
   if (GET_CODE (operands[1]) == REG)
     operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
   else
@@ -2364,7 +2439,6 @@
   else
     {
       gcc_assert (GET_CODE (operands[0]) == MEM);
-      CC_STATUS_INIT;
       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
 	{
 	  operands[1] = gen_rtx_MEM (SImode,
@@ -2383,7 +2457,11 @@
 	  return "add%.l %R2,%1\;move%.l %0,%3\;addx%.l %2,%3\;move%.l %3,%0";
 	}
     }
-})
+}
+  [(set (attr "flags_valid")
+	(if_then_else (match_operand 0 "register_operand")
+		      (const_string "noov")
+		      (const_string "no")))])
 
 (define_insn "addsi_lshrsi_31"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm,dm,d<Q>")
@@ -2428,7 +2506,8 @@
 
 
   "! TARGET_COLDFIRE"
-  "* return output_addsi3 (operands);")
+  "* return output_addsi3 (operands);"
+  [(set_attr "flags_valid" "noov,unchanged,unchanged,noov,unchanged")])
 
 (define_insn_and_split "*addsi3_5200"
   [(set (match_operand:SI 0 "nonimmediate_operand"         "=mr,mr,a,  m,r,  ?a, ?a,?a,?a")
@@ -2513,7 +2592,7 @@
 	  return "subq%.w %2,%0";
 	}
       /* On the CPU32 it is faster to use two addqw instructions to
-	 add a small integer (8 < N <= 16) to a register.  
+	 add a small integer (8 < N <= 16) to a register.
 	 Likewise for subqw.  */
       if (TUNE_CPU32 && REG_P (operands[0]))
 	{
@@ -2534,7 +2613,11 @@
 	return MOTOROLA ? "lea (%c2,%0),%0" : "lea %0@(%c2),%0";
     }
   return "add%.w %2,%0";
-})
+}
+  [(set (attr "flags_valid")
+	(if_then_else (match_operand 0 "address_reg_operand")
+		      (const_string "unchanged")
+		      (const_string "noov")))])
 
 ;; These insns must use MATCH_DUP instead of the more expected
 ;; use of a matching constraint because the "output" here is also
@@ -2548,6 +2631,7 @@
 		 (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
   "!TARGET_COLDFIRE"
 {
+  gcc_assert (!ADDRESS_REG_P (operands[0]));
   if (GET_CODE (operands[1]) == CONST_INT)
     {
       /* If the constant would be a negative number when interpreted as
@@ -2585,11 +2669,10 @@
 	      return "subq%.w #8,%0\;subq%.w %1,%0";
 	    }
 	}
-      if (ADDRESS_REG_P (operands[0]) && !TUNE_68040)
-	return MOTOROLA ? "lea (%c1,%0),%0" : "lea %0@(%c1),%0";
     }
   return "add%.w %1,%0";
-})
+}
+  [(set_attr "flags_valid" "noov")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
@@ -2597,6 +2680,7 @@
 		 (match_dup 0)))]
   "!TARGET_COLDFIRE"
 {
+  gcc_assert (!ADDRESS_REG_P (operands[0]));
   if (GET_CODE (operands[1]) == CONST_INT)
     {
       /* If the constant would be a negative number when interpreted as
@@ -2634,11 +2718,10 @@
 	      return "subq%.w #8,%0\;subq%.w %1,%0";
 	    }
 	}
-      if (ADDRESS_REG_P (operands[0]) && !TUNE_68040)
-	return MOTOROLA ? "lea (%c1,%0),%0" : "lea %0@(%c1),%0";
     }
   return "add%.w %1,%0";
-})
+}
+  [(set_attr "flags_valid" "noov")])
 
 (define_insn "addqi3"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
@@ -2661,7 +2744,8 @@
        }
     }
   return "add%.b %2,%0";
-})
+}
+  [(set_attr "flags_valid" "noov")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
@@ -2779,7 +2863,6 @@
    (clobber (match_scratch:SI 3 "=&d,X,a,?d"))]
   "!TARGET_COLDFIRE"
 {
-  CC_STATUS_INIT;
   if (ADDRESS_REG_P (operands[0]))
     return "sub%.w %2,%0";
   else if (ADDRESS_REG_P (operands[3]))
@@ -2795,7 +2878,6 @@
             (const_int 32))))]
   ""
 {
-  CC_STATUS_INIT;
   if (GET_CODE (operands[1]) == REG)
     operands[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
   else
@@ -2863,7 +2945,6 @@
   else
     {
       gcc_assert (GET_CODE (operands[0]) == MEM);
-      CC_STATUS_INIT;
       if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
 	{
 	  operands[1]
@@ -2882,20 +2963,26 @@
 	  return "sub%.l %R2,%1\;move%.l %0,%3\;subx%.l %2,%3\;move%.l %3,%0";
 	}
     }
-})
+}
+  [(set (attr "flags_valid")
+	(if_then_else (match_operand 0 "register_operand")
+		      (const_string "noov")
+		      (const_string "no")))])
 
 (define_insn "subsi3"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=mda,m,d,a")
-	(minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0")
-		  (match_operand:SI 2 "general_src_operand" "I,dT,mSrT,mSrs")))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=md,ma,m,d,a")
+	(minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0,0")
+		  (match_operand:SI 2 "general_src_operand" "I,I,dT,mSrT,mSrs")))]
   ""
   "@
+   subq%.l %2, %0
    subq%.l %2, %0
    sub%.l %2,%0
    sub%.l %2,%0
    sub%.l %2,%0"
-  [(set_attr "type" "aluq_l,alu_l,alu_l,alu_l")
-   (set_attr "opy" "2")])
+  [(set_attr "type" "aluq_l,aluq_l,alu_l,alu_l,alu_l")
+   (set_attr "opy" "2")
+   (set_attr "flags_valid" "noov,unchanged,noov,noov,unchanged")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "nonimmediate_operand" "=a")
@@ -2910,28 +2997,32 @@
 	(minus:HI (match_operand:HI 1 "general_operand" "0,0")
 		  (match_operand:HI 2 "general_src_operand" "dn,rmSn")))]
   "!TARGET_COLDFIRE"
-  "sub%.w %2,%0")
+  "sub%.w %2,%0"
+  [(set_attr "flags_valid" "noov")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
 	(minus:HI (match_dup 0)
 		  (match_operand:HI 1 "general_src_operand" "dn,rmSn")))]
   "!TARGET_COLDFIRE"
-  "sub%.w %1,%0")
+  "sub%.w %1,%0"
+  [(set_attr "flags_valid" "noov")])
 
 (define_insn "subqi3"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
 	(minus:QI (match_operand:QI 1 "general_operand" "0,0")
 		  (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
   "!TARGET_COLDFIRE"
-  "sub%.b %2,%0")
+  "sub%.b %2,%0"
+  [(set_attr "flags_valid" "noov")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
 	(minus:QI (match_dup 0)
 		  (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
   "!TARGET_COLDFIRE"
-  "sub%.b %1,%0")
+  "sub%.b %1,%0"
+  [(set_attr "flags_valid" "noov")])
 
 (define_expand "sub<mode>3"
   [(set (match_operand:FP 0 "nonimmediate_operand" "")
@@ -3192,10 +3283,7 @@
 	  (const_int 32))))
    (clobber (match_operand:SI 1 "register_operand" "=d"))]
   "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
-{
-  CC_STATUS_INIT;
-  return "mulu%.l %3,%0:%1";
-})
+  "mulu%.l %3,%0:%1")
 
 (define_insn "const_umulsi3_highpart"
   [(set (match_operand:SI 0 "register_operand" "=d")
@@ -3206,10 +3294,7 @@
 	  (const_int 32))))
    (clobber (match_operand:SI 1 "register_operand" "=d"))]
   "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
-{
-  CC_STATUS_INIT;
-  return "mulu%.l %3,%0:%1";
-})
+  "mulu%.l %3,%0:%1")
 
 (define_expand "smulsi3_highpart"
   [(parallel
@@ -3241,10 +3326,7 @@
 	  (const_int 32))))
    (clobber (match_operand:SI 1 "register_operand" "=d"))]
   "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
-{
-  CC_STATUS_INIT;
-  return "muls%.l %3,%0:%1";
-})
+  "muls%.l %3,%0:%1")
 
 (define_insn "const_smulsi3_highpart"
   [(set (match_operand:SI 0 "register_operand" "=d")
@@ -3255,10 +3337,7 @@
 	  (const_int 32))))
    (clobber (match_operand:SI 1 "register_operand" "=d"))]
   "TARGET_68020 && !TUNE_68060 && !TARGET_COLDFIRE"
-{
-  CC_STATUS_INIT;
-  return "muls%.l %3,%0:%1";
-})
+  "muls%.l %3,%0:%1")
 
 (define_expand "mul<mode>3"
   [(set (match_operand:FP 0 "nonimmediate_operand" "")
@@ -3530,16 +3609,13 @@
     "extl %0\;divs %2,%0",
     operands);
   if (!find_reg_note(insn, REG_UNUSED, operands[3]))
-    {
-      CC_STATUS_INIT;
-      return "move%.l %0,%3\;swap %3";
-    }
+    return "move%.l %0,%3\;swap %3";
   else
     return "";
 })
 
 (define_insn "udivmodhi4"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
+  [(set (match_operand:HI 0 "register_operand" "=d")
 	(udiv:HI (match_operand:HI 1 "general_operand" "0")
 		 (match_operand:HI 2 "general_src_operand" "dmSKT")))
    (set (match_operand:HI 3 "register_operand" "=d")
@@ -3558,10 +3634,7 @@
       operands);
 
   if (!find_reg_note(insn, REG_UNUSED, operands[3]))
-    {
-      CC_STATUS_INIT;
-      return "move%.l %0,%3\;swap %3";
-    }
+    return "move%.l %0,%3\;swap %3";
   else
     return "";
 })
@@ -3596,7 +3669,8 @@
   "!TARGET_COLDFIRE"
 {
   return output_andsi3 (operands);
-})
+}
+  [(set_attr "flags_valid" "set")])
 
 (define_insn "andsi3_5200"
   [(set (match_operand:SI 0 "not_sp_operand" "=m,d")
@@ -3621,35 +3695,40 @@
 	(and:HI (match_operand:HI 1 "general_operand" "%0,0")
 		(match_operand:HI 2 "general_src_operand" "dn,dmSn")))]
   "!TARGET_COLDFIRE"
-  "and%.w %2,%0")
+  "and%.w %2,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
 	(and:HI (match_dup 0)
 		(match_operand:HI 1 "general_src_operand" "dn,dmSn")))]
   "!TARGET_COLDFIRE"
-  "and%.w %1,%0")
+  "and%.w %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+m,d"))
 	(and:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
 		(match_dup 0)))]
   "!TARGET_COLDFIRE"
-  "and%.w %1,%0")
+  "and%.w %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn "andqi3"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
 	(and:QI (match_operand:QI 1 "general_operand" "%0,0")
 		(match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
   "!TARGET_COLDFIRE"
-  "and%.b %2,%0")
+  "and%.b %2,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
 	(and:QI (match_dup 0)
 		(match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
   "!TARGET_COLDFIRE"
-  "and%.b %1,%0")
+  "and%.b %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
@@ -3668,7 +3747,6 @@
 {
   int byte_mode;
 
-  CC_STATUS_INIT;
   if (GET_CODE (operands[0]) == REG)
     operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
   else
@@ -3699,7 +3777,8 @@
   "! TARGET_COLDFIRE"
 {
   return output_iorsi3 (operands);
-})
+}
+  [(set_attr "flags_valid" "set")])
 
 (define_insn "iorsi3_5200"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,d")
@@ -3708,7 +3787,8 @@
   "TARGET_COLDFIRE"
 {
   return output_iorsi3 (operands);
-})
+}
+  [(set_attr "flags_valid" "set")])
 
 (define_insn "iorhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d")
@@ -3729,28 +3809,32 @@
 	(ior:HI (match_operand:HI 1 "general_src_operand" "dn,dmSn")
 		(match_dup 0)))]
   "!TARGET_COLDFIRE"
-  "or%.w %1,%0")
+  "or%.w %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn "iorqi3"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=m,d")
 	(ior:QI (match_operand:QI 1 "general_operand" "%0,0")
                 (match_operand:QI 2 "general_src_operand" "dn,dmSn")))]
   "!TARGET_COLDFIRE"
-  "or%.b %2,%0")
+  "or%.b %2,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
 	(ior:QI (match_dup 0)
                 (match_operand:QI 1 "general_src_operand" "dn,dmSn")))]
   "!TARGET_COLDFIRE"
-  "or%.b %1,%0")
+  "or%.b %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+m,d"))
         (ior:QI (match_operand:QI 1 "general_src_operand" "dn,dmSn")
 		(match_dup 0)))]
   "!TARGET_COLDFIRE"
-  "or%.b %1,%0")
+  "or%.b %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 ;; On all 68k models, this makes faster code in a special case.
 ;; See also ashlsi_16, ashrsi_16 and lshrsi_16.
@@ -3762,7 +3846,6 @@
             (const_int 16))))]
   ""
 {
-  CC_STATUS_INIT;
   if (GET_CODE (operands[2]) != REG)
       operands[2] = adjust_address (operands[2], HImode, 2);
   if (GET_CODE (operands[2]) != REG
@@ -3779,7 +3862,6 @@
 {
   int byte_mode;
 
-  CC_STATUS_INIT;
   byte_mode = (GET_MODE (operands[1]) == QImode);
   if (GET_CODE (operands[0]) == MEM)
     operands[0] = adjust_address (operands[0], byte_mode ? QImode : HImode,
@@ -3807,7 +3889,8 @@
   "!TARGET_COLDFIRE"
 {
   return output_xorsi3 (operands);
-})
+}
+  [(set_attr "flags_valid" "set")])
 
 (define_insn "xorsi3_5200"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm,d")
@@ -3816,49 +3899,56 @@
   "TARGET_COLDFIRE"
 {
   return output_xorsi3 (operands);
-})
+}
+  [(set_attr "flags_valid" "set")])
 
 (define_insn "xorhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
 	(xor:HI (match_operand:HI 1 "general_operand" "%0")
 		(match_operand:HI 2 "general_operand" "dn")))]
   "!TARGET_COLDFIRE"
-  "eor%.w %2,%0")
+  "eor%.w %2,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
 	(xor:HI (match_dup 0)
 		(match_operand:HI 1 "general_operand" "dn")))]
   "!TARGET_COLDFIRE"
-  "eor%.w %1,%0")
+  "eor%.w %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
 	(xor:HI (match_operand:HI 1 "general_operand" "dn")
 		(match_dup 0)))]
   "!TARGET_COLDFIRE"
-  "eor%.w %1,%0")
+  "eor%.w %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn "xorqi3"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
 	(xor:QI (match_operand:QI 1 "general_operand" "%0")
 		(match_operand:QI 2 "general_operand" "dn")))]
   "!TARGET_COLDFIRE"
-  "eor%.b %2,%0")
+  "eor%.b %2,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
 	(xor:QI (match_dup 0)
 		(match_operand:QI 1 "general_operand" "dn")))]
   "!TARGET_COLDFIRE"
-  "eor%.b %1,%0")
+  "eor%.b %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
 	(xor:QI (match_operand:QI 1 "general_operand" "dn")
 		(match_dup 0)))]
   "!TARGET_COLDFIRE"
-  "eor%.b %1,%0")
+  "eor%.b %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 ;; negation instructions
 
@@ -3917,38 +4007,44 @@
 	(neg:SI (match_operand:SI 1 "general_operand" "0")))]
   "!TARGET_COLDFIRE"
   "neg%.l %0"
-  [(set_attr "type" "neg_l")])
+  [(set_attr "type" "neg_l")
+   (set_attr "flags_valid" "noov")])
 
 (define_insn "negsi2_5200"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
 	(neg:SI (match_operand:SI 1 "general_operand" "0")))]
   "TARGET_COLDFIRE"
   "neg%.l %0"
-  [(set_attr "type" "neg_l")])
+  [(set_attr "type" "neg_l")
+   (set_attr "flags_valid" "noov")])
 
 (define_insn "neghi2"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
 	(neg:HI (match_operand:HI 1 "general_operand" "0")))]
   "!TARGET_COLDFIRE"
-  "neg%.w %0")
+  "neg%.w %0"
+  [(set_attr "flags_valid" "noov")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
 	(neg:HI (match_dup 0)))]
   "!TARGET_COLDFIRE"
-  "neg%.w %0")
+  "neg%.w %0"
+  [(set_attr "flags_valid" "noov")])
 
 (define_insn "negqi2"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
 	(neg:QI (match_operand:QI 1 "general_operand" "0")))]
   "!TARGET_COLDFIRE"
-  "neg%.b %0")
+  "neg%.b %0"
+  [(set_attr "flags_valid" "noov")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
 	(neg:QI (match_dup 0)))]
   "!TARGET_COLDFIRE"
-  "neg%.b %0")
+  "neg%.b %0"
+  [(set_attr "flags_valid" "noov")])
 
 ;; If using software floating point, just flip the sign bit.
 
@@ -4242,20 +4338,14 @@
   [(set (match_operand:SI 0 "register_operand" "=d")
         (clz:SI (match_operand:SI 1 "general_operand" "do")))]
   "TARGET_68020 && TARGET_BITFIELD"
-{
-  CC_STATUS_INIT;
-  return "bfffo %1{#0:#0},%0";
-})
+  "bfffo %1{#0:#0},%0")
 
 ;; ColdFire ff1 instruction implements clz.
 (define_insn "*clzsi2_cf"
   [(set (match_operand:SI 0 "register_operand" "=d")
  	(clz:SI (match_operand:SI 1 "register_operand" "0")))]
   "ISA_HAS_FF1"
-{
-  CC_STATUS_INIT;
-  return "ff1 %0";
-}
+  "ff1 %0"
   [(set_attr "type" "ext")])
 
 ;; one complement instructions
@@ -4276,7 +4366,8 @@
   [(set (match_operand:SI 0 "nonimmediate_operand" "=dm")
 	(not:SI (match_operand:SI 1 "general_operand" "0")))]
   "!TARGET_COLDFIRE"
-  "not%.l %0")
+  "not%.l %0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn "one_cmplsi2_5200"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
@@ -4289,25 +4380,29 @@
   [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
 	(not:HI (match_operand:HI 1 "general_operand" "0")))]
   "!TARGET_COLDFIRE"
-  "not%.w %0")
+  "not%.w %0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm"))
 	(not:HI (match_dup 0)))]
   "!TARGET_COLDFIRE"
-  "not%.w %0")
+  "not%.w %0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn "one_cmplqi2"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
 	(not:QI (match_operand:QI 1 "general_operand" "0")))]
   "!TARGET_COLDFIRE"
-  "not%.b %0")
+  "not%.b %0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm"))
 	(not:QI (match_dup 0)))]
   "!TARGET_COLDFIRE"
-  "not%.b %0")
+  "not%.b %0"
+  [(set_attr "flags_valid" "yes")])
 
 ;; arithmetic shift instructions
 ;; We don't need the shift memory by 1 bit instruction
@@ -4331,7 +4426,6 @@
     (clobber (match_scratch:SI 2 "=a,X"))]
   ""
 {
-  CC_STATUS_INIT;
   if (GET_CODE (operands[0]) == MEM)
     {
     if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
@@ -4529,13 +4623,10 @@
 	(ashift:SI (match_operand:SI 1 "register_operand" "0")
 		   (const_int 16)))]
   "!TUNE_68060"
-{
-  CC_STATUS_INIT;
-  return "swap %0\;clr%.w %0";
-})
+  "swap %0\;clr%.w %0")
 
 ;; ashift patterns : use lsl instead of asl, because lsl always clears the
-;; overflow bit, so we must not set CC_NO_OVERFLOW.
+;; overflow bit, allowing more comparisons.
 
 ;; On the 68000, this makes faster code in a special case.
 
@@ -4547,8 +4638,6 @@
    && INTVAL (operands[2]) > 16
    && INTVAL (operands[2]) <= 24"
 {
-  CC_STATUS_INIT;
-
   operands[2] = GEN_INT (INTVAL (operands[2]) - 16);
   return "lsl%.w %2,%0\;swap %0\;clr%.w %0";
 })
@@ -4560,40 +4649,45 @@
   ""
 {
   if (operands[2] == const1_rtx)
-    {
-      cc_status.flags = CC_NO_OVERFLOW;
-      return "add%.l %0,%0";
-    }
+    return "add%.l %0,%0";
   return "lsl%.l %2,%0";
-})
+}
+  [(set (attr "flags_valid")
+        (if_then_else (match_operand 2 "const1_operand")
+		      (const_string "noov")
+		      (const_string "yes")))])
 
 (define_insn "ashlhi3"
   [(set (match_operand:HI 0 "register_operand" "=d")
 	(ashift:HI (match_operand:HI 1 "register_operand" "0")
 		   (match_operand:HI 2 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "lsl%.w %2,%0")
+  "lsl%.w %2,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
 	(ashift:HI (match_dup 0)
 		   (match_operand:HI 1 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "lsl%.w %1,%0")
+  "lsl%.w %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn "ashlqi3"
   [(set (match_operand:QI 0 "register_operand" "=d")
 	(ashift:QI (match_operand:QI 1 "register_operand" "0")
 		   (match_operand:QI 2 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "lsl%.b %2,%0")
+  "lsl%.b %2,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
 	(ashift:QI (match_dup 0)
 		   (match_operand:QI 1 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "lsl%.b %1,%0")
+  "lsl%.b %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 ;; On most 68k models, this makes faster code in a special case.
 
@@ -4647,7 +4741,6 @@
   "!TARGET_COLDFIRE"
 {
   operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
-  CC_STATUS_INIT;
   return "asr%.l #1,%0\;roxr%.l #1,%1";
 })
 
@@ -4713,7 +4806,6 @@
 		     (const_int 32)))]
   ""
 {
-  CC_STATUS_INIT;
   if (TARGET_68020)
     return "move%.l %1,%R0\;smi %0\;extb%.l %0";
   else
@@ -4727,7 +4819,6 @@
    (clobber (match_scratch:SI 2 "=d,d"))]
   ""
 {
-  CC_STATUS_INIT;
   operands[3] = adjust_address (operands[0], SImode,
 				which_alternative == 0 ? 4 : 0);
   operands[0] = adjust_address (operands[0], SImode, 0);
@@ -4760,7 +4851,6 @@
 	|| (INTVAL (operands[2]) > 32 && INTVAL (operands[2]) <= 63))"
 {
   operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
-  CC_STATUS_INIT;
   if (INTVAL (operands[2]) == 48)
     return "swap %0\;ext%.l %0\;move%.l %0,%1\;smi %0\;ext%.w %0";
   if (INTVAL (operands[2]) == 31)
@@ -4810,35 +4900,40 @@
   ""
   "asr%.l %2,%0"
   [(set_attr "type" "shift")
-   (set_attr "opy" "2")])
+   (set_attr "opy" "2")
+   (set_attr "flags_valid" "noov")])
 
 (define_insn "ashrhi3"
   [(set (match_operand:HI 0 "register_operand" "=d")
 	(ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
 		     (match_operand:HI 2 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "asr%.w %2,%0")
+  "asr%.w %2,%0"
+  [(set_attr "flags_valid" "noov")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
 	(ashiftrt:HI (match_dup 0)
 		     (match_operand:HI 1 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "asr%.w %1,%0")
+  "asr%.w %1,%0"
+  [(set_attr "flags_valid" "noov")])
 
 (define_insn "ashrqi3"
   [(set (match_operand:QI 0 "register_operand" "=d")
 	(ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
 		     (match_operand:QI 2 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "asr%.b %2,%0")
+  "asr%.b %2,%0"
+  [(set_attr "flags_valid" "noov")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
 	(ashiftrt:QI (match_dup 0)
 		     (match_operand:QI 1 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "asr%.b %1,%0")
+  "asr%.b %1,%0"
+  [(set_attr "flags_valid" "noov")])
 
 ;; logical shift instructions
 
@@ -4885,7 +4980,6 @@
 		     (const_int 1)))]
   "!TARGET_COLDFIRE"
 {
-  CC_STATUS_INIT;
   return "lsr%.l #1,%0\;roxr%.l #1,%R0";
 })
 
@@ -5083,7 +5177,6 @@
 		     (const_int 16)))]
   "!TUNE_68060"
 {
-  CC_STATUS_INIT;
   return "clr%.w %0\;swap %0";
 })
 
@@ -5109,35 +5202,40 @@
   ""
   "lsr%.l %2,%0"
   [(set_attr "type" "shift")
-   (set_attr "opy" "2")])
+   (set_attr "opy" "2")
+   (set_attr "flags_valid" "yes")])
 
 (define_insn "lshrhi3"
   [(set (match_operand:HI 0 "register_operand" "=d")
 	(lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
 		     (match_operand:HI 2 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "lsr%.w %2,%0")
+  "lsr%.w %2,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
 	(lshiftrt:HI (match_dup 0)
 		     (match_operand:HI 1 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "lsr%.w %1,%0")
+  "lsr%.w %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn "lshrqi3"
   [(set (match_operand:QI 0 "register_operand" "=d")
 	(lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
 		     (match_operand:QI 2 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "lsr%.b %2,%0")
+  "lsr%.b %2,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
 	(lshiftrt:QI (match_dup 0)
 		     (match_operand:QI 1 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "lsr%.b %1,%0")
+  "lsr%.b %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 ;; rotate instructions
 
@@ -5147,7 +5245,8 @@
 		   (const_int 16)))]
   ""
   "swap %0"
-  [(set_attr "type" "shift")])
+  [(set_attr "type" "shift")
+   (set_attr "flags_valid" "yes")])
 
 (define_insn "rotlsi3"
   [(set (match_operand:SI 0 "register_operand" "=d")
@@ -5164,7 +5263,8 @@
     }
   else
     return "rol%.l %2,%0";
-})
+}
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn "rotlhi3"
   [(set (match_operand:HI 0 "register_operand" "=d")
@@ -5179,7 +5279,8 @@
     }
   else
     return "rol%.w %2,%0";
-})
+}
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn "*rotlhi3_lowpart"
   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
@@ -5194,7 +5295,8 @@
     }
   else
     return "rol%.w %1,%0";
-})
+}
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn "rotlqi3"
   [(set (match_operand:QI 0 "register_operand" "=d")
@@ -5209,7 +5311,8 @@
     }
   else
     return "rol%.b %2,%0";
-})
+}
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn "*rotlqi3_lowpart"
   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
@@ -5224,14 +5327,16 @@
     }
   else
     return "rol%.b %1,%0";
-})
+}
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn "rotrsi3"
   [(set (match_operand:SI 0 "register_operand" "=d")
 	(rotatert:SI (match_operand:SI 1 "register_operand" "0")
 		     (match_operand:SI 2 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "ror%.l %2,%0")
+  "ror%.l %2,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn "rotrhi3"
   [(set (match_operand:HI 0 "register_operand" "=d")
@@ -5252,14 +5357,16 @@
 	(rotatert:QI (match_operand:QI 1 "register_operand" "0")
 		     (match_operand:QI 2 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "ror%.b %2,%0")
+  "ror%.b %2,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_insn ""
   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
 	(rotatert:QI (match_dup 0)
 		     (match_operand:QI 1 "general_operand" "dI")))]
   "!TARGET_COLDFIRE"
-  "ror%.b %1,%0")
+  "ror%.b %1,%0"
+  [(set_attr "flags_valid" "yes")])
 
 (define_expand "bswapsi2"
   [(set (match_operand:SI 0 "register_operand")
@@ -5284,10 +5391,7 @@
 		(match_operand:SI 1 "general_operand" "d")) 3)
 	(match_dup 0)))]
   ""
-{
-  CC_STATUS_INIT;
-  return "bset %1,%0";
-}
+  "bset %1,%0"
   [(set_attr "type" "bitrw")])
 
 ;; set bit, bit number is (sign/zero)_extended from HImode/QImode
@@ -5298,10 +5402,7 @@
 		[(match_operand 1 "general_operand" "d")])) 3)
 	(match_dup 0)))]
   ""
-{
-  CC_STATUS_INIT;
-  return "bset %1,%0";
-}
+  "bset %1,%0"
   [(set_attr "type" "bitrw")])
 
 (define_insn "*bsetdreg"
@@ -5311,10 +5412,7 @@
 				   (const_int 31)))
 		(match_operand:SI 2 "register_operand" "0")))]
   ""
-{
-  CC_STATUS_INIT;
-  return "bset %1,%0";
-}
+  "bset %1,%0"
   [(set_attr "type" "bitrw")])
 
 (define_insn "*bchgdreg"
@@ -5324,10 +5422,7 @@
 				   (const_int 31)))
 		(match_operand:SI 2 "register_operand" "0")))]
   ""
-{
-  CC_STATUS_INIT;
-  return "bchg %1,%0";
-}
+  "bchg %1,%0"
   [(set_attr "type" "bitrw")])
 
 (define_insn "*bclrdreg"
@@ -5337,10 +5432,7 @@
 				   (const_int 31)))
 		(match_operand:SI 2 "register_operand" "0")))]
   ""
-{
-  CC_STATUS_INIT;
-  return "bclr %1,%0";
-}
+  "bclr %1,%0"
   [(set_attr "type" "bitrw")])
 
 ;; clear bit, bit number is int
@@ -5351,10 +5443,7 @@
 	    (match_operand:SI 1 "general_operand" "d")))
     (const_int 0))]
   ""
-{
-  CC_STATUS_INIT;
-  return "bclr %1,%0";
-}
+  "bclr %1,%0"
   [(set_attr "type" "bitrw")])
 
 ;; clear bit, bit number is (sign/zero)_extended from HImode/QImode
@@ -5366,10 +5455,7 @@
 		[(match_operand 1 "general_operand" "d")])))
     (const_int 0))]
   ""
-{
-  CC_STATUS_INIT;
-  return "bclr %1,%0";
-}
+  "bclr %1,%0"
   [(set_attr "type" "bitrw")])
 
 ;; Special cases of bit-field insns which we should
@@ -5452,7 +5538,6 @@
    && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
    && INTVAL (operands[3]) % INTVAL (operands[2]) == 0"
 {
-  cc_status.flags |= CC_NOT_NEGATIVE;
   if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
     return "bfextu %1{%b3:%b2},%0";
 
@@ -5520,1133 +5605,185 @@
 	(sign_extract:SI (match_operand:QI 1 "memory_operand" "o")
 			 (match_operand:SI 2 "nonmemory_operand" "dn")
 			 (match_operand:SI 3 "nonmemory_operand" "dn")))]
-  "TARGET_68020 && TARGET_BITFIELD"
-  "bfexts %1{%b3:%b2},%0")
-
-(define_expand "extzv"
-  [(set (match_operand:SI 0 "register_operand" "")
-	(zero_extract:SI (match_operand:SI 1 "general_operand" "")
-			 (match_operand:SI 2 "const_int_operand" "")
-			 (match_operand:SI 3 "const_int_operand" "")))]
-  "TARGET_68020 && TARGET_BITFIELD"
-  "")
-
-(define_insn "*extzv_bfextu_mem"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-	(zero_extract:SI (match_operand:QI 1 "memory_operand" "o")
-			 (match_operand:SI 2 "nonmemory_operand" "dn")
-			 (match_operand:SI 3 "nonmemory_operand" "dn")))]
-  "TARGET_68020 && TARGET_BITFIELD"
-{
-  if (GET_CODE (operands[2]) == CONST_INT)
-    {
-      if (INTVAL (operands[2]) != 32)
-	cc_status.flags |= CC_NOT_NEGATIVE;
-    }
-  else
-    {
-      CC_STATUS_INIT;
-    }
-  return "bfextu %1{%b3:%b2},%0";
-})
-
-(define_insn "*insv_bfchg_mem"
-  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
-			 (match_operand:SI 1 "nonmemory_operand" "dn")
-			 (match_operand:SI 2 "nonmemory_operand" "dn"))
-        (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
-		(match_operand 3 "const_int_operand" "n")))]
-  "TARGET_68020 && TARGET_BITFIELD
-   && (INTVAL (operands[3]) == -1
-       || (GET_CODE (operands[1]) == CONST_INT
-           && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))"
-{
-  CC_STATUS_INIT;
-  return "bfchg %0{%b2:%b1}";
-})
-
-(define_insn "*insv_bfclr_mem"
-  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
-			 (match_operand:SI 1 "nonmemory_operand" "dn")
-			 (match_operand:SI 2 "nonmemory_operand" "dn"))
-	(const_int 0))]
-  "TARGET_68020 && TARGET_BITFIELD"
-{
-  CC_STATUS_INIT;
-  return "bfclr %0{%b2:%b1}";
-})
-
-(define_insn "*insv_bfset_mem"
-  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
-			 (match_operand:SI 1 "general_operand" "dn")
-			 (match_operand:SI 2 "general_operand" "dn"))
-	(const_int -1))]
-  "TARGET_68020 && TARGET_BITFIELD"
-{
-  CC_STATUS_INIT;
-  return "bfset %0{%b2:%b1}";
-})
-
-(define_expand "insv"
-  [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "")
-			 (match_operand:SI 1 "const_int_operand" "")
-			 (match_operand:SI 2 "const_int_operand" ""))
-	(match_operand:SI 3 "reg_or_pow2_m1_operand" ""))]
-  "TARGET_68020 && TARGET_BITFIELD"
-  "
-{
-  /* Special case initializing a field to all ones. */
-  if (GET_CODE (operands[3]) == CONST_INT)
-    {
-      if (exact_log2 (INTVAL (operands[3]) + 1) != INTVAL (operands[1]))
-	operands[3] = force_reg (SImode, operands[3]);
-      else
-	operands[3] = constm1_rtx;
-
-    }
-}")
-
-(define_insn "*insv_bfins_mem"
-  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
-			 (match_operand:SI 1 "nonmemory_operand" "dn")
-			 (match_operand:SI 2 "nonmemory_operand" "dn"))
-	(match_operand:SI 3 "register_operand" "d"))]
-  "TARGET_68020 && TARGET_BITFIELD"
-  "bfins %3,%0{%b2:%b1}")
-
-;; Now recognize bit-field insns that operate on registers
-;; (or at least were intended to do so).
-
-(define_insn "*extv_bfexts_reg"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
-	(sign_extract:SI (match_operand:SI 1 "register_operand" "d")
-			 (match_operand:SI 2 "const_int_operand" "n")
-			 (match_operand:SI 3 "const_int_operand" "n")))]
-  "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[3]), 0, 31)"
-  "bfexts %1{%b3:%b2},%0")
-
-(define_insn "*extv_bfextu_reg"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
-	(zero_extract:SI (match_operand:SI 1 "register_operand" "d")
-			 (match_operand:SI 2 "const_int_operand" "n")
-			 (match_operand:SI 3 "const_int_operand" "n")))]
-  "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[3]), 0, 31)"
-{
-  if (GET_CODE (operands[2]) == CONST_INT)
-    {
-      if (INTVAL (operands[2]) != 32)
-	cc_status.flags |= CC_NOT_NEGATIVE;
-    }
-  else
-    {
-      CC_STATUS_INIT;
-    }
-  return "bfextu %1{%b3:%b2},%0";
-})
-
-(define_insn "*insv_bfclr_reg"
-  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
-			 (match_operand:SI 1 "const_int_operand" "n")
-			 (match_operand:SI 2 "const_int_operand" "n"))
-	(const_int 0))]
-  "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)"
-{
-  CC_STATUS_INIT;
-  return "bfclr %0{%b2:%b1}";
-})
-
-(define_insn "*insv_bfset_reg"
-  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
-			 (match_operand:SI 1 "const_int_operand" "n")
-			 (match_operand:SI 2 "const_int_operand" "n"))
-	(const_int -1))]
-  "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)"
-{
-  CC_STATUS_INIT;
-  return "bfset %0{%b2:%b1}";
-})
-
-(define_insn "*insv_bfins_reg"
-  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
-			 (match_operand:SI 1 "const_int_operand" "n")
-			 (match_operand:SI 2 "const_int_operand" "n"))
-	(match_operand:SI 3 "register_operand" "d"))]
-  "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)"
-{
-#if 0
-  /* These special cases are now recognized by a specific pattern.  */
-  if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
-      && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16)
-    return "move%.w %3,%0";
-  if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
-      && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8)
-    return "move%.b %3,%0";
-#endif
-  return "bfins %3,%0{%b2:%b1}";
-})
-
-;; Special patterns for optimizing bit-field instructions.
-
-(define_insn "*tst_bftst_mem"
-  [(set (cc0)
-	(compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
-				  (match_operand:SI 1 "const_int_operand" "n")
-				  (match_operand:SI 2 "general_operand" "dn"))
-	         (const_int 0)))]
-  "TARGET_68020 && TARGET_BITFIELD"
-{
-  if (operands[1] == const1_rtx
-      && GET_CODE (operands[2]) == CONST_INT)
-    {
-      int width = GET_CODE (operands[0]) == REG ? 31 : 7;
-      return output_btst (operands,
-			  GEN_INT (width - INTVAL (operands[2])),
-			  operands[0], insn, 1000);
-      /* Pass 1000 as SIGNPOS argument so that btst will
-         not think we are testing the sign bit for an `and'
-	 and assume that nonzero implies a negative result.  */
-    }
-  if (INTVAL (operands[1]) != 32)
-    cc_status.flags = CC_NOT_NEGATIVE;
-  return "bftst %0{%b2:%b1}";
-})
-
-
-;;; now handle the register cases
-(define_insn "*tst_bftst_reg"
-  [(set (cc0)
-	(compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
-				  (match_operand:SI 1 "const_int_operand" "n")
-			 	  (match_operand:SI 2 "general_operand" "dn"))
-		 (const_int 0)))]
-  "TARGET_68020 && TARGET_BITFIELD
-    && !(CONST_INT_P (operands[2]) && !IN_RANGE (INTVAL (operands[2]), 0, 31))"
-{
-  if (operands[1] == const1_rtx
-      && GET_CODE (operands[2]) == CONST_INT)
-    {
-      int width = GET_CODE (operands[0]) == REG ? 31 : 7;
-      return output_btst (operands, GEN_INT (width - INTVAL (operands[2])),
-			  operands[0], insn, 1000);
-      /* Pass 1000 as SIGNPOS argument so that btst will
-         not think we are testing the sign bit for an `and'
-	 and assume that nonzero implies a negative result.  */
-    }
-  if (INTVAL (operands[1]) != 32)
-    cc_status.flags = CC_NOT_NEGATIVE;
-  return "bftst %0{%b2:%b1}";
-})
-
-(define_insn "scc0_di"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
-    (match_operator 1 "ordered_comparison_operator"
-      [(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
-  "! TARGET_COLDFIRE"
-{
-  return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
-})
-
-(define_insn "scc0_di_5200"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=d")
-    (match_operator 1 "ordered_comparison_operator"
-      [(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
-  "TARGET_COLDFIRE"
-{
-  return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
-})
-
-(define_insn "scc_di"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,dm")
-    (match_operator 1 "ordered_comparison_operator"
-      [(match_operand:DI 2 "general_operand" "ro,r")
-       (match_operand:DI 3 "general_operand" "r,ro")]))]
-  "! TARGET_COLDFIRE"
-{
-  return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
-})
-
-(define_insn "scc_di_5200"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d")
-    (match_operator 1 "ordered_comparison_operator"
-      [(match_operand:DI 2 "general_operand" "ro,r")
-       (match_operand:DI 3 "general_operand" "r,ro")]))]
-  "TARGET_COLDFIRE"
-{
-  return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
-})
-
-;; Note that operand 0 of an SCC insn is supported in the hardware as
-;; memory, but we cannot allow it to be in memory in case the address
-;; needs to be reloaded.
-
-(define_insn ""
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(eq:QI (cc0) (const_int 0)))]
-  ""
-{
-  cc_status = cc_prev_status;
-  OUTPUT_JUMP ("seq %0", "fseq %0", "seq %0");
-})
-
-(define_insn ""
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(ne:QI (cc0) (const_int 0)))]
-  ""
-{
-  cc_status = cc_prev_status;
-  OUTPUT_JUMP ("sne %0", "fsne %0", "sne %0");
-})
-
-(define_insn ""
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(gt:QI (cc0) (const_int 0)))]
-  ""
-{
-  cc_status = cc_prev_status;
-  OUTPUT_JUMP ("sgt %0", "fsgt %0", 0);
-})
-
-(define_insn ""
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(gtu:QI (cc0) (const_int 0)))]
-  ""
-{
-  cc_status = cc_prev_status;
-  return "shi %0";
-})
-
-(define_insn ""
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(lt:QI (cc0) (const_int 0)))]
-  ""
-{
-   cc_status = cc_prev_status;
-   OUTPUT_JUMP ("slt %0", "fslt %0", "smi %0");
-})
-
-(define_insn ""
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(ltu:QI (cc0) (const_int 0)))]
-  ""
-{
-   cc_status = cc_prev_status;
-   return "scs %0";
-})
-
-(define_insn ""
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(ge:QI (cc0) (const_int 0)))]
-  ""
-{
-   cc_status = cc_prev_status;
-   OUTPUT_JUMP ("sge %0", "fsge %0", "spl %0");
-})
-
-(define_insn "*scc"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(geu:QI (cc0) (const_int 0)))]
-  ""
-{
-   cc_status = cc_prev_status;
-   return "scc %0";
-}
-  [(set_attr "type" "scc")])
-
-(define_insn ""
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(le:QI (cc0) (const_int 0)))]
-  ""
-{
-  cc_status = cc_prev_status;
-  OUTPUT_JUMP ("sle %0", "fsle %0", 0);
-})
-
-(define_insn "*sls"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(leu:QI (cc0) (const_int 0)))]
-  ""
-{
-   cc_status = cc_prev_status;
-   return "sls %0";
-}
-  [(set_attr "type" "scc")])
-
-(define_insn "*sordered_1"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(ordered:QI (cc0) (const_int 0)))]
-  "TARGET_68881 && !TUNE_68060"
-{
-  cc_status = cc_prev_status;
-  return "fsor %0";
-})
-
-(define_insn "*sunordered_1"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(unordered:QI (cc0) (const_int 0)))]
-  "TARGET_68881 && !TUNE_68060"
-{
-  cc_status = cc_prev_status;
-  return "fsun %0";
-})
-
-(define_insn "*suneq_1"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(uneq:QI (cc0) (const_int 0)))]
-  "TARGET_68881 && !TUNE_68060"
-{
-  cc_status = cc_prev_status;
-  return "fsueq %0";
-})
-
-(define_insn "*sunge_1"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(unge:QI (cc0) (const_int 0)))]
-  "TARGET_68881 && !TUNE_68060"
-{
-  cc_status = cc_prev_status;
-  return "fsuge %0";
-})
-
-(define_insn "*sungt_1"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(ungt:QI (cc0) (const_int 0)))]
-  "TARGET_68881 && !TUNE_68060"
-{
-  cc_status = cc_prev_status;
-  return "fsugt %0";
-})
-
-(define_insn "*sunle_1"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(unle:QI (cc0) (const_int 0)))]
-  "TARGET_68881 && !TUNE_68060"
-{
-  cc_status = cc_prev_status;
-  return "fsule %0";
-})
-
-(define_insn "*sunlt_1"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(unlt:QI (cc0) (const_int 0)))]
-  "TARGET_68881 && !TUNE_68060"
-{
-  cc_status = cc_prev_status;
-  return "fsult %0";
-})
-
-(define_insn "*sltgt_1"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(ltgt:QI (cc0) (const_int 0)))]
-  "TARGET_68881 && !TUNE_68060"
-{
-  cc_status = cc_prev_status;
-  return "fsogl %0";
-})
-
-(define_insn "*fsogt_1"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(not:QI (unle:QI (cc0) (const_int 0))))]
-  "TARGET_68881 && !TUNE_68060"
-{
-  cc_status = cc_prev_status;
-  return "fsogt %0";
-})
-
-(define_insn "*fsoge_1"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(not:QI (unlt:QI (cc0) (const_int 0))))]
-  "TARGET_68881 && !TUNE_68060"
-{
-  cc_status = cc_prev_status;
-  return "fsoge %0";
-})
-
-(define_insn "*fsolt_1"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(not:QI (unge:QI (cc0) (const_int 0))))]
-  "TARGET_68881 && !TUNE_68060"
-{
-  cc_status = cc_prev_status;
-  return "fsolt %0";
-})
-
-(define_insn "*fsole_1"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-	(not:QI (ungt:QI (cc0) (const_int 0))))]
-  "TARGET_68881 && !TUNE_68060"
-{
-  cc_status = cc_prev_status;
-  return "fsole %0";
-})
-
-;; Basic conditional jump instructions.
-
-(define_insn "beq0_di"
-  [(set (pc)
-    (if_then_else (eq (match_operand:DI 0 "general_operand" "d*a,o,<>")
-            (const_int 0))
-        (label_ref (match_operand 1 "" ",,"))
-        (pc)))
-   (clobber (match_scratch:SI 2 "=d,&d,d"))]
-  ""
-{
-  CC_STATUS_INIT;
-  if (which_alternative == 2)
-    return "move%.l %0,%2\;or%.l %0,%2\;jeq %l1";
-  if ((cc_prev_status.value1
-      && rtx_equal_p (cc_prev_status.value1, operands[0]))
-    || (cc_prev_status.value2
-      && rtx_equal_p (cc_prev_status.value2, operands[0])))
-    {
-      cc_status = cc_prev_status;
-      return "jeq %l1";
-    }
-  if (GET_CODE (operands[0]) == REG)
-    operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
-  else
-    operands[3] = adjust_address (operands[0], SImode, 4);
-  if (! ADDRESS_REG_P (operands[0]))
-    {
-      if (reg_overlap_mentioned_p (operands[2], operands[0]))
-	{
-	  if (reg_overlap_mentioned_p (operands[2], operands[3]))
-	    return "or%.l %0,%2\;jeq %l1";
-	  else
-	    return "or%.l %3,%2\;jeq %l1";
-	}
-      return "move%.l %0,%2\;or%.l %3,%2\;jeq %l1";
-    }
-  operands[4] = gen_label_rtx();
-  if (TARGET_68020 || TARGET_COLDFIRE)
-    output_asm_insn ("tst%.l %0\;jne %l4\;tst%.l %3\;jeq %l1", operands);
-  else
-    output_asm_insn ("cmp%.w #0,%0\;jne %l4\;cmp%.w #0,%3\;jeq %l1", operands);
-  (*targetm.asm_out.internal_label) (asm_out_file, "L",
-				CODE_LABEL_NUMBER (operands[4]));
-  return "";
-})
-
-(define_insn "bne0_di"
-  [(set (pc)
-    (if_then_else (ne (match_operand:DI 0 "general_operand" "d,o,*a")
-            (const_int 0))
-        (label_ref (match_operand 1 "" ",,"))
-        (pc)))
-   (clobber (match_scratch:SI 2 "=d,&d,X"))]
-  ""
-{
-  if ((cc_prev_status.value1
-      && rtx_equal_p (cc_prev_status.value1, operands[0]))
-    || (cc_prev_status.value2
-      && rtx_equal_p (cc_prev_status.value2, operands[0])))
-    {
-      cc_status = cc_prev_status;
-      return "jne %l1";
-    }
-  CC_STATUS_INIT;
-  if (GET_CODE (operands[0]) == REG)
-    operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
-  else
-    operands[3] = adjust_address (operands[0], SImode, 4);
-  if (!ADDRESS_REG_P (operands[0]))
-    {
-      if (reg_overlap_mentioned_p (operands[2], operands[0]))
-	{
-	  if (reg_overlap_mentioned_p (operands[2], operands[3]))
-	    return "or%.l %0,%2\;jne %l1";
-	  else
-	    return "or%.l %3,%2\;jne %l1";
-	}
-      return "move%.l %0,%2\;or%.l %3,%2\;jne %l1";
-    }
-  if (TARGET_68020 || TARGET_COLDFIRE)
-    return "tst%.l %0\;jne %l1\;tst%.l %3\;jne %l1";
-  else
-    return "cmp%.w #0,%0\;jne %l1\;cmp%.w #0,%3\;jne %l1";
-})
-
-(define_insn "bge0_di"
-  [(set (pc)
-    (if_then_else (ge (match_operand:DI 0 "general_operand" "ro")
-            (const_int 0))
-        (label_ref (match_operand 1 "" ""))
-        (pc)))]
-  ""
-{
-  if ((cc_prev_status.value1
-      && rtx_equal_p (cc_prev_status.value1, operands[0]))
-    || (cc_prev_status.value2
-      && rtx_equal_p (cc_prev_status.value2, operands[0])))
-    {
-      cc_status = cc_prev_status;
-      return cc_status.flags & CC_REVERSED ? "jle %l1" : "jpl %l1";
-    }
-  CC_STATUS_INIT;
-  if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (operands[0]))
-    output_asm_insn("tst%.l %0", operands);
-  else
-    {
-      /* On an address reg, cmpw may replace cmpl.  */
-      output_asm_insn("cmp%.w #0,%0", operands);
-    }
-  return "jpl %l1";
-})
-
-(define_insn "blt0_di"
-  [(set (pc)
-    (if_then_else (lt (match_operand:DI 0 "general_operand" "ro")
-            (const_int 0))
-        (label_ref (match_operand 1 "" ""))
-        (pc)))]
-  ""
-{
-  if ((cc_prev_status.value1
-      && rtx_equal_p (cc_prev_status.value1, operands[0]))
-    || (cc_prev_status.value2
-      && rtx_equal_p (cc_prev_status.value2, operands[0])))
-    {
-      cc_status = cc_prev_status;
-      return cc_status.flags & CC_REVERSED ? "jgt %l1" : "jmi %l1";
-    }
-  CC_STATUS_INIT;
-  if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (operands[0]))
-    output_asm_insn("tst%.l %0", operands);
-  else
-    {
-      /* On an address reg, cmpw may replace cmpl.  */
-      output_asm_insn("cmp%.w #0,%0", operands);
-    }
-  return "jmi %l1";
-})
-
-(define_insn "beq"
-  [(set (pc)
-	(if_then_else (eq (cc0)
-			  (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-{
-  OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0");
-}
-  [(set_attr "type" "bcc")])
-
-(define_insn "bne"
-  [(set (pc)
-	(if_then_else (ne (cc0)
-			  (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-{
-  OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0");
-}
-  [(set_attr "type" "bcc")])
-
-(define_insn "bgt"
-  [(set (pc)
-	(if_then_else (gt (cc0)
-			  (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-{
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
-  OUTPUT_JUMP ("jgt %l0", "fjgt %l0", 0);
-}
-  [(set_attr "type" "bcc")])
-
-(define_insn "bgtu"
-  [(set (pc)
-	(if_then_else (gtu (cc0)
-			   (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-{
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
-  return "jhi %l0";
-}
-  [(set_attr "type" "bcc")])
-
-(define_insn "blt"
-  [(set (pc)
-	(if_then_else (lt (cc0)
-			  (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-{
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
-  OUTPUT_JUMP ("jlt %l0", "fjlt %l0", "jmi %l0");
-}
-  [(set_attr "type" "bcc")])
-
-(define_insn "bltu"
-  [(set (pc)
-	(if_then_else (ltu (cc0)
-			   (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-{
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
-  return "jcs %l0";
-}
-  [(set_attr "type" "bcc")])
-
-(define_insn "bge"
-  [(set (pc)
-	(if_then_else (ge (cc0)
-			  (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-{
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
-  OUTPUT_JUMP ("jge %l0", "fjge %l0", "jpl %l0");
-})
-
-(define_insn "bgeu"
-  [(set (pc)
-	(if_then_else (geu (cc0)
-			   (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-{
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
-  return "jcc %l0";
-}
-  [(set_attr "type" "bcc")])
-
-(define_insn "ble"
-  [(set (pc)
-	(if_then_else (le (cc0)
-			  (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-{
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
-  OUTPUT_JUMP ("jle %l0", "fjle %l0", 0);
-}
-  [(set_attr "type" "bcc")])
-
-(define_insn "bleu"
-  [(set (pc)
-	(if_then_else (leu (cc0)
-			   (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  ""
-{
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
-  return "jls %l0";
-}
-  [(set_attr "type" "bcc")])
-
-(define_insn "bordered"
-  [(set (pc)
-	(if_then_else (ordered (cc0) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  "TARGET_HARD_FLOAT"
-{
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjor %l0";
-}
-  [(set_attr "type" "fbcc")])
-
-(define_insn "bunordered"
-  [(set (pc)
-	(if_then_else (unordered (cc0) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  "TARGET_HARD_FLOAT"
-{
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjun %l0";
-}
-  [(set_attr "type" "fbcc")])
-
-(define_insn "buneq"
-  [(set (pc)
-	(if_then_else (uneq (cc0) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  "TARGET_HARD_FLOAT"
-{
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjueq %l0";
-}
-  [(set_attr "type" "fbcc")])
-
-(define_insn "bunge"
-  [(set (pc)
-	(if_then_else (unge (cc0) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  "TARGET_HARD_FLOAT"
-{
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjuge %l0";
-}
-  [(set_attr "type" "fbcc")])
-
-(define_insn "bungt"
-  [(set (pc)
-	(if_then_else (ungt (cc0) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  "TARGET_HARD_FLOAT"
-{
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjugt %l0";
-}
-  [(set_attr "type" "fbcc")])
-
-(define_insn "bunle"
-  [(set (pc)
-	(if_then_else (unle (cc0) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  "TARGET_HARD_FLOAT"
-{
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjule %l0";
-}
-  [(set_attr "type" "fbcc")])
-
-(define_insn "bunlt"
-  [(set (pc)
-	(if_then_else (unlt (cc0) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  "TARGET_HARD_FLOAT"
-{
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjult %l0";
-}
-  [(set_attr "type" "fbcc")])
-
-(define_insn "bltgt"
-  [(set (pc)
-	(if_then_else (ltgt (cc0) (const_int 0))
-		      (label_ref (match_operand 0 "" ""))
-		      (pc)))]
-  "TARGET_HARD_FLOAT"
-{
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjogl %l0";
-}
-  [(set_attr "type" "fbcc")])
-
-;; Negated conditional jump instructions.
-
-(define_insn "*beq_rev"
-  [(set (pc)
-	(if_then_else (eq (cc0)
-			  (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  ""
-{
-  OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0");
-}
-  [(set_attr "type" "bcc")])
-
-(define_insn "*bne_rev"
-  [(set (pc)
-	(if_then_else (ne (cc0)
-			  (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  ""
-{
-  OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0");
-}
-  [(set_attr "type" "bcc")])
-
-(define_insn "*bgt_rev"
-  [(set (pc)
-	(if_then_else (gt (cc0)
-			  (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  ""
-{
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
+  "TARGET_68020 && TARGET_BITFIELD"
+  "bfexts %1{%b3:%b2},%0")
 
-  OUTPUT_JUMP ("jle %l0", "fjngt %l0", 0);
-}
-  [(set_attr "type" "bcc")])
+(define_expand "extzv"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(zero_extract:SI (match_operand:SI 1 "general_operand" "")
+			 (match_operand:SI 2 "const_int_operand" "")
+			 (match_operand:SI 3 "const_int_operand" "")))]
+  "TARGET_68020 && TARGET_BITFIELD"
+  "")
 
-(define_insn "*bgtu_rev"
-  [(set (pc)
-	(if_then_else (gtu (cc0)
-			   (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  ""
+(define_insn "*extzv_bfextu_mem"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+	(zero_extract:SI (match_operand:QI 1 "memory_operand" "o")
+			 (match_operand:SI 2 "nonmemory_operand" "dn")
+			 (match_operand:SI 3 "nonmemory_operand" "dn")))]
+  "TARGET_68020 && TARGET_BITFIELD"
 {
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
-  return "jls %l0";
-}
-  [(set_attr "type" "bcc")])
+  return "bfextu %1{%b3:%b2},%0";
+})
 
-(define_insn "*blt_rev"
-  [(set (pc)
-	(if_then_else (lt (cc0)
-			  (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  ""
+(define_insn "*insv_bfchg_mem"
+  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
+			 (match_operand:SI 1 "nonmemory_operand" "dn")
+			 (match_operand:SI 2 "nonmemory_operand" "dn"))
+        (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
+		(match_operand 3 "const_int_operand" "n")))]
+  "TARGET_68020 && TARGET_BITFIELD
+   && (INTVAL (operands[3]) == -1
+       || (GET_CODE (operands[1]) == CONST_INT
+           && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))"
 {
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
-  OUTPUT_JUMP ("jge %l0", "fjnlt %l0", "jpl %l0");
-}
-  [(set_attr "type" "bcc")])
+  return "bfchg %0{%b2:%b1}";
+})
 
-(define_insn "*bltu_rev"
-  [(set (pc)
-	(if_then_else (ltu (cc0)
-			   (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  ""
+(define_insn "*insv_bfclr_mem"
+  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
+			 (match_operand:SI 1 "nonmemory_operand" "dn")
+			 (match_operand:SI 2 "nonmemory_operand" "dn"))
+	(const_int 0))]
+  "TARGET_68020 && TARGET_BITFIELD"
 {
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
-  return "jcc %l0";
-}
-  [(set_attr "type" "bcc")])
+  return "bfclr %0{%b2:%b1}";
+})
 
-(define_insn "*bge_rev"
-  [(set (pc)
-	(if_then_else (ge (cc0)
-			  (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  ""
+(define_insn "*insv_bfset_mem"
+  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
+			 (match_operand:SI 1 "general_operand" "dn")
+			 (match_operand:SI 2 "general_operand" "dn"))
+	(const_int -1))]
+  "TARGET_68020 && TARGET_BITFIELD"
 {
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
-  OUTPUT_JUMP ("jlt %l0", "fjnge %l0", "jmi %l0");
-}
-  [(set_attr "type" "bcc")])
+  return "bfset %0{%b2:%b1}";
+})
 
-(define_insn "*bgeu_rev"
-  [(set (pc)
-	(if_then_else (geu (cc0)
-			   (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  ""
+(define_expand "insv"
+  [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "")
+			 (match_operand:SI 1 "const_int_operand" "")
+			 (match_operand:SI 2 "const_int_operand" ""))
+	(match_operand:SI 3 "reg_or_pow2_m1_operand" ""))]
+  "TARGET_68020 && TARGET_BITFIELD"
+  "
 {
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+  /* Special case initializing a field to all ones. */
+  if (GET_CODE (operands[3]) == CONST_INT)
     {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
-  return "jcs %l0";
-}
-  [(set_attr "type" "bcc")])
+      if (exact_log2 (INTVAL (operands[3]) + 1) != INTVAL (operands[1]))
+	operands[3] = force_reg (SImode, operands[3]);
+      else
+	operands[3] = constm1_rtx;
 
-(define_insn "*ble_rev"
-  [(set (pc)
-	(if_then_else (le (cc0)
-			  (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  ""
-{
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
     }
+}")
 
-  OUTPUT_JUMP ("jgt %l0", "fjnle %l0", 0);
-}
-  [(set_attr "type" "bcc")])
+(define_insn "*insv_bfins_mem"
+  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
+			 (match_operand:SI 1 "nonmemory_operand" "dn")
+			 (match_operand:SI 2 "nonmemory_operand" "dn"))
+	(match_operand:SI 3 "register_operand" "d"))]
+  "TARGET_68020 && TARGET_BITFIELD"
+  "bfins %3,%0{%b2:%b1}")
 
-(define_insn "*bleu_rev"
-  [(set (pc)
-	(if_then_else (leu (cc0)
-			   (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  ""
-{
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
+;; Now recognize bit-field insns that operate on registers
+;; (or at least were intended to do so).
 
-  return "jhi %l0";
-}
-  [(set_attr "type" "bcc")])
+(define_insn "*extv_bfexts_reg"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
+	(sign_extract:SI (match_operand:SI 1 "register_operand" "d")
+			 (match_operand:SI 2 "const_int_operand" "n")
+			 (match_operand:SI 3 "const_int_operand" "n")))]
+  "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[3]), 0, 31)"
+  "bfexts %1{%b3:%b2},%0")
 
-(define_insn "*bordered_rev"
-  [(set (pc)
-	(if_then_else (ordered (cc0) (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  "TARGET_HARD_FLOAT"
+(define_insn "*extv_bfextu_reg"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
+	(zero_extract:SI (match_operand:SI 1 "register_operand" "d")
+			 (match_operand:SI 2 "const_int_operand" "n")
+			 (match_operand:SI 3 "const_int_operand" "n")))]
+  "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[3]), 0, 31)"
 {
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjun %l0";
-}
-  [(set_attr "type" "fbcc")])
+  return "bfextu %1{%b3:%b2},%0";
+})
 
-(define_insn "*bunordered_rev"
-  [(set (pc)
-	(if_then_else (unordered (cc0) (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  "TARGET_HARD_FLOAT"
+(define_insn "*insv_bfclr_reg"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(const_int 0))]
+  "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)"
 {
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjor %l0";
-}
-  [(set_attr "type" "fbcc")])
+  return "bfclr %0{%b2:%b1}";
+})
 
-(define_insn "*buneq_rev"
-  [(set (pc)
-	(if_then_else (uneq (cc0) (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  "TARGET_HARD_FLOAT"
+(define_insn "*insv_bfset_reg"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(const_int -1))]
+  "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)"
 {
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjogl %l0";
-}
-  [(set_attr "type" "fbcc")])
+  return "bfset %0{%b2:%b1}";
+})
 
-(define_insn "*bunge_rev"
-  [(set (pc)
-	(if_then_else (unge (cc0) (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  "TARGET_HARD_FLOAT"
+(define_insn "*insv_bfins_reg"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(match_operand:SI 3 "register_operand" "d"))]
+  "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)"
 {
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjolt %l0";
-}
-  [(set_attr "type" "fbcc")])
-
-(define_insn "*bungt_rev"
-  [(set (pc)
-	(if_then_else (ungt (cc0) (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  "TARGET_HARD_FLOAT"
+#if 0
+  /* These special cases are now recognized by a specific pattern.  */
+  if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
+      && INTVAL (operands[1]) == 16 && INTVAL (operands[2]) == 16)
+    return "move%.w %3,%0";
+  if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
+      && INTVAL (operands[1]) == 24 && INTVAL (operands[2]) == 8)
+    return "move%.b %3,%0";
+#endif
+  return "bfins %3,%0{%b2:%b1}";
+})
+
+(define_insn "scc0_di"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
+    (match_operator 1 "ordered_comparison_operator"
+      [(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
+  "! TARGET_COLDFIRE"
 {
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjole %l0";
-}
-  [(set_attr "type" "fbcc")])
+  return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
+})
 
-(define_insn "*bunle_rev"
-  [(set (pc)
-	(if_then_else (unle (cc0) (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  "TARGET_HARD_FLOAT"
+(define_insn "scc0_di_5200"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=d")
+    (match_operator 1 "ordered_comparison_operator"
+      [(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
+  "TARGET_COLDFIRE"
 {
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjogt %l0";
-}
-  [(set_attr "type" "fbcc")])
+  return output_scc_di (operands[1], operands[2], const0_rtx, operands[0]);
+})
 
-(define_insn "*bunlt_rev"
-  [(set (pc)
-	(if_then_else (unlt (cc0) (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  "TARGET_HARD_FLOAT"
+(define_insn "scc_di"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,dm")
+    (match_operator 1 "ordered_comparison_operator"
+      [(match_operand:DI 2 "general_operand" "ro,r")
+       (match_operand:DI 3 "general_operand" "r,ro")]))]
+  "! TARGET_COLDFIRE"
 {
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjoge %l0";
-}
-  [(set_attr "type" "fbcc")])
+  return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
+})
 
-(define_insn "*bltgt_rev"
-  [(set (pc)
-	(if_then_else (ltgt (cc0) (const_int 0))
-		      (pc)
-		      (label_ref (match_operand 0 "" ""))))]
-  "TARGET_HARD_FLOAT"
+(define_insn "scc_di_5200"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d")
+    (match_operator 1 "ordered_comparison_operator"
+      [(match_operand:DI 2 "general_operand" "ro,r")
+       (match_operand:DI 3 "general_operand" "r,ro")]))]
+  "TARGET_COLDFIRE"
 {
-  gcc_assert (cc_prev_status.flags & CC_IN_68881);
-  return "fjueq %l0";
-}
-  [(set_attr "type" "fbcc")])
+  return output_scc_di (operands[1], operands[2], operands[3], operands[0]);
+})
 
 ;; Unconditional and other jump instructions
 (define_insn "jump"
@@ -6731,7 +5868,6 @@
 		 (const_int -1)))]
   "!TARGET_COLDFIRE"
 {
-  CC_STATUS_INIT;
   if (DATA_REG_P (operands[0]))
     return "dbra %0,%l1";
   if (GET_CODE (operands[0]) == MEM)
@@ -6751,7 +5887,6 @@
 		 (const_int -1)))]
   "!TARGET_COLDFIRE"
 {
-  CC_STATUS_INIT;
   if (DATA_REG_P (operands[0]))
     return "dbra %0,%l1\;clr%.w %0\;subq%.l #1,%0\;jcc %l1";
   if (GET_CODE (operands[0]) == MEM)
@@ -6774,7 +5909,6 @@
 		 (const_int -1)))]
   "!TARGET_COLDFIRE && find_reg_note (insn, REG_NONNEG, 0)"
 {
-  CC_STATUS_INIT;
   if (DATA_REG_P (operands[0]))
     return "dbra %0,%l1";
   if (GET_CODE (operands[0]) == MEM)
@@ -6809,7 +5943,6 @@
 		 (const_int -1)))]
   "!TARGET_COLDFIRE && find_reg_note (insn, REG_NONNEG, 0)"
 {
-  CC_STATUS_INIT;
   if (DATA_REG_P (operands[0]))
     return "dbra %0,%l1\;clr%.w %0\;subq%.l #1,%0\;jcc %l1";
   if (GET_CODE (operands[0]) == MEM)
@@ -6956,13 +6089,15 @@
 (define_insn "blockage"
   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
   ""
-  "")
+  ""
+  [(set_attr "flags_valid" "unchanged")])
 
 (define_insn "nop"
   [(const_int 0)]
   ""
   "nop"
-  [(set_attr "type" "nop")])
+  [(set_attr "type" "nop")
+   (set_attr "flags_valid" "unchanged")])
 
 (define_expand "prologue"
   [(const_int 0)]
@@ -7334,8 +6469,9 @@
 (define_mode_iterator DBCC [HI SI])
 
 (define_peephole
-  [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
-                             [(cc0) (const_int 0)])
+  [(set (pc) (if_then_else (match_operator 3 "ordered_comparison_operator"
+			    [(match_operand:CMPMODE 4 "general_operand" "")
+			     (match_operand:CMPMODE 5 "general_operand" "")])
                            (label_ref (match_operand 2 "" ""))
                            (pc)))
    (parallel
@@ -7348,16 +6484,18 @@
      (set (match_dup 0)
 	  (plus:DBCC (match_dup 0)
 		     (const_int -1)))])]
-  "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
+  "!TARGET_COLDFIRE && DATA_REG_P (operands[0])"
 {
-  CC_STATUS_INIT;
-  output_dbcc_and_branch (operands);
+  rtx_code code = GET_CODE (operands[3]);
+  code = m68k_output_compare_<CMPMODE:mode> (operands[4], operands[5], code);
+  output_dbcc_and_branch (operands, code);
   return "";
 })
 
 (define_peephole
-  [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
-                             [(cc0) (const_int 0)])
+  [(set (pc) (if_then_else (match_operator 3 "ordered_comparison_operator"
+			    [(match_operand:CMPMODE 4 "general_operand" "")
+			     (match_operand:CMPMODE 5 "general_operand" "")])
                            (label_ref (match_operand 2 "" ""))
                            (pc)))
    (parallel
@@ -7371,10 +6509,11 @@
      (set (match_dup 0)
 	  (plus:DBCC (match_dup 0)
 		     (const_int -1)))])]
-  "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
+  "!TARGET_COLDFIRE && DATA_REG_P (operands[0])"
 {
-  CC_STATUS_INIT;
-  output_dbcc_and_branch (operands);
+  rtx_code code = GET_CODE (operands[3]);
+  code = m68k_output_compare_<CMPMODE:mode> (operands[4], operands[5], code);
+  output_dbcc_and_branch (operands, code);
   return "";
 })
 
@@ -7387,10 +6526,7 @@
     {
       if (REGNO (operands[0]) == REGNO (operands[1]))
 	{
-	  /* Extending float to double in an fp-reg is a no-op.
-	     NOTICE_UPDATE_CC has already assumed that the
-	     cc will be set.  So cancel what it did.  */
-	  cc_status = cc_prev_status;
+	  /* Extending float to double in an fp-reg is a no-op.  */
 	  return "";
 	}
       return "f%$move%.x %1,%0";
@@ -7419,10 +6555,7 @@
     {
       if (REGNO (operands[0]) == REGNO (operands[1]))
 	{
-	  /* Extending float to double in an fp-reg is a no-op.
-	     NOTICE_UPDATE_CC has already assumed that the
-	     cc will be set.  So cancel what it did.  */
-	  cc_status = cc_prev_status;
+	  /* Extending float to double in an fp-reg is a no-op.  */
 	  return "";
 	}
       return "fmove%.x %1,%0";
@@ -7501,57 +6634,41 @@
 ;; also the trap vector used by TRAPcc instruction. By restricting
 ;; these patterns to const1_operand, they will not be generated.
 ;; Left disabled for now, as enabling it seems to cause issues.
-(define_expand "ctrapdi4"
+(define_insn "ctrap<mode>4"
   [(trap_if (match_operator 0 "ordered_comparison_operator"
-			    [(cc0) (const_int 0)])
-	    (match_operand:SI 3 "const1_operand" ""))]
-  "TARGET_68020"
+	     [(match_operand:CMPMODE 1 "nonimmediate_operand" "<cmp1_constraints>")
+	      (match_operand:CMPMODE 2 "general_operand" "<cmp2_constraints>")])
+	      (match_operand:SI 3 "const1_operand" ""))]
+  "TARGET_68020 && !TARGET_COLDFIRE"
 {
-  if (operands[2] == const0_rtx)
-    emit_insn (gen_tstdi (operands[1]));
-  else
-    emit_insn (gen_cmpdi (operands[1], operands[2]));
-  operands[1] = cc0_rtx;
-  operands[2] = const0_rtx;
-})
-
-(define_expand "ctrapsi4"
-  [(set (cc0)
-	(compare (match_operand:SI 1 "nonimmediate_operand" "")
-		 (match_operand:SI 2 "general_operand" "")))
-   (trap_if (match_operator 0 "ordered_comparison_operator"
-			    [(cc0) (const_int 0)])
-	    (match_operand:SI 3 "const1_operand" ""))]
-  "TARGET_68020"
-  "")
-
-(define_expand "ctraphi4"
-  [(set (cc0)
-	(compare (match_operand:HI 1 "nonimmediate_src_operand" "")
-		 (match_operand:HI 2 "general_src_operand" "")))
-   (trap_if (match_operator 0 "ordered_comparison_operator"
-			    [(cc0) (const_int 0)])
-	    (match_operand:SI 3 "const1_operand" ""))]
-  "TARGET_68020"
-  "")
-
-(define_expand "ctrapqi4"
-  [(set (cc0)
-	(compare (match_operand:QI 1 "nonimmediate_src_operand" "")
-		 (match_operand:QI 2 "general_src_operand" "")))
-   (trap_if (match_operator 0 "ordered_comparison_operator"
-			    [(cc0) (const_int 0)])
-	    (match_operand:SI 3 "const1_operand" ""))]
-  "TARGET_68020"
-  "")
+  rtx_code code = GET_CODE (operands[0]);
+  code = m68k_output_compare_<mode> (operands[1], operands[2], code);
+  switch (code)
+  {
+  case EQ:  return "trapeq";
+  case NE:  return "trapne";
+  case GT:  return "trapgt";
+  case GTU: return "traphi";
+  case LT:  return "traplt";
+  case LTU: return "trapcs";
+  case GE:  return "trapge";
+  case GEU: return "trapcc";
+  case LE:  return "traple";
+  case LEU: return "trapls";
+  default: gcc_unreachable ();
+  }
+})
 
-(define_insn "*conditional_trap"
+(define_insn "ctrap<mode>4_cf"
   [(trap_if (match_operator 0 "ordered_comparison_operator"
-			    [(cc0) (const_int 0)])
-	    (match_operand:SI 1 "const1_operand" "I"))]
-  "TARGET_68020 && ! flags_in_68881 ()"
-{
-  switch (GET_CODE (operands[0]))
+	     [(match_operand:CMPMODE 1 "nonimmediate_operand" "<cmp1_cf_constraints>")
+	      (match_operand:CMPMODE 2 "general_operand" "<cmp2_cf_constraints>")])
+	      (match_operand:SI 3 "const1_operand" ""))]
+  "TARGET_68020 && TARGET_COLDFIRE"
+{
+  rtx_code code = GET_CODE (operands[0]);
+  code = m68k_output_compare_<mode> (operands[1], operands[2], code);
+  switch (code)
   {
   case EQ:  return "trapeq";
   case NE:  return "trapne";
@@ -7646,10 +6763,8 @@
 (define_peephole2
   [(set (match_operand:SI 0 "register_operand" "")
 	(match_operand:SI 1 "addq_subq_operand" ""))
-   (set (cc0) (compare (match_operand:SI 2 "register_operand" "")
-		       (match_dup 0)))
    (set (pc) (if_then_else (match_operator 5 "equality_comparison_operator"
-			    [(cc0) (const_int 0)])
+			    [(match_operand:SI 2 "register_operand" "") (match_dup 0)])
 			   (match_operand 3 "pc_or_label_operand")
 			   (match_operand 4 "pc_or_label_operand")))]
   "peep2_reg_dead_p (2, operands[0])
@@ -7658,8 +6773,7 @@
    && DATA_REG_P (operands[2])
    && !rtx_equal_p (operands[0], operands[2])"
   [(set (match_dup 2) (plus:SI (match_dup 2) (match_dup 6)))
-   (set (cc0) (compare (match_dup 2) (const_int 0)))
-   (set (pc) (if_then_else (match_op_dup 5 [(cc0) (const_int 0)])
+   (set (pc) (if_then_else (match_op_dup 5 [(match_dup 2) (const_int 0)])
 			   (match_dup 3)
 			   (match_dup 4)))]
   "operands[6] = GEN_INT (-INTVAL (operands[1]));")
@@ -7667,9 +6781,8 @@
 (define_peephole2
   [(set (match_operand:SI 0 "register_operand" "")
 	(match_operand:SI 1 "pow2_m1_operand" ""))
-   (set (cc0) (compare (match_operand:SI 2 "register_operand" "")
-		       (match_operand:SI 3 "register_operand" "")))
-   (set (pc) (if_then_else (gtu (cc0) (const_int 0))
+   (set (pc) (if_then_else (gtu (match_operand:SI 2 "register_operand" "")
+				(match_operand:SI 3 "register_operand" ""))
 			   (match_operand 4 "pc_or_label_operand")
 			   (match_operand 5 "pc_or_label_operand")))]
   "INTVAL (operands[1]) <= 255
@@ -7680,8 +6793,7 @@
    && (optimize_size || TUNE_68040_60)
    && DATA_REG_P (operands[2])"
   [(set (match_dup 7) (lshiftrt:SI (match_dup 7) (match_dup 6)))
-   (set (cc0) (compare (match_dup 7) (const_int 0)))
-   (set (pc) (if_then_else (ne (cc0) (const_int 0))
+   (set (pc) (if_then_else (ne (match_dup 7) (const_int 0))
 			   (match_dup 4) (match_dup 5)))]
   "
 {
@@ -7690,9 +6802,8 @@
 }")
 
 (define_peephole2
-  [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
-		       (match_operand:SI 1 "pow2_m1_operand" "")))
-   (set (pc) (if_then_else (gtu (cc0) (const_int 0))
+  [(set (pc) (if_then_else (gtu (match_operand:SI 0 "register_operand" "")
+				(match_operand:SI 1 "pow2_m1_operand" ""))
 			   (match_operand 2 "pc_or_label_operand")
 			   (match_operand 3 "pc_or_label_operand")))]
   "INTVAL (operands[1]) <= 255
@@ -7701,17 +6812,15 @@
    && (optimize_size || TUNE_68040_60)
    && DATA_REG_P (operands[0])"
   [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 4)))
-   (set (cc0) (compare (match_dup 0) (const_int 0)))
-   (set (pc) (if_then_else (ne (cc0) (const_int 0))
+   (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
 			   (match_dup 2) (match_dup 3)))]
   "{ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); }")
 
 (define_peephole2
   [(set (match_operand:SI 0 "register_operand" "")
 	(match_operand:SI 1 "pow2_m1_operand" ""))
-   (set (cc0) (compare (match_operand:SI 2 "register_operand" "")
-		       (match_operand:SI 3 "register_operand" "")))
-   (set (pc) (if_then_else (leu (cc0) (const_int 0))
+   (set (pc) (if_then_else (leu (match_operand:SI 2 "register_operand" "")
+				(match_operand:SI 3 "register_operand" ""))
 			   (match_operand 4 "pc_or_label_operand")
 			   (match_operand 5 "pc_or_label_operand")))]
   "INTVAL (operands[1]) <= 255
@@ -7722,8 +6831,7 @@
    && (optimize_size || TUNE_68040_60)
    && DATA_REG_P (operands[2])"
   [(set (match_dup 7) (lshiftrt:SI (match_dup 7) (match_dup 6)))
-   (set (cc0) (compare (match_dup 7) (const_int 0)))
-   (set (pc) (if_then_else (eq (cc0) (const_int 0))
+   (set (pc) (if_then_else (eq (match_dup 7) (const_int 0))
 			   (match_dup 4) (match_dup 5)))]
   "
 {
@@ -7731,9 +6839,8 @@
   operands[7] = operands[2];
 }")
 (define_peephole2
-  [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
-		       (match_operand:SI 1 "pow2_m1_operand" "")))
-   (set (pc) (if_then_else (leu (cc0) (const_int 0))
+  [(set (pc) (if_then_else (leu (match_operand:SI 0 "register_operand" "")
+				(match_operand:SI 1 "pow2_m1_operand" ""))
 			   (match_operand 2 "pc_or_label_operand")
 			   (match_operand 3 "pc_or_label_operand")))]
   "INTVAL (operands[1]) <= 255
@@ -7742,8 +6849,7 @@
    && (optimize_size || TUNE_68040_60)
    && DATA_REG_P (operands[0])"
   [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 4)))
-   (set (cc0) (compare (match_dup 0) (const_int 0)))
-   (set (pc) (if_then_else (eq (cc0) (const_int 0))
+   (set (pc) (if_then_else (eq (match_dup 0) (const_int 0))
 			   (match_dup 2) (match_dup 3)))]
   "{ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); }")
 
@@ -7752,10 +6858,9 @@
 ;; internally against 65535).
 ;; The rotate in the output pattern will turn into a swap.
 (define_peephole2
-  [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
-		       (const_int 65535)))
-   (set (pc) (if_then_else (match_operator 1 "swap_peephole_relational_operator"
-			     [(cc0) (const_int 0)])
+  [(set (pc) (if_then_else (match_operator 1 "swap_peephole_relational_operator"
+			     [(match_operand:SI 0 "register_operand" "")
+			      (const_int 65535)])
 			   (match_operand 2 "pc_or_label_operand")
 			   (match_operand 3 "pc_or_label_operand")))]
   "peep2_reg_dead_p (1, operands[0])
@@ -7763,7 +6868,6 @@
    && (optimize_size || TUNE_68000_10)
    && DATA_REG_P (operands[0])"
   [(set (match_dup 0) (rotate:SI (match_dup 0) (const_int 16)))
-   (set (cc0) (compare (subreg:HI (match_dup 0) 2) (const_int 0)))
-   (set (pc) (if_then_else (match_op_dup 1 [(cc0) (const_int 0)])
+   (set (pc) (if_then_else (match_op_dup 1 [(subreg:HI (match_dup 0) 2) (const_int 0)])
 			   (match_dup 2) (match_dup 3)))]
   "")
diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md
index 4cc3d3dc1bd..9e4c8ba864f 100644
--- a/gcc/config/m68k/predicates.md
+++ b/gcc/config/m68k/predicates.md
@@ -115,15 +115,6 @@
 	  && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
 })
 
-;; Return true if X is a valid comparison operator for the dbcc
-;; instruction.  Note it rejects floating point comparison
-;; operators. (In the future we could use Fdbcc).  It also rejects
-;; some comparisons when CC_NO_OVERFLOW is set.
-
-(define_predicate "valid_dbcc_comparison_p"
-  (and (match_code "eq,ne,gtu,ltu,geu,leu,gt,lt,ge,le")
-       (match_test "valid_dbcc_comparison_p_2 (op, mode)")))
-
 (define_predicate "m68k_cstore_comparison_operator"
   (if_then_else (match_test "TARGET_68881")
 	        (match_operand 0 "comparison_operator")
@@ -234,15 +225,17 @@
 
 ;; Special case of general_src_operand, which rejects a few fp
 ;; constants (which we prefer in registers) before reload.
+;; Used only in comparisons, and we do want to allow zero.
 
 (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));
+  return (!CONSTANT_P (op)
+	  || op == CONST0_RTX (mode)
+	  || (TARGET_68881
+	      && (!standard_68881_constant_p (op)
+		  || reload_in_progress
+		  || reload_completed)));
 })
 
 ;; Used to detect constants that are valid for addq/subq instructions
@@ -282,3 +275,6 @@
 
 (define_predicate "swap_peephole_relational_operator"
   (match_code "gtu,leu,gt,le"))
+
+(define_predicate "address_reg_operand"
+  (match_test ("ADDRESS_REG_P (op)")))
diff --git a/gcc/recog.c b/gcc/recog.c
index 9e9cca7db02..0482818c453 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -923,23 +923,6 @@ validate_simplify_insn (rtx_insn *insn)
   return ((num_changes_pending () > 0) && (apply_change_group () > 0));
 }
 
-/* Return 1 if the insn using CC0 set by INSN does not contain
-   any ordered tests applied to the condition codes.
-   EQ and NE tests do not count.  */
-
-int
-next_insn_tests_no_inequality (rtx_insn *insn)
-{
-  rtx_insn *next = next_cc0_user (insn);
-
-  /* If there is no next insn, we have to take the conservative choice.  */
-  if (next == 0)
-    return 0;
-
-  return (INSN_P (next)
-	  && ! inequality_comparisons_p (PATTERN (next)));
-}
-
 /* Return 1 if OP is a valid general operand for machine mode MODE.
    This is either a register reference, a memory reference,
    or a constant.  In the case of a memory reference, the address
diff --git a/gcc/recog.h b/gcc/recog.h
index 71d88e3e376..69238cf16a6 100644
--- a/gcc/recog.h
+++ b/gcc/recog.h
@@ -112,7 +112,6 @@ extern void validate_replace_rtx_group (rtx, rtx, rtx_insn *);
 extern void validate_replace_src_group (rtx, rtx, rtx_insn *);
 extern bool validate_simplify_insn (rtx_insn *insn);
 extern int num_changes_pending (void);
-extern int next_insn_tests_no_inequality (rtx_insn *);
 extern bool reg_fits_class_p (const_rtx, reg_class_t, int, machine_mode);
 
 extern int offsettable_memref_p (rtx);
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 1369e66a136..be27937f7f9 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3514,7 +3514,6 @@ extern bool insn_nothrow_p (const_rtx);
 extern bool can_nonlocal_goto (const rtx_insn *);
 extern void copy_reg_eh_region_note_forward (rtx, rtx_insn *, rtx);
 extern void copy_reg_eh_region_note_backward (rtx, rtx_insn *, rtx);
-extern int inequality_comparisons_p (const_rtx);
 extern rtx replace_rtx (rtx, rtx, rtx, bool = false);
 extern void replace_label (rtx *, rtx, rtx, bool);
 extern void replace_label_in_insn (rtx_insn *, rtx_insn *, rtx_insn *, bool);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 720aa093a23..241a35b0e6c 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -3021,64 +3021,6 @@ may_trap_or_fault_p (const_rtx x)
   return may_trap_p_1 (x, 1);
 }
 
-/* Return nonzero if X contains a comparison that is not either EQ or NE,
-   i.e., an inequality.  */
-
-int
-inequality_comparisons_p (const_rtx x)
-{
-  const char *fmt;
-  int len, i;
-  const enum rtx_code code = GET_CODE (x);
-
-  switch (code)
-    {
-    case REG:
-    case SCRATCH:
-    case PC:
-    case CC0:
-    CASE_CONST_ANY:
-    case CONST:
-    case LABEL_REF:
-    case SYMBOL_REF:
-      return 0;
-
-    case LT:
-    case LTU:
-    case GT:
-    case GTU:
-    case LE:
-    case LEU:
-    case GE:
-    case GEU:
-      return 1;
-
-    default:
-      break;
-    }
-
-  len = GET_RTX_LENGTH (code);
-  fmt = GET_RTX_FORMAT (code);
-
-  for (i = 0; i < len; i++)
-    {
-      if (fmt[i] == 'e')
-	{
-	  if (inequality_comparisons_p (XEXP (x, i)))
-	    return 1;
-	}
-      else if (fmt[i] == 'E')
-	{
-	  int j;
-	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-	    if (inequality_comparisons_p (XVECEXP (x, i, j)))
-	      return 1;
-	}
-    }
-
-  return 0;
-}
-
 /* Replace any occurrence of FROM in X with TO.  The function does
    not enter into CONST_DOUBLE for the replace.
 

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