public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Eliminate cc0 from m68k
@ 2019-11-13 13:08 Bernd Schmidt
  2019-11-13 13:09 ` [PATCH 1/4] Preliminary m68k patches Bernd Schmidt
                   ` (6 more replies)
  0 siblings, 7 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-13 13:08 UTC (permalink / raw)
  To: GCC Patches

This is a set of patches to convert m68k so that it no longer uses cc0.
The approach is to combine cc0 setter/user pairs into cbranch and cstore
patterns. It does not expose the flag register directly. Since m68k is a
target that is not under active development, and probably receives very
limited testing, I felt it was important to make it generate as close to
the same code as previously. Also, given that the target clobbers the
flags for pretty much every move, it seems unlikely that there's much
value to be had from anything more complex. Trying to model every
instruction's effect on the flags would be too error-prone for not
nearly enough gain.

The cc0 machinery allows for eliminating unnecessary comparisons by
examining the effect instructions have on the flags registers. I have
replicated that mechanism with a relatively modest amount of code based
on a final_postscan_insn hook, but it is now opt-in: an instruction
pattern can set the "flags_valid" attribute to a number of possible
values to indicate what effect it has. That should be more reliable (try
git log m68k.md to see recent sprinkling of CC_STATUS_INIT to squash
bugs with the previous mechanism).
We can remember either values where the flags indicate a comparison
against zero (after practically all arithmetic and move insns), or
alternatively record two comparison operands to eliminate identical
compares. I stopped adding optimizations once I found it hard to find
any meaningful differences in generated code. In particular, the
m68k.exp tests which verify that these optimizations are performed all
still pass.

Testing was done with the qemu-system-m68k/debian combination. I do not
have access to Coldfire hardware, and I tried to be somewhat
conservative, for example by not adding "flags_valid" everywhere it
would probably be possible. For someone with access to the hardware, it
should be trivial to add such attributes and test that everything still
works.
I'll have to rerun my final tests because test_summary made a mess of
things, but as far as I am able to tell, there are no regressions, and
the patch set even fixes some failures in libstdc++.

The first and second patch contain the m68k changes. They are separated
only to make the review easier, they were not tested separately (since
the time for a test run is measured in days). The first patch contains
preliminary cleanup and fixes, the second the main cc0 conversion. After
that, there are some changes in the rest of the compiler.


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 1/4] Preliminary m68k patches
  2019-11-13 13:08 [PATCH 0/4] Eliminate cc0 from m68k Bernd Schmidt
@ 2019-11-13 13:09 ` Bernd Schmidt
  2019-11-13 20:37   ` Jeff Law
  2019-11-13 13:13 ` [PATCH 2/4] The main m68k cc0 conversion Bernd Schmidt
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-13 13:09 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1579 bytes --]

This tidies up a few spots in the m68k backend in preparation for the
large patch to follow.  This is purely for review purposes: this patch
has not been tested independently, and will be committed together with
the following one.

Noteworthy changes:

Some patterns and peepholes were unified through mode iterators.  The
m68k_subword_comparison_operator predicate was adapted to also work with
SImode.

There are already scc_di patterns, so there is no need to generate a cc0
set/use pair in cstoredi.

Without HAVE_cc0, combine sometimes substitutes a stack push into the
destination of a divmod instruction, and then gets confused because it
doesn't seem to expect it in a PARALLEL.  Since the instruction only
works on registers anyway, use register_operand.

There are patterns that use register_operand with "do" constraints which
allow memory. This works at reload time, but the instruction can not be
rerecognized later on.  This becomes a problem if such operands occur in
a jump instruction, as subsequent passes will try to redirect branches
and thus attempt to rerecognize the pattern.

movqi/movhi do not accept constants that are not CONST_INT.  The code to
output them would not set flags correctly and was changed to
gcc_unreachable.

Comments were added to some patterns which are not being generated due
to incorrect tests/predicates. Fixing these is out of scope for this
work, but the problems are at least documented.

All the passes working on conditional traps seem to assume
const_true_rtx is used for unconditional ones, rather than const1_rtx.


Bernd

[-- Attachment #2: m68k-1.diff --]
[-- Type: text/x-patch, Size: 15326 bytes --]

            * config/m68k/m68k.c (output_move_himode, output_move_qimode):
            Replace code for non-CONST_INT constants with gcc_unreachable.
            * config/m68k/m68k.md (cbranchdi): Don't generate individual
            compare and test.
            (CMPMODE): New mode_iterator.
            (cbranchsi4, cbranchqi4, cbranchhi4): Replace expanders with
            cbranch<mode>4.
            (cstoresi4, cstoreqi4, cstorehi4): Replace expanders with
            cstore<mode>4.
            (cmp<mode>_68881): Remove 'F' constraint from first comparison
            operand.
            (bit test insns patterns): Use nonimmediate_operand, not
            register_operand, for source operands that allow memory in
            their constraints.
            (divmodsi4, udivmodsi4, divmodhi4 and related unnamed patterns):
            Use register_operand, not nonimmediate_operand, for the
            destinations.
            (DBCC): New mode_iterator.
            (dbcc peepholes): Use it to reduce duplication.
            (trap): Use const_true_rtx, not const1_rtx.
            * config/m68k/predicates.md (m68k_comparison_operand): Renamed
            from m68k_subword_comparison_operand and changed to handle
            SImode.

diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 1030dfa5957..4f3503b9118 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -3072,7 +3072,7 @@ output_move_simode (rtx *operands)
 const char *
 output_move_himode (rtx *operands)
 {
- if (GET_CODE (operands[1]) == CONST_INT)
+  if (GET_CODE (operands[1]) == CONST_INT)
     {
       if (operands[1] == const0_rtx
 	  && (DATA_REG_P (operands[0])
@@ -3094,7 +3094,7 @@ output_move_himode (rtx *operands)
 	return "move%.w %1,%0";
     }
   else if (CONSTANT_P (operands[1]))
-    return "move%.l %1,%0";
+    gcc_unreachable ();
   return "move%.w %1,%0";
 }
 
@@ -3103,7 +3103,7 @@ output_move_qimode (rtx *operands)
 {
   /* 68k family always modifies the stack pointer by at least 2, even for
      byte pushes.  The 5200 (ColdFire) does not do this.  */
-  
+
   /* This case is generated by pushqi1 pattern now.  */
   gcc_assert (!(GET_CODE (operands[0]) == MEM
 		&& GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
@@ -3134,7 +3134,7 @@ output_move_qimode (rtx *operands)
   if (operands[1] == const0_rtx && ADDRESS_REG_P (operands[0]))
     return "sub%.l %0,%0";
   if (GET_CODE (operands[1]) != CONST_INT && CONSTANT_P (operands[1]))
-    return "move%.l %1,%0";
+    gcc_unreachable ();
   /* 68k family (including the 5200 ColdFire) does not support byte moves to
      from address registers.  */
   if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 31e8767e7e3..e60978150d1 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -456,19 +456,14 @@
 	  (match_operand:DI 3 "general_operand")]))]
   ""
 {
-  if (operands[3] == const0_rtx)
-    emit_insn (gen_tstdi (operands[2]));
-  else
-    emit_insn (gen_cmpdi (operands[2], operands[3]));
-  operands[2] = cc0_rtx;
-  operands[3] = const0_rtx;
 })
 
+(define_mode_iterator CMPMODE [QI HI SI])
 
-(define_expand "cbranchsi4"
+(define_expand "cbranch<mode>4"
   [(set (cc0)
-	(compare (match_operand:SI 1 "nonimmediate_operand" "")
-		 (match_operand:SI 2 "general_operand" "")))
+	(compare (match_operand:CMPMODE 1 "nonimmediate_operand" "")
+		 (match_operand:CMPMODE 2 "m68k_comparison_operand" "")))
    (set (pc)
 	(if_then_else (match_operator 0 "ordered_comparison_operator"
                        [(cc0) (const_int 0)])
@@ -477,17 +472,16 @@
   ""
   "")
 
-(define_expand "cstoresi4"
+(define_expand "cstore<mode>4"
   [(set (cc0)
-	(compare (match_operand:SI 2 "nonimmediate_operand" "")
-		 (match_operand:SI 3 "general_operand" "")))
+	(compare (match_operand:CMPMODE 2 "nonimmediate_operand" "")
+		 (match_operand:CMPMODE 3 "m68k_comparison_operand" "")))
    (set (match_operand:QI 0 "register_operand")
 	(match_operator:QI 1 "ordered_comparison_operator"
          [(cc0) (const_int 0)]))]
   ""
   "")
 
-
 ;; A composite of the cmp, cmpa, cmpi & cmpm m68000 op codes.
 ;;
 ;; In theory we ought to be able to use some 'S' constraints and
@@ -536,28 +530,6 @@
 }
   [(set_attr "type" "cmp_l")])
 
-(define_expand "cbranchhi4"
-  [(set (cc0)
-	(compare (match_operand:HI 1 "nonimmediate_operand" "")
-		 (match_operand:HI 2 "m68k_subword_comparison_operand" "")))
-   (set (pc)
-	(if_then_else (match_operator 0 "ordered_comparison_operator"
-                       [(cc0) (const_int 0)])
-		      (label_ref (match_operand 3 ""))
-		      (pc)))]
-  ""
-  "")
-
-(define_expand "cstorehi4"
-  [(set (cc0)
-	(compare (match_operand:HI 2 "nonimmediate_operand" "")
-		 (match_operand:HI 3 "m68k_subword_comparison_operand" "")))
-   (set (match_operand:QI 0 "register_operand")
-	(match_operator:QI 1 "ordered_comparison_operator"
-         [(cc0) (const_int 0)]))]
-  ""
-  "")
-
 (define_insn ""
   [(set (cc0)
         (compare (match_operand:HI 0 "nonimmediate_operand" "rnm,d,n,m,>")
@@ -575,28 +547,6 @@
   return "cmp%.w %d1,%d0";
 })
 
-(define_expand "cbranchqi4"
-  [(set (cc0)
-	(compare (match_operand:QI 1 "nonimmediate_operand" "")
-		 (match_operand:QI 2 "m68k_subword_comparison_operand" "")))
-   (set (pc)
-	(if_then_else (match_operator 0 "ordered_comparison_operator"
-                       [(cc0) (const_int 0)])
-		      (label_ref (match_operand 3 ""))
-		      (pc)))]
-  ""
-  "")
-
-(define_expand "cstoreqi4"
-  [(set (cc0)
-	(compare (match_operand:QI 2 "nonimmediate_operand" "")
-		 (match_operand:QI 3 "m68k_subword_comparison_operand" "")))
-   (set (match_operand:QI 0 "register_operand")
-	(match_operator:QI 1 "ordered_comparison_operator"
-         [(cc0) (const_int 0)]))]
-  ""
-  "")
-
 (define_insn ""
   [(set (cc0)
         (compare (match_operand:QI 0 "nonimmediate_operand" "dn,dm,>")
@@ -626,6 +576,8 @@
   "TARGET_HARD_FLOAT"
   "")
 
+;; ??? 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" "")
@@ -639,7 +591,7 @@
 
 (define_insn "*cmp<mode>_68881"
   [(set (cc0)
-	(compare (match_operand:FP 0 "fp_src_operand" "f,f,<FP:dreg>mF")
+	(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")))]
   "TARGET_68881
    && (register_operand (operands[0], <MODE>mode)
@@ -763,7 +715,7 @@
 (define_insn ""
   [(set
     (cc0)
-    (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "do")
+    (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)))]
@@ -787,7 +739,7 @@
 (define_insn ""
   [(set
     (cc0)
-    (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "dQ")
+    (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)))]
@@ -3483,19 +3435,19 @@
 
 (define_expand "divmodsi4"
   [(parallel
-    [(set (match_operand:SI 0 "nonimmediate_operand" "")
+    [(set (match_operand:SI 0 "register_operand" "")
           (div:SI (match_operand:SI 1 "general_operand" "")
                   (match_operand:SI 2 "general_src_operand" "")))
-     (set (match_operand:SI 3 "nonimmediate_operand" "")
+     (set (match_operand:SI 3 "register_operand" "")
           (mod:SI (match_dup 1) (match_dup 2)))])]
   "TARGET_68020 || TARGET_CF_HWDIV"
   "")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
+  [(set (match_operand:SI 0 "register_operand" "=d")
 	(div:SI (match_operand:SI 1 "general_operand" "0")
 		(match_operand:SI 2 "general_src_operand" "d<Q>U")))
-   (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
+   (set (match_operand:SI 3 "register_operand" "=&d")
 	(mod:SI (match_dup 1) (match_dup 2)))]
   "TARGET_CF_HWDIV"
 {
@@ -3510,10 +3462,10 @@
    (set_attr "opy" "2")])
 
 (define_insn ""
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
+  [(set (match_operand:SI 0 "register_operand" "=d")
 	(div:SI (match_operand:SI 1 "general_operand" "0")
 		(match_operand:SI 2 "general_src_operand" "dmSTK")))
-   (set (match_operand:SI 3 "nonimmediate_operand" "=d")
+   (set (match_operand:SI 3 "register_operand" "=d")
 	(mod:SI (match_dup 1) (match_dup 2)))]
   "TARGET_68020"
 {
@@ -3525,19 +3477,19 @@
 
 (define_expand "udivmodsi4"
   [(parallel
-    [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
+    [(set (match_operand:SI 0 "register_operand" "=d")
           (udiv:SI (match_operand:SI 1 "general_operand" "0")
                    (match_operand:SI 2 "general_src_operand" "dmSTK")))
-     (set (match_operand:SI 3 "nonimmediate_operand" "=d")
+     (set (match_operand:SI 3 "register_operand" "=d")
           (umod:SI (match_dup 1) (match_dup 2)))])]
   "TARGET_68020 || TARGET_CF_HWDIV"
   "")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
+  [(set (match_operand:SI 0 "register_operand" "=d")
 	(udiv:SI (match_operand:SI 1 "general_operand" "0")
 		 (match_operand:SI 2 "general_src_operand" "d<Q>U")))
-   (set (match_operand:SI 3 "nonimmediate_operand" "=&d")
+   (set (match_operand:SI 3 "register_operand" "=&d")
 	(umod:SI (match_dup 1) (match_dup 2)))]
   "TARGET_CF_HWDIV"
 {
@@ -3552,10 +3504,10 @@
    (set_attr "opy" "2")])
 
 (define_insn ""
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
+  [(set (match_operand:SI 0 "register_operand" "=d")
 	(udiv:SI (match_operand:SI 1 "general_operand" "0")
 		 (match_operand:SI 2 "general_src_operand" "dmSTK")))
-   (set (match_operand:SI 3 "nonimmediate_operand" "=d")
+   (set (match_operand:SI 3 "register_operand" "=d")
 	(umod:SI (match_dup 1) (match_dup 2)))]
   "TARGET_68020 && !TARGET_COLDFIRE"
 {
@@ -3566,10 +3518,10 @@
 })
 
 (define_insn "divmodhi4"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
+  [(set (match_operand:HI 0 "register_operand" "=d")
 	(div:HI (match_operand:HI 1 "general_operand" "0")
 		(match_operand:HI 2 "general_src_operand" "dmSKT")))
-   (set (match_operand:HI 3 "nonimmediate_operand" "=d")
+   (set (match_operand:HI 3 "register_operand" "=d")
 	(mod:HI (match_dup 1) (match_dup 2)))]
   "!TARGET_COLDFIRE || TARGET_CF_HWDIV"
 {
@@ -3590,7 +3542,7 @@
   [(set (match_operand:HI 0 "nonimmediate_operand" "=d")
 	(udiv:HI (match_operand:HI 1 "general_operand" "0")
 		 (match_operand:HI 2 "general_src_operand" "dmSKT")))
-   (set (match_operand:HI 3 "nonimmediate_operand" "=d")
+   (set (match_operand:HI 3 "register_operand" "=d")
 	(umod:HI (match_dup 1) (match_dup 2)))]
   "!TARGET_COLDFIRE || TARGET_CF_HWDIV"
 {
@@ -7379,6 +7331,7 @@
 ;;
 ;; Which moves the jCC condition outside the inner loop for free.
 ;;
+(define_mode_iterator DBCC [HI SI])
 
 (define_peephole
   [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
@@ -7388,13 +7341,13 @@
    (parallel
     [(set (pc)
 	  (if_then_else
-	    (ne (match_operand:HI 0 "register_operand" "")
+	    (ne (match_operand:DBCC 0 "register_operand" "")
 	        (const_int 0))
 	    (label_ref (match_operand 1 "" ""))
 	    (pc)))
      (set (match_dup 0)
-	  (plus:HI (match_dup 0)
-		   (const_int -1)))])]
+	  (plus:DBCC (match_dup 0)
+		     (const_int -1)))])]
   "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
 {
   CC_STATUS_INIT;
@@ -7410,66 +7363,20 @@
    (parallel
     [(set (pc)
 	  (if_then_else
-	    (ne (match_operand:SI 0 "register_operand" "")
+	    (ge (plus:DBCC (match_operand:DBCC 0 "register_operand" "")
+			   (const_int -1))
 	        (const_int 0))
 	    (label_ref (match_operand 1 "" ""))
 	    (pc)))
      (set (match_dup 0)
-	  (plus:SI (match_dup 0)
-		   (const_int -1)))])]
+	  (plus:DBCC (match_dup 0)
+		     (const_int -1)))])]
   "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
 {
   CC_STATUS_INIT;
   output_dbcc_and_branch (operands);
   return "";
 })
-
-(define_peephole
-  [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
-                             [(cc0) (const_int 0)])
-                           (label_ref (match_operand 2 "" ""))
-                           (pc)))
-   (parallel
-    [(set (pc)
-	  (if_then_else
-	    (ge (plus:HI (match_operand:HI 0 "register_operand" "")
-		         (const_int -1))
-	        (const_int 0))
-	    (label_ref (match_operand 1 "" ""))
-	    (pc)))
-     (set (match_dup 0)
-	  (plus:HI (match_dup 0)
-		   (const_int -1)))])]
-  "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
-{
-  CC_STATUS_INIT;
-  output_dbcc_and_branch (operands);
-  return "";
-})
-
-(define_peephole
-  [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p"
-                             [(cc0) (const_int 0)])
-                           (label_ref (match_operand 2 "" ""))
-                           (pc)))
-   (parallel
-    [(set (pc)
-	  (if_then_else
-	    (ge (plus:SI (match_operand:SI 0 "register_operand" "")
-		         (const_int -1))
-	        (const_int 0))
-	    (label_ref (match_operand 1 "" ""))
-	    (pc)))
-     (set (match_dup 0)
-	  (plus:SI (match_dup 0)
-		   (const_int -1)))])]
-  "!TARGET_COLDFIRE && DATA_REG_P (operands[0]) && ! flags_in_68881 ()"
-{
-  CC_STATUS_INIT;
-  output_dbcc_and_branch (operands);
-  return "";
-})
-
 \f
 (define_insn "extendsfxf2"
   [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f")
@@ -7583,13 +7490,17 @@
     return "fcos%.<FP:prec> %1,%0";
 })
 
-;; Unconditional traps are assumed to have (const_int 1) for the condition.
+;; Unconditional traps are assumed to have const_true_rtx for the condition.
 (define_insn "trap"
-  [(trap_if (const_int 1) (const_int 7))]
+  [(trap_if (const_int -1) (const_int 7))]
   ""
   "trap #7"
   [(set_attr "type" "trap")])
 
+;; ??? Our trap instruction uses constant 7 for operand 3, which is
+;; 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"
   [(trap_if (match_operator 0 "ordered_comparison_operator"
 			    [(cc0) (const_int 0)])
diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md
index ad297883f85..4cc3d3dc1bd 100644
--- a/gcc/config/m68k/predicates.md
+++ b/gcc/config/m68k/predicates.md
@@ -210,10 +210,10 @@
   (and (match_code "const_int")
        (match_test "op == const1_rtx")))
 
-;; A valid operand for a HImode or QImode conditional operation.
-;; ColdFire has tst patterns, but not cmp patterns.
-(define_predicate "m68k_subword_comparison_operand"
-  (if_then_else (match_test "TARGET_COLDFIRE")
+;; A valid operand for a conditional operation.
+;; ColdFire has tst patterns for HImode and QImode, but not cmp patterns.
+(define_predicate "m68k_comparison_operand"
+  (if_then_else (match_test "TARGET_COLDFIRE && mode != SImode")
                 (and (match_code "const_int")
 		     (match_test "op == const0_rtx"))
 		(match_operand 0 "general_src_operand")))

^ permalink raw reply	[flat|nested] 87+ messages in thread

* [PATCH 2/4] The main m68k cc0 conversion
  2019-11-13 13:08 [PATCH 0/4] Eliminate cc0 from m68k Bernd Schmidt
  2019-11-13 13:09 ` [PATCH 1/4] Preliminary m68k patches Bernd Schmidt
@ 2019-11-13 13:13 ` Bernd Schmidt
  2019-11-13 13:29   ` Bernd Schmidt
  2019-11-13 13:21 ` [PATCH 3/4] Set costs for jumps in combine Bernd Schmidt
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-13 13:13 UTC (permalink / raw)
  To: GCC Patches

This achieves the conversion by using combined cbranch/cstore patterns,
and using a mechanism similar to the cc_status tracking to elide certain
comparisons.  Unlike cc_status, this is opt-in and requires a
flags_valid attribute to be set for suitable instructions.  Due to lack
of test hardware, this conversion is omitted for a number of coldfire
patterns as opposed to normal m68k.

For DImode comparisons, scc_di and beq0_di/bne0_di patterns already
existed and are reused.  The bgt0_di/ble0_di patterns are replaced with
expander code to test just the high word, along with some smarts in
m68k_find_flags_value.


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* [PATCH 3/4] Set costs for jumps in combine
  2019-11-13 13:08 [PATCH 0/4] Eliminate cc0 from m68k Bernd Schmidt
  2019-11-13 13:09 ` [PATCH 1/4] Preliminary m68k patches Bernd Schmidt
  2019-11-13 13:13 ` [PATCH 2/4] The main m68k cc0 conversion Bernd Schmidt
@ 2019-11-13 13:21 ` Bernd Schmidt
  2019-11-13 16:26   ` Segher Boessenkool
  2019-11-13 13:24 ` [PATCH 4/4] Fix autoinc cbranch Bernd Schmidt
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-13 13:21 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 564 bytes --]

The combiner is somewhat strange about how it uses costs. If any of the
insns involved in a comparison have a cost of 0, it does not verify that
the substitution is cheaper. Also, it does not compute costs for jump
insns, so they are always set to zero. As a consequence, any possible
substitution is performed if a combination into a jump is possible,
which turns out isn't really desirable on m68k with cbranch patterns.

This patch simply removes a test for NONJUMP_INSN_P. Bootstrapped and
tested on the gcc135 machine (powerpc64le-unknown-linux-gnu).


Bernd

[-- Attachment #2: m68k-3.diff --]
[-- Type: text/x-patch, Size: 612 bytes --]

	* combine.c (combine_instructions): Record costs for jumps.

diff --git a/gcc/combine.c b/gcc/combine.c
index 857ea30dafd..9446d2769ab 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1234,8 +1234,7 @@ combine_instructions (rtx_insn *f, unsigned int nregs)
 						    insn);
 
 	    /* Record the current insn_cost of this instruction.  */
-	    if (NONJUMP_INSN_P (insn))
-	      INSN_COST (insn) = insn_cost (insn, optimize_this_for_speed_p);
+	    INSN_COST (insn) = insn_cost (insn, optimize_this_for_speed_p);
 	    if (dump_file)
 	      {
 		fprintf (dump_file, "insn_cost %d for ", INSN_COST (insn));

^ permalink raw reply	[flat|nested] 87+ messages in thread

* [PATCH 4/4] Fix autoinc cbranch
  2019-11-13 13:08 [PATCH 0/4] Eliminate cc0 from m68k Bernd Schmidt
                   ` (2 preceding siblings ...)
  2019-11-13 13:21 ` [PATCH 3/4] Set costs for jumps in combine Bernd Schmidt
@ 2019-11-13 13:24 ` Bernd Schmidt
  2019-11-19  0:36   ` Segher Boessenkool
  2019-11-13 18:58 ` [PATCH 0/4] Eliminate cc0 from m68k Segher Boessenkool
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-13 13:24 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1052 bytes --]

After the m68k cc0 conversion, there is one code quality regression that
I can see: we no longer generate autoinc addressing modes in
comparisons. This is because the parts of the compiler that generate
autoinc are unwilling to substitute into jumps.

If you look at the code in reload, you'll see that it's careful around
jumps at find_reload time, and the code to perform autoinc reloads does
try to put all the extra code before the instruction. LRA seems to have
copied most of that code.
Also, in the former cc0 reality, a compare wasn't really any different
from a jump on m68k: we can't have a reload after the instruction in
either case. Any kind of move or arithmetic would clobber the flags.

That leads me to believe that there is no issue with autoinc in jumps,
hence this patch. Bootstrapped and tested on the gcc135 machine
(powerpc64le-unknown-linux-gnu). I don't really expect this to get
approved; alternatively I could write some peepholes which would
generate the same code as long as register pressure doesn't get too high.


Bernd

[-- Attachment #2: m68k-4.diff --]
[-- Type: text/x-patch, Size: 2006 bytes --]

	* auto-inc-dec.c (merge_in_block): Allow jumps.
	* combine.c (can_combine_p): Allow jumps in autoinc.

diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c
index bdb6efa..6dab135 100644
--- a/gcc/auto-inc-dec.c
+++ b/gcc/auto-inc-dec.c
@@ -1441,10 +1441,11 @@ merge_in_block (int max_reg, basic_block bb)
          continue;
        }
 
-      /* This continue is deliberate.  We do not want the uses of the
-        jump put into reg_next_use because it is not considered safe to
-        combine a preincrement with a jump.  */
-      if (JUMP_P (insn))
+      /* We used to skip jump insns, but both reload and LRA seem to
+        take precautions not to perform autoinc reloads after a jump or
+        a comparison.  Allow them for regular autoinc only (for test
+        coverage reasons more than anything).  */
+      if ((HAVE_PRE_MODIFY_REG || HAVE_POST_MODIFY_REG) && JUMP_P (insn))
        continue;
 
       if (dump_file)
diff --git a/gcc/combine.c b/gcc/combine.c
index 857ea30..e9e1464 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -2119,15 +2118,12 @@ can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED,
 
   /* If INSN contains an autoincrement or autodecrement, make sure that
      register is not used between there and I3, and not already used in
-     I3 either.  Neither must it be used in PRED or SUCC, if they exist.
-     Also insist that I3 not be a jump; if it were one
-     and the incremented register were spilled, we would lose.  */
+     I3 either.  Neither must it be used in PRED or SUCC, if they exist.  */
 
   if (AUTO_INC_DEC)
     for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
       if (REG_NOTE_KIND (link) == REG_INC
-         && (JUMP_P (i3)
-             || reg_used_between_p (XEXP (link, 0), insn, i3)
+         && (reg_used_between_p (XEXP (link, 0), insn, i3)
              || (pred != NULL_RTX
                  && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (pred)))
              || (pred2 != NULL_RTX

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-13 13:13 ` [PATCH 2/4] The main m68k cc0 conversion Bernd Schmidt
@ 2019-11-13 13:29   ` Bernd Schmidt
  2019-11-17 18:00     ` Jeff Law
  2019-11-23 17:36     ` John Paul Adrian Glaubitz
  0 siblings, 2 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-13 13:29 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 30 bytes --]

Once more with patch.


Bernd

[-- Attachment #2: m68k-2.diff --]
[-- Type: text/x-patch, Size: 169719 bytes --]

            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);
 \f
 /* 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);
 }
 \f
-/* 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;
 }
+\f
+/* 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;
 }
 \f
 /* 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";
 }
-\f
-/* 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 ();
     }
 }
 \f
@@ -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
 
-\f
-/* 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)
 \f
 /* 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;
 })
 \f
-;; 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")])
-
-\f
-;; 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")])
-\f
-;; 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);
-})
-
-\f
-;; 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")))])
 \f
 ;; 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")])
 \f
 ;; 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")])
 \f
 ;; 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")])
 \f
 ;; 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")])
 \f
 ;; 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")])
 \f
 ;; 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}";
-})
-\f
-;; 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}";
-})
-\f
-(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";
-})
-\f
-;; 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")])
-\f
-;; 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}";
+})
+\f
+(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]);
+})
 \f
 ;; 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 "";
 })
 \f
@@ -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));
 }
 \f
-/* 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)));
-}
-\f
 /* 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);
 }
 \f
-/* 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;
-}
-\f
 /* Replace any occurrence of FROM in X with TO.  The function does
    not enter into CONST_DOUBLE for the replace.
 

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 3/4] Set costs for jumps in combine
  2019-11-13 13:21 ` [PATCH 3/4] Set costs for jumps in combine Bernd Schmidt
@ 2019-11-13 16:26   ` Segher Boessenkool
  2019-11-21 13:53     ` Bernd Schmidt
  0 siblings, 1 reply; 87+ messages in thread
From: Segher Boessenkool @ 2019-11-13 16:26 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

Hi!

On Wed, Nov 13, 2019 at 02:13:48PM +0100, Bernd Schmidt wrote:
> The combiner is somewhat strange about how it uses costs. If any of the
> insns involved in a comparison have a cost of 0, it does not verify that
> the substitution is cheaper.

"Cost 0" means "unknown cost".  This isn't just combine, it is a property
of insn_cost (and insn_rtx_cost before it).  It does make it impossible
for combine to deal with actual zero cost things.

> Also, it does not compute costs for jump
> insns, so they are always set to zero. As a consequence, any possible
> substitution is performed if a combination into a jump is possible,
> which turns out isn't really desirable on m68k with cbranch patterns.
> 
> This patch simply removes a test for NONJUMP_INSN_P. Bootstrapped and
> tested on the gcc135 machine (powerpc64le-unknown-linux-gnu).

I wonder why that test was there.  It was added in r84513, which is where
insn_rtx_cost was made from combine_insn_cost, which didn't have that
non-jump thing yet.

It is still stage 1, so we'll find out if any target breaks I guess.
Okay for trunk.  Thanks!


Segher

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-13 13:08 [PATCH 0/4] Eliminate cc0 from m68k Bernd Schmidt
                   ` (3 preceding siblings ...)
  2019-11-13 13:24 ` [PATCH 4/4] Fix autoinc cbranch Bernd Schmidt
@ 2019-11-13 18:58 ` Segher Boessenkool
  2019-11-13 19:07   ` Bernd Schmidt
  2019-11-13 19:41 ` Jeff Law
  2019-11-15 13:49 ` Andreas Schwab
  6 siblings, 1 reply; 87+ messages in thread
From: Segher Boessenkool @ 2019-11-13 18:58 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

On Wed, Nov 13, 2019 at 02:04:59PM +0100, Bernd Schmidt wrote:
> This is a set of patches to convert m68k so that it no longer uses cc0.

I tried this out with a kernel build (just the defconfig).  First problem
was patch 4 doesn't apply, it has white-space damage.  It's small, I fixed
that up manually.  But then I hit

during RTL pass: jump2
/home/segher/src/kernel/fs/binfmt_elf.c: In function 'elf_core_dump':
/home/segher/src/kernel/fs/binfmt_elf.c:2409:1: internal compiler error: in patch_jump_insn, at cfgrtl.c:1290
0x102c3c2f patch_jump_insn
        /home/segher/src/gcc/gcc/cfgrtl.c:1290
0x102c3df3 redirect_branch_edge
        /home/segher/src/gcc/gcc/cfgrtl.c:1317
0x102c442b rtl_redirect_edge_and_branch
        /home/segher/src/gcc/gcc/cfgrtl.c:1450
0x102ad04f redirect_edge_and_branch(edge_def*, basic_block_def*)
        /home/segher/src/gcc/gcc/cfghooks.c:373
0x10dbb517 try_forward_edges
        /home/segher/src/gcc/gcc/cfgcleanup.c:562
0x10dbb517 try_optimize_cfg
        /home/segher/src/gcc/gcc/cfgcleanup.c:2960
0x10dbb517 cleanup_cfg(int)
        /home/segher/src/gcc/gcc/cfgcleanup.c:3174
0x10dbd41f execute
        /home/segher/src/gcc/gcc/cfgcleanup.c:3353

Can you reproduce that?


Segher

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-13 18:58 ` [PATCH 0/4] Eliminate cc0 from m68k Segher Boessenkool
@ 2019-11-13 19:07   ` Bernd Schmidt
  2019-11-13 19:25     ` Segher Boessenkool
  2019-11-15 13:48     ` John Paul Adrian Glaubitz
  0 siblings, 2 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-13 19:07 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 855 bytes --]

On 11/13/19 7:16 PM, Segher Boessenkool wrote:
> I tried this out with a kernel build (just the defconfig).

> during RTL pass: jump2
> /home/segher/src/kernel/fs/binfmt_elf.c: In function 'elf_core_dump':
> /home/segher/src/kernel/fs/binfmt_elf.c:2409:1: internal compiler error: in patch_jump_insn, at cfgrtl.c:1290

> Can you reproduce that?

Yes. It's actually an issue I spotted at one point, but I thought to
myself "I'll just leave it, I want to make the minimum amount of
changes". Should have thought harder.

The constraints for comparison patterns in m68k.md allow constants as
the first operand of a comparison. They also use nonimmediate_operand.
Hence, the internal error you saw when something tries to rerecognize
the instruction.

The following should fix it, but it's only very lightly tested so far.
I'll merge it into patch 2.


Bernd

[-- Attachment #2: m68k-5.diff --]
[-- Type: text/x-patch, Size: 781 bytes --]

	* config/m68k/m68k.md (cmp1_constraints): Don't allow constants.

diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index bb46e5880e2..56685db0c72 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -488,7 +488,7 @@
 ;; and operand predicates.  So to be safe, just don't allow the PC-rel
 
 (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 cmp1_constraints [(QI "dn,dm,>") (HI "rnm,d,n,m,>") (SI "r,r,r,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

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-13 19:07   ` Bernd Schmidt
@ 2019-11-13 19:25     ` Segher Boessenkool
  2019-11-15 13:48     ` John Paul Adrian Glaubitz
  1 sibling, 0 replies; 87+ messages in thread
From: Segher Boessenkool @ 2019-11-13 19:25 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

On Wed, Nov 13, 2019 at 07:57:58PM +0100, Bernd Schmidt wrote:
> On 11/13/19 7:16 PM, Segher Boessenkool wrote:
> > I tried this out with a kernel build (just the defconfig).
> 
> > during RTL pass: jump2
> > /home/segher/src/kernel/fs/binfmt_elf.c: In function 'elf_core_dump':
> > /home/segher/src/kernel/fs/binfmt_elf.c:2409:1: internal compiler error: in patch_jump_insn, at cfgrtl.c:1290
> 
> > Can you reproduce that?
> 
> Yes. It's actually an issue I spotted at one point, but I thought to
> myself "I'll just leave it, I want to make the minimum amount of
> changes". Should have thought harder.
> 
> The constraints for comparison patterns in m68k.md allow constants as
> the first operand of a comparison. They also use nonimmediate_operand.
> Hence, the internal error you saw when something tries to rerecognize
> the instruction.
> 
> The following should fix it, but it's only very lightly tested so far.
> I'll merge it into patch 2.

It works on the kernel build, at least.  No idea if this *runs*, I just
built it ;-)

Sizes, R0 is trunk, R1 is with your patches:

                    R0        R1
        m68k   3720557   3721245

(that is 100.018%, looks great!)


Segher

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-13 13:08 [PATCH 0/4] Eliminate cc0 from m68k Bernd Schmidt
                   ` (4 preceding siblings ...)
  2019-11-13 18:58 ` [PATCH 0/4] Eliminate cc0 from m68k Segher Boessenkool
@ 2019-11-13 19:41 ` Jeff Law
  2019-11-14 15:00   ` Richard Henderson
  2019-11-15 13:49 ` Andreas Schwab
  6 siblings, 1 reply; 87+ messages in thread
From: Jeff Law @ 2019-11-13 19:41 UTC (permalink / raw)
  To: Bernd Schmidt, GCC Patches

On 11/13/19 6:04 AM, Bernd Schmidt wrote:
> This is a set of patches to convert m68k so that it no longer uses cc0.
> The approach is to combine cc0 setter/user pairs into cbranch and cstore
> patterns. It does not expose the flag register directly. Since m68k is a
> target that is not under active development, and probably receives very
> limited testing, I felt it was important to make it generate as close to
> the same code as previously. Also, given that the target clobbers the
> flags for pretty much every move, it seems unlikely that there's much
> value to be had from anything more complex. Trying to model every
> instruction's effect on the flags would be too error-prone for not
> nearly enough gain.
I tend to agree.  My only worry would be introducing a new way to deal
with cc0.  But I'll certainly look at the changes with an open mind.

It might play well with ideas I had while looking at the H8 port which
has a very similar model.


> 
> The cc0 machinery allows for eliminating unnecessary comparisons by
> examining the effect instructions have on the flags registers. I have
> replicated that mechanism with a relatively modest amount of code based
> on a final_postscan_insn hook, but it is now opt-in: an instruction
> pattern can set the "flags_valid" attribute to a number of possible
> values to indicate what effect it has. That should be more reliable (try
> git log m68k.md to see recent sprinkling of CC_STATUS_INIT to squash
> bugs with the previous mechanism).
Yea, sounds like a reimplementation of the tst elimination bits, but
buried in the backend.  Given the choice of dropping the port or burying
this kind of stuff in there, I'd lean towards accepting the latter.


> We can remember either values where the flags indicate a comparison
> against zero (after practically all arithmetic and move insns), or
> alternatively record two comparison operands to eliminate identical
> compares. I stopped adding optimizations once I found it hard to find
> any meaningful differences in generated code. In particular, the
> m68k.exp tests which verify that these optimizations are performed all
> still pass.
Yea.  One of the things I was pondering was dropping many/most of the
combiner patterns then only adding those back which were clearly still
important.  I have a strong suspicion we have *many* unnecessary
patterns.  Of course finding those may be more work than its worth.


> 
> Testing was done with the qemu-system-m68k/debian combination. I do not
> have access to Coldfire hardware, and I tried to be somewhat
> conservative, for example by not adding "flags_valid" everywhere it
> would probably be possible. For someone with access to the hardware, it
> should be trivial to add such attributes and test that everything still
> works.
I'm happy to add your patch to my tester.  It'll verify the compiler
bootstraps and can build glibc & the kernel.

Jeff

ps.  On a more personal note -- good to hear from you Bernd.  I hope
things are going well.

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 1/4] Preliminary m68k patches
  2019-11-13 13:09 ` [PATCH 1/4] Preliminary m68k patches Bernd Schmidt
@ 2019-11-13 20:37   ` Jeff Law
  2019-11-14 12:25     ` Bernd Schmidt
  0 siblings, 1 reply; 87+ messages in thread
From: Jeff Law @ 2019-11-13 20:37 UTC (permalink / raw)
  To: Bernd Schmidt, GCC Patches

On 11/13/19 6:08 AM, Bernd Schmidt wrote:
> This tidies up a few spots in the m68k backend in preparation for the
> large patch to follow.  This is purely for review purposes: this patch
> has not been tested independently, and will be committed together with
> the following one.
> 
> Noteworthy changes:
> 
> Some patterns and peepholes were unified through mode iterators.  The
> m68k_subword_comparison_operator predicate was adapted to also work with
> SImode.
> 
> There are already scc_di patterns, so there is no need to generate a cc0
> set/use pair in cstoredi.
> 
> Without HAVE_cc0, combine sometimes substitutes a stack push into the
> destination of a divmod instruction, and then gets confused because it
> doesn't seem to expect it in a PARALLEL.  Since the instruction only
> works on registers anyway, use register_operand.
> 
> There are patterns that use register_operand with "do" constraints which
> allow memory. This works at reload time, but the instruction can not be
> rerecognized later on.  This becomes a problem if such operands occur in
> a jump instruction, as subsequent passes will try to redirect branches
> and thus attempt to rerecognize the pattern.
> 
> movqi/movhi do not accept constants that are not CONST_INT.  The code to
> output them would not set flags correctly and was changed to
> gcc_unreachable.
> 
> Comments were added to some patterns which are not being generated due
> to incorrect tests/predicates. Fixing these is out of scope for this
> work, but the problems are at least documented.
> 
> All the passes working on conditional traps seem to assume
> const_true_rtx is used for unconditional ones, rather than const1_rtx.
> 
> 
> Bernd
> 
> 
> m68k-1.diff
> 
>             * config/m68k/m68k.c (output_move_himode, output_move_qimode):
>             Replace code for non-CONST_INT constants with gcc_unreachable.
>             * config/m68k/m68k.md (cbranchdi): Don't generate individual
>             compare and test.
>             (CMPMODE): New mode_iterator.
>             (cbranchsi4, cbranchqi4, cbranchhi4): Replace expanders with
>             cbranch<mode>4.
>             (cstoresi4, cstoreqi4, cstorehi4): Replace expanders with
>             cstore<mode>4.
>             (cmp<mode>_68881): Remove 'F' constraint from first comparison
>             operand.
>             (bit test insns patterns): Use nonimmediate_operand, not
>             register_operand, for source operands that allow memory in
>             their constraints.
>             (divmodsi4, udivmodsi4, divmodhi4 and related unnamed patterns):
>             Use register_operand, not nonimmediate_operand, for the
>             destinations.
>             (DBCC): New mode_iterator.
>             (dbcc peepholes): Use it to reduce duplication.
>             (trap): Use const_true_rtx, not const1_rtx.
>             * config/m68k/predicates.md (m68k_comparison_operand): Renamed
>             from m68k_subword_comparison_operand and changed to handle
>             SImode.
OK.  I'd actually recommend this go ahead and get installed.  My tester
will bootstrap it overnight.

Jeff

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 1/4] Preliminary m68k patches
  2019-11-13 20:37   ` Jeff Law
@ 2019-11-14 12:25     ` Bernd Schmidt
  2019-11-17 18:27       ` Jeff Law
  2019-11-18 16:52       ` Jeff Law
  0 siblings, 2 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-14 12:25 UTC (permalink / raw)
  To: Jeff Law, GCC Patches

On 11/13/19 9:03 PM, Jeff Law wrote:
> OK.  I'd actually recommend this go ahead and get installed.  My tester
> will bootstrap it overnight.

Alright, let me know how that turns out. What kind of machine do you
have for that?


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-13 19:41 ` Jeff Law
@ 2019-11-14 15:00   ` Richard Henderson
  0 siblings, 0 replies; 87+ messages in thread
From: Richard Henderson @ 2019-11-14 15:00 UTC (permalink / raw)
  To: Jeff Law, Bernd Schmidt, GCC Patches

On 11/13/19 8:35 PM, Jeff Law wrote:
> On 11/13/19 6:04 AM, Bernd Schmidt wrote:
>> The cc0 machinery allows for eliminating unnecessary comparisons by
>> examining the effect instructions have on the flags registers. I have
>> replicated that mechanism with a relatively modest amount of code based
>> on a final_postscan_insn hook, but it is now opt-in: an instruction
>> pattern can set the "flags_valid" attribute to a number of possible
>> values to indicate what effect it has. That should be more reliable (try
>> git log m68k.md to see recent sprinkling of CC_STATUS_INIT to squash
>> bugs with the previous mechanism).
> Yea, sounds like a reimplementation of the tst elimination bits, but
> buried in the backend.  Given the choice of dropping the port or burying
> this kind of stuff in there, I'd lean towards accepting the latter.

Indeed.  Even if we wanted an eventual transition to the tst elimination bits,
this is a better starting place than from cc0.


r~

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-13 19:07   ` Bernd Schmidt
  2019-11-13 19:25     ` Segher Boessenkool
@ 2019-11-15 13:48     ` John Paul Adrian Glaubitz
  2019-11-15 14:36       ` John Paul Adrian Glaubitz
  1 sibling, 1 reply; 87+ messages in thread
From: John Paul Adrian Glaubitz @ 2019-11-15 13:48 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Bernd Schmidt, gcc-patches

Hi Segher!

> It works on the kernel build, at least.  No idea if this *runs*, I just
> built it ;-)

I just did that and kernel 5.3.9 built with gcc trunk with Bernd's patches
boots fine on qemu-m68k-system. I will test the kernel on a real Amiga
later but I'm confident it will work there as well.

Thanks to everyone, especially Bernd for helping to make the cc0 transition
for m68k happen!

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaubitz@debian.org
`. `'   Freie Universitaet Berlin - glaubitz@physik.fu-berlin.de
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-13 13:08 [PATCH 0/4] Eliminate cc0 from m68k Bernd Schmidt
                   ` (5 preceding siblings ...)
  2019-11-13 19:41 ` Jeff Law
@ 2019-11-15 13:49 ` Andreas Schwab
  2019-11-15 16:34   ` Bernd Schmidt
  6 siblings, 1 reply; 87+ messages in thread
From: Andreas Schwab @ 2019-11-15 13:49 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

Here are the results of running the testsuite on m68k-linux:

http://gcc.gnu.org/ml/gcc-testresults/2019-11/msg00908.html

This is a list of regressions:

g++.old-deja/g++.other/dyncast1.C  -std=c++14 execution test
g++.old-deja/g++.other/dyncast1.C  -std=c++17 execution test
g++.old-deja/g++.other/dyncast1.C  -std=c++2a execution test
g++.old-deja/g++.other/dyncast1.C  -std=c++98 execution test
g++.old-deja/g++.other/dyncast6.C  -std=gnu++14 execution test
g++.old-deja/g++.other/dyncast6.C  -std=gnu++17 execution test
g++.old-deja/g++.other/dyncast6.C  -std=gnu++2a execution test
g++.old-deja/g++.other/dyncast6.C  -std=gnu++98 execution test
g++.old-deja/g++.other/rttid3.C  -std=gnu++14 execution test
g++.old-deja/g++.other/rttid3.C  -std=gnu++17 execution test
g++.old-deja/g++.other/rttid3.C  -std=gnu++2a execution test
g++.old-deja/g++.other/rttid3.C  -std=gnu++98 execution test
g++.old-deja/g++.robertl/eb46.C  -std=c++14 execution test
g++.old-deja/g++.robertl/eb46.C  -std=c++17 execution test
g++.old-deja/g++.robertl/eb46.C  -std=c++2a execution test
g++.old-deja/g++.robertl/eb46.C  -std=c++98 execution test

18_support/nested_exception/rethrow_if_nested.cc execution test
20_util/function_objects/comparisons_pointer.cc execution test
21_strings/basic_string/inserters_extractors/char/8.cc execution test
22_locale/num_get/get/char/16.cc execution test
24_iterators/istream_iterator/1.cc execution test
25_algorithms/copy_n/50119.cc execution test
27_io/basic_istream/extractors_arithmetic/char/01.cc execution test
27_io/basic_istream/extractors_arithmetic/char/02.cc execution test
27_io/basic_istream/extractors_arithmetic/char/03.cc execution test
27_io/basic_istream/extractors_arithmetic/char/10.cc execution test
27_io/basic_istream/extractors_arithmetic/char/11.cc execution test
27_io/basic_istream/extractors_arithmetic/char/13.cc execution test
27_io/basic_istream/extractors_arithmetic/char/dr696.cc execution test
27_io/basic_istream/seekg/char/8348-1.cc execution test
27_io/basic_istream/seekg/char/8348-2.cc execution test
27_io/basic_istream/tellg/char/8348.cc execution test
27_io/basic_istringstream/assign/1.cc execution test
27_io/basic_istringstream/cons/move.cc execution test
27_io/basic_istringstream/str/char/1.cc execution test
27_io/basic_stringbuf/seekoff/char/1.cc execution test
27_io/basic_stringbuf/seekoff/wchar_t/1.cc execution test
27_io/basic_stringbuf/seekoff/wchar_t/2.cc execution test
27_io/basic_stringstream/assign/1.cc execution test
27_io/filesystem/path/concat/path.cc execution test
27_io/manipulators/standard/char/quoted.cc execution test
27_io/rvalue_streams.cc execution test
28_regex/algorithms/regex_match/awk/cstring_01.cc execution test
28_regex/algorithms/regex_match/ecma/char/57173.cc execution test
28_regex/algorithms/regex_match/ecma/char/68863.cc execution test
28_regex/algorithms/regex_match/ecma/char/backref.cc execution test
28_regex/algorithms/regex_match/ecma/char/emptygroup.cc execution test
28_regex/algorithms/regex_match/ecma/char/hex.cc execution test
28_regex/algorithms/regex_match/extended/cstring_range.cc execution test
28_regex/algorithms/regex_replace/char/basic_replace.cc execution test
28_regex/algorithms/regex_replace/char/dr2213.cc execution test
28_regex/basic_regex/multiple_quantifiers.cc execution test
28_regex/match_results/format.cc execution test
28_regex/regression.cc execution test
28_regex/traits/char/value.cc execution test
backward/strstream_move.cc execution test
ext/random/k_distribution/operators/serialize.cc execution test
ext/random/nakagami_distribution/operators/serialize.cc execution test
ext/random/normal_mv_distribution/operators/serialize.cc execution test
ext/random/rice_distribution/operators/serialize.cc execution test
ext/random/uniform_inside_sphere_distribution/operators/serialize.cc execution test
tr1/5_numerical_facilities/random/discard_block/operators/serialize.cc execution test
tr1/7_regular_expressions/regex_traits/char/value.cc execution test
tr1/7_regular_expressions/regex_traits/wchar_t/value.cc execution test

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-15 13:48     ` John Paul Adrian Glaubitz
@ 2019-11-15 14:36       ` John Paul Adrian Glaubitz
  0 siblings, 0 replies; 87+ messages in thread
From: John Paul Adrian Glaubitz @ 2019-11-15 14:36 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Bernd Schmidt, gcc-patches

Hi!

On 11/15/19 2:45 PM, John Paul Adrian Glaubitz wrote:
>> It works on the kernel build, at least.  No idea if this *runs*, I just
>> built it ;-)
> 
> I just did that and kernel 5.3.9 built with gcc trunk with Bernd's patches
> boots fine on qemu-m68k-system. I will test the kernel on a real Amiga
> later but I'm confident it will work there as well.

Kernel built with the patched gcc-10 also boots fine on my Amiga 4000 68060 :).

I'm test building various packages now to see if I can see any other issues but
so far I'm very confident that there are no obvious regressions.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaubitz@debian.org
`. `'   Freie Universitaet Berlin - glaubitz@physik.fu-berlin.de
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-15 13:49 ` Andreas Schwab
@ 2019-11-15 16:34   ` Bernd Schmidt
  2019-11-15 16:36     ` Andreas Schwab
  0 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-15 16:34 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: GCC Patches

On 11/15/19 2:48 PM, Andreas Schwab wrote:
> Here are the results of running the testsuite on m68k-linux:
> 
> http://gcc.gnu.org/ml/gcc-testresults/2019-11/msg00908.html
> 
> This is a list of regressions:

Are these with the patch? I'm not seeing any of these in my testing with
qemu. Are you on real hardware (and on which hardware?), and can you do
anything to help narrow down what's going wrong?


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-15 16:34   ` Bernd Schmidt
@ 2019-11-15 16:36     ` Andreas Schwab
  2019-11-15 21:41       ` Bernd Schmidt
  0 siblings, 1 reply; 87+ messages in thread
From: Andreas Schwab @ 2019-11-15 16:36 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

On Nov 15 2019, Bernd Schmidt wrote:

> Are these with the patch?

Yes.

> Are you on real hardware

No, I'm using aranym.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-15 16:36     ` Andreas Schwab
@ 2019-11-15 21:41       ` Bernd Schmidt
  2019-11-15 22:21         ` Andreas Schwab
  0 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-15 21:41 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: GCC Patches

On 11/15/19 5:34 PM, Andreas Schwab wrote:
> On Nov 15 2019, Bernd Schmidt wrote:
> 
>> Are these with the patch?
> 
> Yes.
> 
>> Are you on real hardware
> 
> No, I'm using aranym.

Any chance you could show the command lines from the log files or some
other way of reproducing the issue?


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-15 21:41       ` Bernd Schmidt
@ 2019-11-15 22:21         ` Andreas Schwab
  2019-11-15 22:22           ` Bernd Schmidt
  0 siblings, 1 reply; 87+ messages in thread
From: Andreas Schwab @ 2019-11-15 22:21 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

On Nov 15 2019, Bernd Schmidt wrote:

> Any chance you could show the command lines from the log files or some
> other way of reproducing the issue?

Executing on aranym: OMP_NUM_THREADS=2 LD_LIBRARY_PATH=.:/daten/aranym/gcc/gcc-20191115/Build/m68k-linux/./libstdc++-v3/src/.libs:/daten/aranym/gcc/gcc-20191115/Build/m68k-linux/./libstdc++-v3/src/.libs:/daten/aranym/gcc/gcc-20191115/Build/gcc:/daten/aranym/gcc/gcc-20191115/Build/gcc timeout 1200 ./dyncast1.exe     (timeout = 300)
Executed ./dyncast1.exe, status 1
Output: Error 25
child process exited abnormally
FAIL: g++.old-deja/g++.other/dyncast1.C  -std=c++17 execution test

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-15 22:21         ` Andreas Schwab
@ 2019-11-15 22:22           ` Bernd Schmidt
  2019-11-15 22:57             ` Andreas Schwab
  0 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-15 22:22 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: GCC Patches

On 11/15/19 10:58 PM, Andreas Schwab wrote:
> On Nov 15 2019, Bernd Schmidt wrote:
> 
>> Any chance you could show the command lines from the log files or some
>> other way of reproducing the issue?
> 
> Executing on aranym: OMP_NUM_THREADS=2 LD_LIBRARY_PATH=.:/daten/aranym/gcc/gcc-20191115/Build/m68k-linux/./libstdc++-v3/src/.libs:/daten/aranym/gcc/gcc-20191115/Build/m68k-linux/./libstdc++-v3/src/.libs:/daten/aranym/gcc/gcc-20191115/Build/gcc:/daten/aranym/gcc/gcc-20191115/Build/gcc timeout 1200 ./dyncast1.exe     (timeout = 300)
> Executed ./dyncast1.exe, status 1
> Output: Error 25
> child process exited abnormally
> FAIL: g++.old-deja/g++.other/dyncast1.C  -std=c++17 execution test

I meant the compiler command line of course... for any -mcpu flags that
might differ from my test run.


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-15 22:22           ` Bernd Schmidt
@ 2019-11-15 22:57             ` Andreas Schwab
  2019-11-16  0:17               ` Bernd Schmidt
  2019-11-16 12:16               ` John Paul Adrian Glaubitz
  0 siblings, 2 replies; 87+ messages in thread
From: Andreas Schwab @ 2019-11-15 22:57 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

On Nov 15 2019, Bernd Schmidt wrote:

> I meant the compiler command line of course... for any -mcpu flags that
> might differ from my test run.

There are none.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-15 22:57             ` Andreas Schwab
@ 2019-11-16  0:17               ` Bernd Schmidt
  2019-11-16  8:26                 ` Andreas Schwab
  2019-11-16 10:47                 ` Andreas Schwab
  2019-11-16 12:16               ` John Paul Adrian Glaubitz
  1 sibling, 2 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-16  0:17 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: GCC Patches

On 11/15/19 11:50 PM, Andreas Schwab wrote:
> On Nov 15 2019, Bernd Schmidt wrote:
> 
>> I meant the compiler command line of course... for any -mcpu flags that
>> might differ from my test run.
> 
> There are none.

Well, there has to be some difference between what you are doing and
what I am doing, because:

Running /local/src/egcs/git/gcc/testsuite/g++.old-deja/old-deja.exp ...

		=== g++ Summary ===

# of expected passes		26826
# of expected failures		82
# of unsupported tests		157
/local/src/egcs/bm68k-test/gcc/xg++  version 10.0.0 20191101
(experimental) (GCC)

Is there anything you think you can give me to help reproduce this?
Before/after assembly files, generated with -fverbose-asm?


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-16  0:17               ` Bernd Schmidt
@ 2019-11-16  8:26                 ` Andreas Schwab
  2019-11-16 13:32                   ` Bernd Schmidt
  2019-11-16 10:47                 ` Andreas Schwab
  1 sibling, 1 reply; 87+ messages in thread
From: Andreas Schwab @ 2019-11-16  8:26 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

On Nov 16 2019, Bernd Schmidt wrote:

> Well, there has to be some difference between what you are doing and
> what I am doing, because:
>
> Running /local/src/egcs/git/gcc/testsuite/g++.old-deja/old-deja.exp ...
>
> 		=== g++ Summary ===
>
> # of expected passes		26826
> # of expected failures		82
> # of unsupported tests		157
> /local/src/egcs/bm68k-test/gcc/xg++  version 10.0.0 20191101
> (experimental) (GCC)

		=== g++ Summary ===

# of expected passes		170041
# of unexpected failures	74
# of expected failures		708
# of unresolved testcases	2
# of unsupported tests		7419
/daten/aranym/gcc/gcc-20191115/Build/gcc/xg++  version 10.0.0 20191114 (experimental) [trunk revision 278266] (GCC) 

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-16  0:17               ` Bernd Schmidt
  2019-11-16  8:26                 ` Andreas Schwab
@ 2019-11-16 10:47                 ` Andreas Schwab
  1 sibling, 0 replies; 87+ messages in thread
From: Andreas Schwab @ 2019-11-16 10:47 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

Running /daten/aranym/gcc/gcc-20191116/gcc/testsuite/g++.old-deja/old-deja.exp ...
FAIL: g++.old-deja/g++.other/dyncast1.C  -std=c++98 execution test
FAIL: g++.old-deja/g++.other/dyncast1.C  -std=c++14 execution test
FAIL: g++.old-deja/g++.other/dyncast1.C  -std=c++17 execution test
FAIL: g++.old-deja/g++.other/dyncast1.C  -std=c++2a execution test
FAIL: g++.old-deja/g++.other/dyncast6.C  -std=gnu++98 execution test
FAIL: g++.old-deja/g++.other/dyncast6.C  -std=gnu++14 execution test
FAIL: g++.old-deja/g++.other/dyncast6.C  -std=gnu++17 execution test
FAIL: g++.old-deja/g++.other/dyncast6.C  -std=gnu++2a execution test
FAIL: g++.old-deja/g++.other/rttid3.C  -std=gnu++98 execution test
FAIL: g++.old-deja/g++.other/rttid3.C  -std=gnu++14 execution test
FAIL: g++.old-deja/g++.other/rttid3.C  -std=gnu++17 execution test
FAIL: g++.old-deja/g++.other/rttid3.C  -std=gnu++2a execution test
FAIL: g++.old-deja/g++.robertl/eb46.C  -std=c++98 execution test
FAIL: g++.old-deja/g++.robertl/eb46.C  -std=c++14 execution test
FAIL: g++.old-deja/g++.robertl/eb46.C  -std=c++17 execution test
FAIL: g++.old-deja/g++.robertl/eb46.C  -std=c++2a execution test

                === g++ Summary ===

# of expected passes            26803
# of unexpected failures        16
# of expected failures          82
# of unsupported tests          157
/daten/aranym/gcc/gcc-20191116/Build/gcc/xg++  version 10.0.0 20191115 (experimental) [trunk revision 278320] (GCC)

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-15 22:57             ` Andreas Schwab
  2019-11-16  0:17               ` Bernd Schmidt
@ 2019-11-16 12:16               ` John Paul Adrian Glaubitz
  1 sibling, 0 replies; 87+ messages in thread
From: John Paul Adrian Glaubitz @ 2019-11-16 12:16 UTC (permalink / raw)
  To: Andreas Schwab, d6a42db5-cc76-95b7-abe4-2487ff06e5aa
  Cc: Bernd Schmidt, gcc-patches

Hi Andreas!

>                 === g++ Summary ===
> 
> # of expected passes            26803
> # of unexpected failures        16
> # of expected failures          82
> # of unsupported tests          157
> /daten/aranym/gcc/gcc-20191116/Build/gcc/xg++  version 10.0.0 20191115 (experimental) [trunk revision 278320] (GCC)

Is this testsuite run with or without Bernd's patches?

If yes, I think it would be a good sign that the patches are good for submission.

I will try to get the patches backported to gcc-9 so that we can start building Debian
packages with a patched gcc-9 which may help finding more regressions.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaubitz@debian.org
`. `'   Freie Universitaet Berlin - glaubitz@physik.fu-berlin.de
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-16  8:26                 ` Andreas Schwab
@ 2019-11-16 13:32                   ` Bernd Schmidt
  0 siblings, 0 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-16 13:32 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: GCC Patches

On 11/16/19 9:18 AM, Andreas Schwab wrote:
> On Nov 16 2019, Bernd Schmidt wrote:
> 
>> Well, there has to be some difference between what you are doing and
>> what I am doing, because:
>>
>> Running /local/src/egcs/git/gcc/testsuite/g++.old-deja/old-deja.exp ...
>>
>> 		=== g++ Summary ===
>>
>> # of expected passes		26826
>> # of expected failures		82
>> # of unsupported tests		157
>> /local/src/egcs/bm68k-test/gcc/xg++  version 10.0.0 20191101
>> (experimental) (GCC)
> 
> 		=== g++ Summary ===
> 
> # of expected passes		170041
> # of unexpected failures	74
> # of expected failures		708
> # of unresolved testcases	2
> # of unsupported tests		7419
> /daten/aranym/gcc/gcc-20191115/Build/gcc/xg++  version 10.0.0 20191114 (experimental) [trunk revision 278266] (GCC) 

Once again, that doesn't help me track things down. A bug report without
instructions to reproduce is useless. Could you please provide me the
generated assembly files with -fverbose-asm that I asked for?


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-13 13:29   ` Bernd Schmidt
@ 2019-11-17 18:00     ` Jeff Law
       [not found]       ` <5bba50b1-f8de-42fb-1057-208b52c847fb@t-online.de>
  2019-11-23 17:36     ` John Paul Adrian Glaubitz
  1 sibling, 1 reply; 87+ messages in thread
From: Jeff Law @ 2019-11-17 18:00 UTC (permalink / raw)
  To: Bernd Schmidt, gcc-patches

On 11/13/19 6:23 AM, Bernd Schmidt wrote:
> Once more with patch.
> 
> 
> Bernd
> 
> 
> m68k-2.diff
> 
>             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.
My inclination is to ACK this as-is and let us iterate on any bugs that
pop up.  Bernd has a long history with GCC and I absolutely trust his
ability, judgment and commitment to addressing any issues.

While scanning this patch I did notice the introduction of
CC_STATUS_INIT in output_{and,ior,xor}si.  You might want to check that.

So unless there's objections over the next say 48-72 hrs, let's get the
kit in and we can iterate if there's further issues that need resolving.

Jeff

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 1/4] Preliminary m68k patches
  2019-11-14 12:25     ` Bernd Schmidt
@ 2019-11-17 18:27       ` Jeff Law
  2019-11-18 16:52       ` Jeff Law
  1 sibling, 0 replies; 87+ messages in thread
From: Jeff Law @ 2019-11-17 18:27 UTC (permalink / raw)
  To: Bernd Schmidt, GCC Patches

On 11/14/19 5:23 AM, Bernd Schmidt wrote:
> On 11/13/19 9:03 PM, Jeff Law wrote:
>> OK.  I'd actually recommend this go ahead and get installed.  My tester
>> will bootstrap it overnight.
> 
> Alright, let me know how that turns out. What kind of machine do you
> have for that?
Sorry I should have been clearer.  I expected you to commit the first
patch and my tester would have picked it up automatically.

Regrardless, I put the first patch into my magic testing directory, so
it'll get bootstrapped later today.

jeff

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 1/4] Preliminary m68k patches
  2019-11-14 12:25     ` Bernd Schmidt
  2019-11-17 18:27       ` Jeff Law
@ 2019-11-18 16:52       ` Jeff Law
  1 sibling, 0 replies; 87+ messages in thread
From: Jeff Law @ 2019-11-18 16:52 UTC (permalink / raw)
  To: Bernd Schmidt, GCC Patches

On 11/14/19 5:23 AM, Bernd Schmidt wrote:
> On 11/13/19 9:03 PM, Jeff Law wrote:
>> OK.  I'd actually recommend this go ahead and get installed.  My tester
>> will bootstrap it overnight.
> 
> Alright, let me know how that turns out. What kind of machine do you
> have for that?
So patch#1 had a minor problem applying to the top of the trunk, but it
was easily resolved by hand.  GCC bootstrapped & built glibc and was
building the kernel when the beaker machine either crashed or got
reclaimed by beaker.

So after ~14 hours we know it was working reasonably well (as expected),
but don't have full confirmation.

jeff

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
       [not found]       ` <5bba50b1-f8de-42fb-1057-208b52c847fb@t-online.de>
@ 2019-11-18 17:42         ` Bernd Schmidt
  2019-11-18 17:55           ` Jeff Law
  0 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-18 17:42 UTC (permalink / raw)
  To: Jeff Law, GCC Patches

(Apologies to Jeff who's getting this twice because I didn't hit
reply-all the first time.)

On 11/17/19 6:56 PM, Jeff Law wrote:

> While scanning this patch I did notice the introduction of
> CC_STATUS_INIT in output_{and,ior,xor}si.  You might want to check that.

That is intentional. CC_STATUS_INIT can be used without cc0, and there's
precedent in (IIRC) ARM. We need it to get final to tell us when it
encounters a label - those don't make it to the postscan_insn hook.

> So unless there's objections over the next say 48-72 hrs, let's get the
> kit in and we can iterate if there's further issues that need resolving.

Cool. I'll wait for a final confirmation.


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-18 17:42         ` Bernd Schmidt
@ 2019-11-18 17:55           ` Jeff Law
  0 siblings, 0 replies; 87+ messages in thread
From: Jeff Law @ 2019-11-18 17:55 UTC (permalink / raw)
  To: Bernd Schmidt, GCC Patches

On 11/18/19 9:51 AM, Bernd Schmidt wrote:
> (Apologies to Jeff who's getting this twice because I didn't hit
> reply-all the first time.)
> 
> On 11/17/19 6:56 PM, Jeff Law wrote:
> 
>> While scanning this patch I did notice the introduction of
>> CC_STATUS_INIT in output_{and,ior,xor}si.  You might want to check that.
> 
> That is intentional. CC_STATUS_INIT can be used without cc0, and there's
> precedent in (IIRC) ARM. We need it to get final to tell us when it
> encounters a label - those don't make it to the postscan_insn hook.
OK.  Just saw it and found it a bit odd.  No worries if it was intentional.

jeff

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 4/4] Fix autoinc cbranch
  2019-11-13 13:24 ` [PATCH 4/4] Fix autoinc cbranch Bernd Schmidt
@ 2019-11-19  0:36   ` Segher Boessenkool
  2019-11-24 14:20     ` Bernd Schmidt
  0 siblings, 1 reply; 87+ messages in thread
From: Segher Boessenkool @ 2019-11-19  0:36 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

On Wed, Nov 13, 2019 at 02:21:01PM +0100, Bernd Schmidt wrote:
> After the m68k cc0 conversion, there is one code quality regression that
> I can see: we no longer generate autoinc addressing modes in
> comparisons. This is because the parts of the compiler that generate
> autoinc are unwilling to substitute into jumps.
> 
> If you look at the code in reload, you'll see that it's careful around
> jumps at find_reload time, and the code to perform autoinc reloads does
> try to put all the extra code before the instruction. LRA seems to have
> copied most of that code.
> Also, in the former cc0 reality, a compare wasn't really any different
> from a jump on m68k: we can't have a reload after the instruction in
> either case. Any kind of move or arithmetic would clobber the flags.
> 
> That leads me to believe that there is no issue with autoinc in jumps,
> hence this patch. Bootstrapped and tested on the gcc135 machine
> (powerpc64le-unknown-linux-gnu). I don't really expect this to get
> approved; alternatively I could write some peepholes which would
> generate the same code as long as register pressure doesn't get too high.

I don't see why it wouldn't work?  If you apply it now we will still
have a lot of time to find problems with it, if those exist.

The combine parts are okay for trunk, if you keep an eye out :-)


Segher

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 3/4] Set costs for jumps in combine
  2019-11-13 16:26   ` Segher Boessenkool
@ 2019-11-21 13:53     ` Bernd Schmidt
  2019-11-22  0:52       ` Segher Boessenkool
  0 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-21 13:53 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

On 11/13/19 5:16 PM, Segher Boessenkool wrote:
> On Wed, Nov 13, 2019 at 02:13:48PM +0100, Bernd Schmidt wrote:
>> Also, it does not compute costs for jump
>> insns, so they are always set to zero. As a consequence, any possible
>> substitution is performed if a combination into a jump is possible,
>> which turns out isn't really desirable on m68k with cbranch patterns.
>>
>> This patch simply removes a test for NONJUMP_INSN_P. Bootstrapped and
>> tested on the gcc135 machine (powerpc64le-unknown-linux-gnu).
> 
> I wonder why that test was there.  It was added in r84513, which is where
> insn_rtx_cost was made from combine_insn_cost, which didn't have that
> non-jump thing yet.
> 
> It is still stage 1, so we'll find out if any target breaks I guess.
> Okay for trunk.  Thanks!

Thanks. Just FYI, this is held up a little. I decided I'd also test on
x86, and there it shows a case where ix86_rtx_cost misses something: the
i386/pr30315.c testcase wants to combine compares into addition+jump on
carry, but the rtx_costs show too high a cost for (compare (plus)). I'm
testing a fix for that in i386.c.


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 3/4] Set costs for jumps in combine
  2019-11-21 13:53     ` Bernd Schmidt
@ 2019-11-22  0:52       ` Segher Boessenkool
  2019-11-22  1:09         ` Bernd Schmidt
  2019-11-22  2:43         ` Paul Koning
  0 siblings, 2 replies; 87+ messages in thread
From: Segher Boessenkool @ 2019-11-22  0:52 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

On Thu, Nov 21, 2019 at 02:36:53PM +0100, Bernd Schmidt wrote:
> On 11/13/19 5:16 PM, Segher Boessenkool wrote:
> > On Wed, Nov 13, 2019 at 02:13:48PM +0100, Bernd Schmidt wrote:
> >> Also, it does not compute costs for jump
> >> insns, so they are always set to zero. As a consequence, any possible
> >> substitution is performed if a combination into a jump is possible,
> >> which turns out isn't really desirable on m68k with cbranch patterns.
> >>
> >> This patch simply removes a test for NONJUMP_INSN_P. Bootstrapped and
> >> tested on the gcc135 machine (powerpc64le-unknown-linux-gnu).
> > 
> > I wonder why that test was there.  It was added in r84513, which is where
> > insn_rtx_cost was made from combine_insn_cost, which didn't have that
> > non-jump thing yet.
> > 
> > It is still stage 1, so we'll find out if any target breaks I guess.
> > Okay for trunk.  Thanks!
> 
> Thanks. Just FYI, this is held up a little. I decided I'd also test on
> x86, and there it shows a case where ix86_rtx_cost misses something: the
> i386/pr30315.c testcase wants to combine compares into addition+jump on
> carry, but the rtx_costs show too high a cost for (compare (plus)). I'm
> testing a fix for that in i386.c.

Maybe i386 should implement the insn_cost hook as well?  For most targets
that is a lot simpler to get right than rtx_cost, but allowing memory in
many insns and all the different insn lengths complicates matters.  At
least insn_cost isn't inside-out, that should make it easier to deal with
already.


Segher

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 3/4] Set costs for jumps in combine
  2019-11-22  0:52       ` Segher Boessenkool
@ 2019-11-22  1:09         ` Bernd Schmidt
  2019-11-22  2:43         ` Paul Koning
  1 sibling, 0 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-22  1:09 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

On 11/22/19 1:42 AM, Segher Boessenkool wrote:
> On Thu, Nov 21, 2019 at 02:36:53PM +0100, Bernd Schmidt wrote:
>> Thanks. Just FYI, this is held up a little. I decided I'd also test on
>> x86, and there it shows a case where ix86_rtx_cost misses something: the
>> i386/pr30315.c testcase wants to combine compares into addition+jump on
>> carry, but the rtx_costs show too high a cost for (compare (plus)). I'm
>> testing a fix for that in i386.c.
> 
> Maybe i386 should implement the insn_cost hook as well?  For most targets
> that is a lot simpler to get right than rtx_cost, but allowing memory in
> many insns and all the different insn lengths complicates matters.  At
> least insn_cost isn't inside-out, that should make it easier to deal with
> already.

That kind of thing is up to the x86 maintainers. I think the problem at
hand can be fixed quite simply by detecting PLUS inside COMPARE and just
counting it like we would a normal PLUS. Patch will follow once testing
is complete.


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 3/4] Set costs for jumps in combine
  2019-11-22  0:52       ` Segher Boessenkool
  2019-11-22  1:09         ` Bernd Schmidt
@ 2019-11-22  2:43         ` Paul Koning
  2019-11-22 16:57           ` Segher Boessenkool
  1 sibling, 1 reply; 87+ messages in thread
From: Paul Koning @ 2019-11-22  2:43 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Bernd Schmidt, GCC Patches



> On Nov 21, 2019, at 7:42 PM, Segher Boessenkool <segher@kernel.crashing.org> wrote:
> 
> ...
> Maybe i386 should implement the insn_cost hook as well?  For most targets
> that is a lot simpler to get right than rtx_cost, but allowing memory in
> many insns and all the different insn lengths complicates matters.  At
> least insn_cost isn't inside-out, that should make it easier to deal with
> already.

Yes, rtx_cost is a pain to write and understand.  I looked at insn_cost in the past but was told, or got the impression somehow, that it is at the moment a partial solution and rtx_cost is still needed to complete the cost picture.

Is that incorrect, or no longer accurate?  I would like to dump rtx_cost in my target if that is now indeed a valid thing to do.

	paul


^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 3/4] Set costs for jumps in combine
  2019-11-22  2:43         ` Paul Koning
@ 2019-11-22 16:57           ` Segher Boessenkool
  0 siblings, 0 replies; 87+ messages in thread
From: Segher Boessenkool @ 2019-11-22 16:57 UTC (permalink / raw)
  To: Paul Koning; +Cc: Bernd Schmidt, GCC Patches

On Thu, Nov 21, 2019 at 08:12:05PM -0500, Paul Koning wrote:
> > On Nov 21, 2019, at 7:42 PM, Segher Boessenkool <segher@kernel.crashing.org> wrote:
> > 
> > ...
> > Maybe i386 should implement the insn_cost hook as well?  For most targets
> > that is a lot simpler to get right than rtx_cost, but allowing memory in
> > many insns and all the different insn lengths complicates matters.  At
> > least insn_cost isn't inside-out, that should make it easier to deal with
> > already.
> 
> Yes, rtx_cost is a pain to write and understand.  I looked at insn_cost in the past but was told, or got the impression somehow, that it is at the moment a partial solution and rtx_cost is still needed to complete the cost picture.
> 
> Is that incorrect, or no longer accurate?  I would like to dump rtx_cost in my target if that is now indeed a valid thing to do.

Some things still want the rtx_cost of non-insns.  CSE does this, as does
expand (for figuring out the multiplication strategy to use, for one thing),
and then there are set_src_cost and set_rtx_cost (which are probably not
hard to fix, for the cases where there *is* an insn for doing things).

With rtx_cost you need to estimate the cost of arbitrary RTL expressions,
whether that means anything for the machine or not.  This does not make
terribly much sense, but changing the compiler her without regressing
things isn't trivial.


Segher

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-13 13:29   ` Bernd Schmidt
  2019-11-17 18:00     ` Jeff Law
@ 2019-11-23 17:36     ` John Paul Adrian Glaubitz
  2019-11-23 19:54       ` Jeff Law
  1 sibling, 1 reply; 87+ messages in thread
From: John Paul Adrian Glaubitz @ 2019-11-23 17:36 UTC (permalink / raw)
  To: Jeff Law; +Cc: Bernd Schmidt, gcc-patches

Hi Jeff!

> On 11/13/19 6:23 AM, Bernd Schmidt wrote:
>> Once more with patch.
>> 
>> 
>> Bernd
>> 
>> 
>> m68k-2.diff
>> 
>>             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.
> My inclination is to ACK this as-is and let us iterate on any bugs that
> pop up.  Bernd has a long history with GCC and I absolutely trust his
> ability, judgment and commitment to addressing any issues.
> 
> While scanning this patch I did notice the introduction of
> CC_STATUS_INIT in output_{and,ior,xor}si.  You might want to check that.
> 
> So unless there's objections over the next say 48-72 hrs, let's get the
> kit in and we can iterate if there's further issues that need resolving.

Any news on this? I would be in favor of merging these patches as I have
tested them successfully on Debian by building the gcc-snapshot package
with the patches applied. I used all four patches plus the additional one
required to be able to build the kernel.

I did not see the bootstrap problems that Mikael reported and Andreas has
reported that the issues is not reliably reproducible on Aranym. He suspected
that it might be a bug in the MMU emulation in Aranym which only triggers
randomly depending on the current memory layout.

I have used a patched gcc-10 to build the Debian kernel (package version 5.3.9-3)
and it builds fine. The kernel also boots without any problems on my Amiga 4000
with 68060/50 accelerator and 128 MB RAM.

So, I think we should get the patches merged so we have a chance to extensively
test them in Debian with the help of the gcc-snapshot package that gets
regularly updated in Debian.

I will report any bugs that I am running into.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaubitz@debian.org
`. `'   Freie Universitaet Berlin - glaubitz@physik.fu-berlin.de
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-23 17:36     ` John Paul Adrian Glaubitz
@ 2019-11-23 19:54       ` Jeff Law
  2019-11-23 20:53         ` Oleg Endo
                           ` (2 more replies)
  0 siblings, 3 replies; 87+ messages in thread
From: Jeff Law @ 2019-11-23 19:54 UTC (permalink / raw)
  To: John Paul Adrian Glaubitz; +Cc: Bernd Schmidt, gcc-patches

On 11/23/19 10:14 AM, John Paul Adrian Glaubitz wrote:
> Hi Jeff!
> 
>> On 11/13/19 6:23 AM, Bernd Schmidt wrote:
>>> Once more with patch.
>>>
>>>
>>> Bernd
>>>
>>>
>>> m68k-2.diff
>>>
>>>             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.
>> My inclination is to ACK this as-is and let us iterate on any bugs that
>> pop up.  Bernd has a long history with GCC and I absolutely trust his
>> ability, judgment and commitment to addressing any issues.
>>
>> While scanning this patch I did notice the introduction of
>> CC_STATUS_INIT in output_{and,ior,xor}si.  You might want to check that.
>>
>> So unless there's objections over the next say 48-72 hrs, let's get the
>> kit in and we can iterate if there's further issues that need resolving.
> 
> Any news on this? I would be in favor of merging these patches as I have
> tested them successfully on Debian by building the gcc-snapshot package
> with the patches applied. I used all four patches plus the additional one
> required to be able to build the kernel.
Not really.  I've already indicated to Bernd that he should go ahead and
commit the changes and we can iterate on any problems that arise.

> 
> I did not see the bootstrap problems that Mikael reported and Andreas has
> reported that the issues is not reliably reproducible on Aranym. He suspected
> that it might be a bug in the MMU emulation in Aranym which only triggers
> randomly depending on the current memory layout.
Good to know it wasn't reproducible and might ultimately be a bug in aranym.

Jeff

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-23 19:54       ` Jeff Law
@ 2019-11-23 20:53         ` Oleg Endo
  2019-11-24 18:09           ` Jeff Law
  2019-11-23 22:34         ` Bernd Schmidt
  2019-11-25 12:34         ` Bernd Schmidt
  2 siblings, 1 reply; 87+ messages in thread
From: Oleg Endo @ 2019-11-23 20:53 UTC (permalink / raw)
  To: Jeff Law, John Paul Adrian Glaubitz, Bernd Schmidt, gcc-patches; +Cc: stefan

On Sat, 2019-11-23 at 10:36 -0700, Jeff Law wrote:
> 
> > Any news on this? I would be in favor of merging these patches as I
> > have
> > tested them successfully on Debian by building the gcc-snapshot
> > package
> > with the patches applied. I used all four patches plus the
> > additional one
> > required to be able to build the kernel.
> 
> Not really.  I've already indicated to Bernd that he should go ahead
> and
> commit the changes and we can iterate on any problems that arise.
> 
> > 
> > I did not see the bootstrap problems that Mikael reported and
> > Andreas has
> > reported that the issues is not reliably reproducible on Aranym. He
> > suspected
> > that it might be a bug in the MMU emulation in Aranym which only
> > triggers
> > randomly depending on the current memory layout.
> 
> Good to know it wasn't reproducible and might ultimately be a bug in
> aranym.
> 

Meanwhile, another patch that's supposed to do the same thing was
posted:

https://gcc.gnu.org/ml/gcc-patches/2019-11/msg02131.html

Cheers,
Oleg

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-23 19:54       ` Jeff Law
  2019-11-23 20:53         ` Oleg Endo
@ 2019-11-23 22:34         ` Bernd Schmidt
  2019-11-24 10:25           ` Bernd Schmidt
  2019-11-25 12:34         ` Bernd Schmidt
  2 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-23 22:34 UTC (permalink / raw)
  To: Jeff Law, John Paul Adrian Glaubitz; +Cc: gcc-patches

On 11/23/19 6:36 PM, Jeff Law wrote:
> Not really.  I've already indicated to Bernd that he should go ahead and commit the changes and we can iterate on any problems that arise.

In the meantime I've made an aranym setup in addition to the qemu setup
I had, and I've not been able to reproduce failures like the ones
Andreas reported.
I'll spend a few more days trying to see if I can do something about the
bootstrap failure Mikael saw (currently trying to do a two-stage cross
build rather than a really slow bootstrap).


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-23 22:34         ` Bernd Schmidt
@ 2019-11-24 10:25           ` Bernd Schmidt
  2019-11-25 11:37             ` Andreas Schwab
  2019-11-28 20:00             ` Gunther Nikl
  0 siblings, 2 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-24 10:25 UTC (permalink / raw)
  To: Jeff Law, John Paul Adrian Glaubitz; +Cc: gcc-patches, Mikael Pettersson

[-- Attachment #1: Type: text/plain, Size: 574 bytes --]

On 11/23/19 9:53 PM, Bernd Schmidt wrote:
> I'll spend a few more days trying to see if I can do something about the
> bootstrap failure Mikael saw (currently trying to do a two-stage cross
> build rather than a really slow bootstrap).

Whew, I think I have it. One tst instruction eliminated when it
shouldn't have been:

        move.w %a4,%d0
-       tst.b %d0
-       jeq .L352
+       jeq .L353

And the reason - that's a movqi using move.w. The following should fix
it. I'll run a few more tests, and then check it all in as Jeff
suggested if things looks OK.


Bernd

[-- Attachment #2: m68k-fix.diff --]
[-- Type: text/x-patch, Size: 558 bytes --]

diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index c72325fa4ab..8d010ebe6e9 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -3314,7 +3314,11 @@ output_move_qimode (rtx *operands)
   /* 68k family (including the 5200 ColdFire) does not support byte moves to
      from address registers.  */
   if (ADDRESS_REG_P (operands[0]) || ADDRESS_REG_P (operands[1]))
-    return "move%.w %1,%0";
+    {
+      if (ADDRESS_REG_P (operands[1]))
+	CC_STATUS_INIT;
+      return "move%.w %1,%0";
+    }
   return "move%.b %1,%0";
 }
 

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 4/4] Fix autoinc cbranch
  2019-11-19  0:36   ` Segher Boessenkool
@ 2019-11-24 14:20     ` Bernd Schmidt
  2019-11-24 17:48       ` Segher Boessenkool
  0 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-24 14:20 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 374 bytes --]

On 11/19/19 1:27 AM, Segher Boessenkool wrote:
> The combine parts are okay for trunk, if you keep an eye out :-)

Thanks, now committed. That leaves the auto-inc-dec part. Since we're
being adventurous, I've also bootstrapped and tested the following in
the meantime (on the gcc135 machine). This just deletes the tests for
jumps entirely rather than hedging bets.


Bernd

[-- Attachment #2: ainc2.diff --]
[-- Type: text/x-patch, Size: 538 bytes --]

Index: gcc/auto-inc-dec.c
===================================================================
--- gcc/auto-inc-dec.c	(revision 278653)
+++ gcc/auto-inc-dec.c	(working copy)
@@ -1441,12 +1441,6 @@ merge_in_block (int max_reg, basic_block
 	  continue;
 	}
 
-      /* This continue is deliberate.  We do not want the uses of the
-	 jump put into reg_next_use because it is not considered safe to
-	 combine a preincrement with a jump.  */
-      if (JUMP_P (insn))
-	continue;
-
       if (dump_file)
 	dump_insn_slim (dump_file, insn);
 

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 4/4] Fix autoinc cbranch
  2019-11-24 14:20     ` Bernd Schmidt
@ 2019-11-24 17:48       ` Segher Boessenkool
  2019-11-24 19:55         ` Segher Boessenkool
  0 siblings, 1 reply; 87+ messages in thread
From: Segher Boessenkool @ 2019-11-24 17:48 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

Hi!

On Sun, Nov 24, 2019 at 03:19:49PM +0100, Bernd Schmidt wrote:
> -      /* This continue is deliberate.  We do not want the uses of the
> -	 jump put into reg_next_use because it is not considered safe to
> -	 combine a preincrement with a jump.  */
> -      if (JUMP_P (insn))
> -	continue;

Huh, I wonder where that came from.  More archaelogy :-)

(This patch looks fine to me, fwiw).


Segher

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-23 20:53         ` Oleg Endo
@ 2019-11-24 18:09           ` Jeff Law
  0 siblings, 0 replies; 87+ messages in thread
From: Jeff Law @ 2019-11-24 18:09 UTC (permalink / raw)
  To: Oleg Endo, John Paul Adrian Glaubitz, Bernd Schmidt, gcc-patches; +Cc: stefan

On 11/23/19 12:54 PM, Oleg Endo wrote:
> On Sat, 2019-11-23 at 10:36 -0700, Jeff Law wrote:
>>
>>> Any news on this? I would be in favor of merging these patches as I
>>> have
>>> tested them successfully on Debian by building the gcc-snapshot
>>> package
>>> with the patches applied. I used all four patches plus the
>>> additional one
>>> required to be able to build the kernel.
>>
>> Not really.  I've already indicated to Bernd that he should go ahead
>> and
>> commit the changes and we can iterate on any problems that arise.
>>
>>>
>>> I did not see the bootstrap problems that Mikael reported and
>>> Andreas has
>>> reported that the issues is not reliably reproducible on Aranym. He
>>> suspected
>>> that it might be a bug in the MMU emulation in Aranym which only
>>> triggers
>>> randomly depending on the current memory layout.
>>
>> Good to know it wasn't reproducible and might ultimately be a bug in
>> aranym.
>>
> 
> Meanwhile, another patch that's supposed to do the same thing was
> posted:
> 
> https://gcc.gnu.org/ml/gcc-patches/2019-11/msg02131.html
Yes.  I'm aware.  Given Bernd's was submitted first and looks generally
sound, I think his has priority.

jeff

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 4/4] Fix autoinc cbranch
  2019-11-24 17:48       ` Segher Boessenkool
@ 2019-11-24 19:55         ` Segher Boessenkool
  2019-11-24 20:47           ` Bernd Schmidt
  0 siblings, 1 reply; 87+ messages in thread
From: Segher Boessenkool @ 2019-11-24 19:55 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

On Sun, Nov 24, 2019 at 11:39:05AM -0600, Segher Boessenkool wrote:
> On Sun, Nov 24, 2019 at 03:19:49PM +0100, Bernd Schmidt wrote:
> > -      /* This continue is deliberate.  We do not want the uses of the
> > -	 jump put into reg_next_use because it is not considered safe to
> > -	 combine a preincrement with a jump.  */
> > -      if (JUMP_P (insn))
> > -	continue;
> 
> Huh, I wonder where that came from.  More archaelogy :-)

It came in as r115135 on the dataflow-branch.  Patch is at
https://gcc.gnu.org/ml/gcc-patches/2006-07/msg00037.html .

And that is where I lost track.

But.  Allowing autoinc into jump insns means those jump insns may then
eventually need an output reload; it may just have been because of that?


Segher

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 4/4] Fix autoinc cbranch
  2019-11-24 19:55         ` Segher Boessenkool
@ 2019-11-24 20:47           ` Bernd Schmidt
  2019-11-24 22:20             ` Segher Boessenkool
  0 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-24 20:47 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

On 11/24/19 8:43 PM, Segher Boessenkool wrote:
> But.  Allowing autoinc into jump insns means those jump insns may then
> eventually need an output reload; it may just have been because of that?

That's almost certainly the reasoning, but as I pointed out in my
original mail - reload is careful around autoincs and emits the reload
sequence before the reloaded insn.

For example, see inc_for_reload:
      /* Postincrement.
	 Because this might be a jump insn or a compare, and because RELOADREG
	 may not be available after the insn in an input reload, we must do
	 the incrementation before the insn being reloaded for.

On m68k with cc0 this is already necessary, because even a cmp insn
cannot have output reloads (they would overwrite the flags). This is why
I think it should be safe to allow them in jumps too.


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 4/4] Fix autoinc cbranch
  2019-11-24 20:47           ` Bernd Schmidt
@ 2019-11-24 22:20             ` Segher Boessenkool
  0 siblings, 0 replies; 87+ messages in thread
From: Segher Boessenkool @ 2019-11-24 22:20 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

On Sun, Nov 24, 2019 at 08:55:37PM +0100, Bernd Schmidt wrote:
> On 11/24/19 8:43 PM, Segher Boessenkool wrote:
> > But.  Allowing autoinc into jump insns means those jump insns may then
> > eventually need an output reload; it may just have been because of that?
> 
> That's almost certainly the reasoning, but as I pointed out in my
> original mail - reload is careful around autoincs and emits the reload
> sequence before the reloaded insn.

Yes, and that isn't anything new either.

Does LRA do this as well?  ...  Yes it does, see lra-constraints.c, search
for "Because this might be a jump" as well.

> For example, see inc_for_reload:
>       /* Postincrement.
> 	 Because this might be a jump insn or a compare, and because RELOADREG
> 	 may not be available after the insn in an input reload, we must do
> 	 the incrementation before the insn being reloaded for.
> 
> On m68k with cc0 this is already necessary, because even a cmp insn
> cannot have output reloads (they would overwrite the flags). This is why
> I think it should be safe to allow them in jumps too.

Yeah, auto-modify makes my head hurt :-)

Output reloads definitely are *not* safe in jumps, but auto-modify seems
to be indeed.


Segher

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-24 10:25           ` Bernd Schmidt
@ 2019-11-25 11:37             ` Andreas Schwab
  2019-11-25 12:33               ` Bernd Schmidt
  2019-11-28 20:00             ` Gunther Nikl
  1 sibling, 1 reply; 87+ messages in thread
From: Andreas Schwab @ 2019-11-25 11:37 UTC (permalink / raw)
  To: Bernd Schmidt
  Cc: Jeff Law, John Paul Adrian Glaubitz, gcc-patches, Mikael Pettersson

On Nov 24 2019, Bernd Schmidt wrote:

> Whew, I think I have it. One tst instruction eliminated when it
> shouldn't have been:
>
>         move.w %a4,%d0
> -       tst.b %d0
> -       jeq .L352
> +       jeq .L353
>
> And the reason - that's a movqi using move.w. The following should fix
> it.

Apparently that also fixed the testsuite regressions.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-25 11:37             ` Andreas Schwab
@ 2019-11-25 12:33               ` Bernd Schmidt
  2019-11-25 13:51                 ` Andreas Schwab
  0 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-25 12:33 UTC (permalink / raw)
  To: Andreas Schwab
  Cc: Jeff Law, John Paul Adrian Glaubitz, gcc-patches, Mikael Pettersson

On 11/25/19 12:26 PM, Andreas Schwab wrote:
> On Nov 24 2019, Bernd Schmidt wrote:
> 
>> Whew, I think I have it. One tst instruction eliminated when it
>> shouldn't have been:
>>
>>         move.w %a4,%d0
>> -       tst.b %d0
>> -       jeq .L352
>> +       jeq .L353
>>
>> And the reason - that's a movqi using move.w. The following should fix
>> it.
> 
> Apparently that also fixed the testsuite regressions.

I still wish I knew how you managed to reproduce those. That would have
been easier to debug than messing around with a three-stage
cross-to-native setup.


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-23 19:54       ` Jeff Law
  2019-11-23 20:53         ` Oleg Endo
  2019-11-23 22:34         ` Bernd Schmidt
@ 2019-11-25 12:34         ` Bernd Schmidt
  2019-11-25 12:38           ` John Paul Adrian Glaubitz
                             ` (2 more replies)
  2 siblings, 3 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-25 12:34 UTC (permalink / raw)
  To: Jeff Law, John Paul Adrian Glaubitz; +Cc: gcc-patches

On 11/23/19 6:36 PM, Jeff Law wrote:

> Not really.  I've already indicated to Bernd that he should go ahead and
> commit the changes and we can iterate on any problems that arise.

After the last fix, I did some more testing and since I feel confident
that it really is in good shape now, I committed it. Thanks!


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-25 12:34         ` Bernd Schmidt
@ 2019-11-25 12:38           ` John Paul Adrian Glaubitz
  2019-11-25 12:39             ` Bernd Schmidt
  2019-11-25 12:40           ` Tobias Burnus
  2019-11-26  0:49           ` Joseph Myers
  2 siblings, 1 reply; 87+ messages in thread
From: John Paul Adrian Glaubitz @ 2019-11-25 12:38 UTC (permalink / raw)
  To: Bernd Schmidt, Jeff Law; +Cc: gcc-patches

Hi Bernd!

On 11/25/19 1:33 PM, Bernd Schmidt wrote:
> On 11/23/19 6:36 PM, Jeff Law wrote:
> 
>> Not really.  I've already indicated to Bernd that he should go ahead and
>> commit the changes and we can iterate on any problems that arise.
> 
> After the last fix, I did some more testing and since I feel confident
> that it really is in good shape now, I committed it. Thanks!

Are all 4 + 2 patches in now? Thus, can we close the bug?

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaubitz@debian.org
`. `'   Freie Universitaet Berlin - glaubitz@physik.fu-berlin.de
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-25 12:38           ` John Paul Adrian Glaubitz
@ 2019-11-25 12:39             ` Bernd Schmidt
  2019-11-25 12:44               ` John Paul Adrian Glaubitz
  0 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-25 12:39 UTC (permalink / raw)
  To: John Paul Adrian Glaubitz, Jeff Law; +Cc: gcc-patches

On 11/25/19 1:34 PM, John Paul Adrian Glaubitz wrote:
> Are all 4 + 2 patches in now? Thus, can we close the bug?

We're missing one piece for better autoinc generation, but that's a
small optimization issue. The cc0 conversion is complete.


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-25 12:34         ` Bernd Schmidt
  2019-11-25 12:38           ` John Paul Adrian Glaubitz
@ 2019-11-25 12:40           ` Tobias Burnus
  2019-11-25 13:08             ` Bernd Schmidt
  2019-11-25 14:42             ` Segher Boessenkool
  2019-11-26  0:49           ` Joseph Myers
  2 siblings, 2 replies; 87+ messages in thread
From: Tobias Burnus @ 2019-11-25 12:40 UTC (permalink / raw)
  To: Bernd Schmidt, Jeff Law, John Paul Adrian Glaubitz; +Cc: gcc-patches

Hi Bernd,

Thanks for the m68k work! Can you also update 
https://gcc.gnu.org/backends.html ?
(Webseite repo ist now in git, cf. https://gcc.gnu.org/about.html#git )

Cheers,

Tobias

PS: I wonder whether some other archs also should be updated on that web 
page.

On 11/25/19 1:33 PM, Bernd Schmidt wrote:
> On 11/23/19 6:36 PM, Jeff Law wrote:
>
>> Not really.  I've already indicated to Bernd that he should go ahead and
>> commit the changes and we can iterate on any problems that arise.
> After the last fix, I did some more testing and since I feel confident
> that it really is in good shape now, I committed it. Thanks!
>
>
> Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-25 12:39             ` Bernd Schmidt
@ 2019-11-25 12:44               ` John Paul Adrian Glaubitz
  0 siblings, 0 replies; 87+ messages in thread
From: John Paul Adrian Glaubitz @ 2019-11-25 12:44 UTC (permalink / raw)
  To: Bernd Schmidt, Jeff Law; +Cc: gcc-patches

On 11/25/19 1:38 PM, Bernd Schmidt wrote:
> On 11/25/19 1:34 PM, John Paul Adrian Glaubitz wrote:
>> Are all 4 + 2 patches in now? Thus, can we close the bug?
> 
> We're missing one piece for better autoinc generation, but that's a
> small optimization issue. The cc0 conversion is complete.

Great. I have clicked "Accept" in Bountysource and hope the
remaining backers will, too.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaubitz@debian.org
`. `'   Freie Universitaet Berlin - glaubitz@physik.fu-berlin.de
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-25 12:40           ` Tobias Burnus
@ 2019-11-25 13:08             ` Bernd Schmidt
  2019-11-25 14:42             ` Segher Boessenkool
  1 sibling, 0 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-25 13:08 UTC (permalink / raw)
  To: Tobias Burnus, Jeff Law, John Paul Adrian Glaubitz; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 160 bytes --]

On 11/25/19 1:38 PM, Tobias Burnus wrote:
> Thanks for the m68k work! Can you also update
> https://gcc.gnu.org/backends.html ?

Committed as obvious.


Bernd


[-- Attachment #2: backends.diff --]
[-- Type: text/x-patch, Size: 706 bytes --]

commit f42834ad5e77c05cb6bc0908b8fc9282fec7fc19
Author: Bernd Schmidt <bernds_cb1@t-online.de>
Date:   Mon Nov 25 13:48:08 2019 +0100

    Change backends table to show m68k does not use cc0

diff --git a/htdocs/backends.html b/htdocs/backends.html
index c9449065..c4b916d3 100644
--- a/htdocs/backends.html
+++ b/htdocs/backends.html
@@ -89,7 +89,7 @@ iq2000     | ???   FICB       b  g  t
 lm32       |       F             g
 m32c       |    L  FI    l    b  g    s
 m32r       |       FI         b       s
-m68k       |   ?            cpb   i
+m68k       |   ?             pb   i
 mcore      |  ?    FI        pb mg    s
 mep        |       F C        b  g  t s
 microblaze |         CB           i   s

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-25 12:33               ` Bernd Schmidt
@ 2019-11-25 13:51                 ` Andreas Schwab
  0 siblings, 0 replies; 87+ messages in thread
From: Andreas Schwab @ 2019-11-25 13:51 UTC (permalink / raw)
  To: Bernd Schmidt
  Cc: Jeff Law, John Paul Adrian Glaubitz, gcc-patches, Mikael Pettersson

On Nov 25 2019, Bernd Schmidt wrote:

> On 11/25/19 12:26 PM, Andreas Schwab wrote:
>> On Nov 24 2019, Bernd Schmidt wrote:
>> 
>>> Whew, I think I have it. One tst instruction eliminated when it
>>> shouldn't have been:
>>>
>>>         move.w %a4,%d0
>>> -       tst.b %d0
>>> -       jeq .L352
>>> +       jeq .L353
>>>
>>> And the reason - that's a movqi using move.w. The following should fix
>>> it.
>> 
>> Apparently that also fixed the testsuite regressions.
>
> I still wish I knew how you managed to reproduce those.

It's undefined behaviour, so you can get all kinds of random results.
The binary diff clearly shows the missing tstb insns.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-25 12:40           ` Tobias Burnus
  2019-11-25 13:08             ` Bernd Schmidt
@ 2019-11-25 14:42             ` Segher Boessenkool
  2019-11-25 14:46               ` John Paul Adrian Glaubitz
  1 sibling, 1 reply; 87+ messages in thread
From: Segher Boessenkool @ 2019-11-25 14:42 UTC (permalink / raw)
  To: Tobias Burnus
  Cc: Bernd Schmidt, Jeff Law, John Paul Adrian Glaubitz, gcc-patches

Hi!

On Mon, Nov 25, 2019 at 01:38:53PM +0100, Tobias Burnus wrote:
> Thanks for the m68k work! Can you also update 
> https://gcc.gnu.org/backends.html ?

> PS: I wonder whether some other archs also should be updated on that web 
> page.

Possibly.  Probably?

But, do you have any particular suggestions?


Segher

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-25 14:42             ` Segher Boessenkool
@ 2019-11-25 14:46               ` John Paul Adrian Glaubitz
  2019-11-29 17:32                 ` Segher Boessenkool
  0 siblings, 1 reply; 87+ messages in thread
From: John Paul Adrian Glaubitz @ 2019-11-25 14:46 UTC (permalink / raw)
  To: Segher Boessenkool, Tobias Burnus; +Cc: Bernd Schmidt, Jeff Law, gcc-patches

On 11/25/19 3:40 PM, Segher Boessenkool wrote:
> On Mon, Nov 25, 2019 at 01:38:53PM +0100, Tobias Burnus wrote:
>> Thanks for the m68k work! Can you also update 
>> https://gcc.gnu.org/backends.html ?
> 
>> PS: I wonder whether some other archs also should be updated on that web 
>> page.
> 
> Possibly.  Probably?
> 
> But, do you have any particular suggestions?

For m68k, it should be added that a free simulator is available as qemu
has gained full emulation support for m68k as compared to the previous
ColdFire-only emulation, i.e. the question mark in the "S" column should
be removed.

Same applies to i386, s390 and tilegx. These are all supported by qemu.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaubitz@debian.org
`. `'   Freie Universitaet Berlin - glaubitz@physik.fu-berlin.de
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-25 12:34         ` Bernd Schmidt
  2019-11-25 12:38           ` John Paul Adrian Glaubitz
  2019-11-25 12:40           ` Tobias Burnus
@ 2019-11-26  0:49           ` Joseph Myers
  2019-11-26  2:22             ` Bernd Schmidt
  2 siblings, 1 reply; 87+ messages in thread
From: Joseph Myers @ 2019-11-26  0:49 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: Jeff Law, John Paul Adrian Glaubitz, gcc-patches

On Mon, 25 Nov 2019, Bernd Schmidt wrote:

> On 11/23/19 6:36 PM, Jeff Law wrote:
> 
> > Not really.  I've already indicated to Bernd that he should go ahead and
> > commit the changes and we can iterate on any problems that arise.
> 
> After the last fix, I did some more testing and since I feel confident
> that it really is in good shape now, I committed it. Thanks!

I'm seeing a libgcc build failure for coldfire in my build-many-glibcs.py 
bot (m68k-linux-gnu configured --with-arch=cf --disable-multilib).  That's 
building _mulsc3.o; I get assembler errors:

/tmp/ccvO6ZQR.s: Assembler messages:
/tmp/ccvO6ZQR.s:81: Error: invalid instruction for this architecture; 
needs M68K fpu (68020 [68k, 68ec020], 68030 [68ec030], 68040 [68ec040], 
68060 [68ec060], cpu32 [68330, 68331, 68332, 68333, 68334, 68336, 68340, 
68341, 68349, 68360]) -- statement `fcmp.x %fp0,%fp0' ignored
/tmp/ccvO6ZQR.s:98: Error: invalid instruction for this architecture; 
needs M68K fpu (68020 [68k, 68ec020], 68030 [68ec030], 68040 [68ec040], 
68060 [68ec060], cpu32 [68330, 68331, 68332, 68333, 68334, 68336, 68340, 
68341, 68349, 68360]) -- statement `fcmp.x %fp1,%fp1' ignored

I've not bisected, but r278642 was OK and r278694 had the failure, so I'm 
guessing it's probably this patch.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-26  0:49           ` Joseph Myers
@ 2019-11-26  2:22             ` Bernd Schmidt
  2019-11-26  2:45               ` Joseph Myers
  2019-11-26  8:04               ` John Paul Adrian Glaubitz
  0 siblings, 2 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-26  2:22 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Jeff Law, John Paul Adrian Glaubitz, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 544 bytes --]

On 11/26/19 1:36 AM, Joseph Myers wrote:
> I'm seeing a libgcc build failure for coldfire in my build-many-glibcs.py 
> bot (m68k-linux-gnu configured --with-arch=cf --disable-multilib).  That's 
> building _mulsc3.o; I get assembler errors:

I overlooked a difference in the 68881 vs coldfire patterns when I
combined them. They use different suffixes for register compares (I only
spotted the different constraints).

The following seems to fix the assembler failures. I cannot properly
test Coldfire however due to lack of hardware.


Bernd

[-- Attachment #2: cf-fcmp.diff --]
[-- Type: text/x-patch, Size: 1086 bytes --]

	* config/m68k/,68k.c (m68k_output_compare_fp): Use .d instead of .x
	for register compares on Coldfire.

diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 8d010ebe6e9..4b30c401e80 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -4501,7 +4501,12 @@ m68k_output_compare_fp (rtx op0, rtx op1, rtx_code code)
   if (op1 == CONST0_RTX (GET_MODE (op0)))
     {
       if (FP_REG_P (op0))
-	output_asm_insn ("ftst%.x %0", ops);
+	{
+	  if (TARGET_COLDFIRE_FPU)
+	    output_asm_insn ("ftst%.d %0", ops);
+	  else
+	    output_asm_insn ("ftst%.x %0", ops);
+	}
       else
 	output_asm_insn (("ftst%." + prec + " %0").c_str (), ops);
       return code;
@@ -4510,7 +4515,10 @@ m68k_output_compare_fp (rtx op0, rtx op1, rtx_code code)
   switch (which_alternative)
     {
     case 0:
-      output_asm_insn ("fcmp%.x %1,%0", ops);
+      if (TARGET_COLDFIRE_FPU)
+	output_asm_insn ("fcmp%.d %1,%0", ops);
+      else
+	output_asm_insn ("fcmp%.x %1,%0", ops);
       break;
     case 1:
       output_asm_insn (("fcmp%." + prec + " %f1,%0").c_str (), ops);

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-26  2:22             ` Bernd Schmidt
@ 2019-11-26  2:45               ` Joseph Myers
  2019-11-26  5:11                 ` Bernd Schmidt
  2019-11-26  8:04               ` John Paul Adrian Glaubitz
  1 sibling, 1 reply; 87+ messages in thread
From: Joseph Myers @ 2019-11-26  2:45 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: Jeff Law, John Paul Adrian Glaubitz, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2111 bytes --]

On Tue, 26 Nov 2019, Bernd Schmidt wrote:

> On 11/26/19 1:36 AM, Joseph Myers wrote:
> > I'm seeing a libgcc build failure for coldfire in my build-many-glibcs.py 
> > bot (m68k-linux-gnu configured --with-arch=cf --disable-multilib).  That's 
> > building _mulsc3.o; I get assembler errors:
> 
> I overlooked a difference in the 68881 vs coldfire patterns when I
> combined them. They use different suffixes for register compares (I only
> spotted the different constraints).
> 
> The following seems to fix the assembler failures. I cannot properly
> test Coldfire however due to lack of hardware.

Thanks for fixing this (this is not a review of the patch).

The soft-float ColdFire build (--with-arch=cf --with-cpu=54455 
--disable-multilib) successfully built libgcc and glibc, but ran into an 
ICE building the glibc tests.  Again, I've not bisected but this commit 
seems likely to be responsible.  Compile the attached preprocessed source 
with -O2.

during RTL pass: jump2
test-strncmp.c: In function 'test_main':
test-strncmp.c:477:1: internal compiler error: in patch_jump_insn, at cfgrtl.c:1291
0x767a92 patch_jump_insn
        /scratch/jmyers/glibc/many10/src/gcc/gcc/cfgrtl.c:1290
0x767b9f redirect_branch_edge
        /scratch/jmyers/glibc/many10/src/gcc/gcc/cfgrtl.c:1317
0x76a722 rtl_redirect_edge_and_branch
        /scratch/jmyers/glibc/many10/src/gcc/gcc/cfgrtl.c:1450
0x752e09 redirect_edge_and_branch(edge_def*, basic_block_def*)
        /scratch/jmyers/glibc/many10/src/gcc/gcc/cfghooks.c:373
0x122555c try_forward_edges
        /scratch/jmyers/glibc/many10/src/gcc/gcc/cfgcleanup.c:562
0x122555c try_optimize_cfg
        /scratch/jmyers/glibc/many10/src/gcc/gcc/cfgcleanup.c:2960
0x1226a8d cleanup_cfg(int)
        /scratch/jmyers/glibc/many10/src/gcc/gcc/cfgcleanup.c:3174
0x1226cb8 execute
        /scratch/jmyers/glibc/many10/src/gcc/gcc/cfgcleanup.c:3354
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.

-- 
Joseph S. Myers
joseph@codesourcery.com

[-- Attachment #2: Type: application/gzip, Size: 22567 bytes --]

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-26  2:45               ` Joseph Myers
@ 2019-11-26  5:11                 ` Bernd Schmidt
  2019-11-26 23:34                   ` Joseph Myers
  0 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-26  5:11 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Jeff Law, John Paul Adrian Glaubitz, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 569 bytes --]

On 11/26/19 3:21 AM, Joseph Myers wrote:
> 
> The soft-float ColdFire build (--with-arch=cf --with-cpu=54455 
> --disable-multilib) successfully built libgcc and glibc, but ran into an 
> ICE building the glibc tests.  Again, I've not bisected but this commit 
> seems likely to be responsible.  Compile the attached preprocessed source 
> with -O2.

Try the following. This seems to be the same (preexisting) problem which
got fixed for the normal 68k compare patterns, where an operand with
nonimmediate_operand predicate allows constants in its constraints.


Bernd

[-- Attachment #2: cf-cmp1.diff --]
[-- Type: text/x-patch, Size: 629 bytes --]

diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 25e0b73741f..d6df385787a 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -496,7 +496,7 @@
 ;; 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 cmp1_cf_constraints [(QI "dm") (HI "dm") (SI "mr,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")])
 

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-26  2:22             ` Bernd Schmidt
  2019-11-26  2:45               ` Joseph Myers
@ 2019-11-26  8:04               ` John Paul Adrian Glaubitz
  1 sibling, 0 replies; 87+ messages in thread
From: John Paul Adrian Glaubitz @ 2019-11-26  8:04 UTC (permalink / raw)
  To: Bernd Schmidt, Joseph Myers; +Cc: Jeff Law, Angelo Dureghello, gcc-patches

Hi Bernd!

On 11/26/19 2:44 AM, Bernd Schmidt wrote:
> I overlooked a difference in the 68881 vs coldfire patterns when I
> combined them. They use different suffixes for register compares (I only
> spotted the different constraints).
> 
> The following seems to fix the assembler failures. I cannot properly
> test Coldfire however due to lack of hardware.

Angelo Dureghello (CC'ed) does active kernel development work on ColdFire and
he might be able to help with testing on the platform. He also created two
open-source ColdFire SBCs [1, 2].

I do have multiple ColdFire boards myself, but they are currently not set
up and it would take me some time to get them running as I have never used
them before.

Adrian

> [1] http://sysam.it/cff_amcore.html
> [2] http://sysam.it/cff_stmark2.html

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaubitz@debian.org
`. `'   Freie Universitaet Berlin - glaubitz@physik.fu-berlin.de
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-26  5:11                 ` Bernd Schmidt
@ 2019-11-26 23:34                   ` Joseph Myers
  2019-11-27  8:45                     ` Richard Biener
  0 siblings, 1 reply; 87+ messages in thread
From: Joseph Myers @ 2019-11-26 23:34 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: Jeff Law, John Paul Adrian Glaubitz, gcc-patches

On Tue, 26 Nov 2019, Bernd Schmidt wrote:

> On 11/26/19 3:21 AM, Joseph Myers wrote:
> > 
> > The soft-float ColdFire build (--with-arch=cf --with-cpu=54455 
> > --disable-multilib) successfully built libgcc and glibc, but ran into an 
> > ICE building the glibc tests.  Again, I've not bisected but this commit 
> > seems likely to be responsible.  Compile the attached preprocessed source 
> > with -O2.
> 
> Try the following. This seems to be the same (preexisting) problem which
> got fixed for the normal 68k compare patterns, where an operand with
> nonimmediate_operand predicate allows constants in its constraints.

I confirm that this and the previous patch together allow both the 
ColdFire configurations in build-many-glibcs.py to complete clean builds 
of GCC, glibc and glibc tests.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-26 23:34                   ` Joseph Myers
@ 2019-11-27  8:45                     ` Richard Biener
  0 siblings, 0 replies; 87+ messages in thread
From: Richard Biener @ 2019-11-27  8:45 UTC (permalink / raw)
  To: Joseph Myers
  Cc: Bernd Schmidt, Jeff Law, John Paul Adrian Glaubitz, gcc-patches

On Wed, Nov 27, 2019 at 12:18 AM Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Tue, 26 Nov 2019, Bernd Schmidt wrote:
>
> > On 11/26/19 3:21 AM, Joseph Myers wrote:
> > >
> > > The soft-float ColdFire build (--with-arch=cf --with-cpu=54455
> > > --disable-multilib) successfully built libgcc and glibc, but ran into an
> > > ICE building the glibc tests.  Again, I've not bisected but this commit
> > > seems likely to be responsible.  Compile the attached preprocessed source
> > > with -O2.
> >
> > Try the following. This seems to be the same (preexisting) problem which
> > got fixed for the normal 68k compare patterns, where an operand with
> > nonimmediate_operand predicate allows constants in its constraints.
>
> I confirm that this and the previous patch together allow both the
> ColdFire configurations in build-many-glibcs.py to complete clean builds
> of GCC, glibc and glibc tests.

Both patches are OK.

Thanks,
Richard.

> --
> Joseph S. Myers
> joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-24 10:25           ` Bernd Schmidt
  2019-11-25 11:37             ` Andreas Schwab
@ 2019-11-28 20:00             ` Gunther Nikl
  2019-11-28 20:45               ` Bernd Schmidt
  1 sibling, 1 reply; 87+ messages in thread
From: Gunther Nikl @ 2019-11-28 20:00 UTC (permalink / raw)
  To: Bernd Schmidt
  Cc: Jeff Law, John Paul Adrian Glaubitz, gcc-patches, Mikael Pettersson

Bernd Schmidt <bernds_cb1@t-online.de>:
> On 11/23/19 9:53 PM, Bernd Schmidt wrote:
> > I'll spend a few more days trying to see if I can do something
> > about the bootstrap failure Mikael saw (currently trying to do a
> > two-stage cross build rather than a really slow bootstrap).  
> 
> Whew, I think I have it. One tst instruction eliminated when it
> shouldn't have been:
> 
>         move.w %a4,%d0
> -       tst.b %d0
> -       jeq .L352
> +       jeq .L353
> 
> And the reason - that's a movqi using move.w.

Can this problem also happen on older (pre-ccmode) GCC versions? Or was
this only an issue of the ccmode conversion?

What about the compare constraint errors? Are those also present on
older GCC versions but never surfaced?

Thanks,
Gunther

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-28 20:00             ` Gunther Nikl
@ 2019-11-28 20:45               ` Bernd Schmidt
  0 siblings, 0 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-28 20:45 UTC (permalink / raw)
  To: Gunther Nikl
  Cc: Jeff Law, John Paul Adrian Glaubitz, gcc-patches, Mikael Pettersson

On 11/28/19 8:53 PM, Gunther Nikl wrote:> Bernd Schmidt
<bernds_cb1@t-online.de>:
>> On 11/23/19 9:53 PM, Bernd Schmidt wrote:

>>         move.w %a4,%d0
>> -       tst.b %d0
>> -       jeq .L352
>> +       jeq .L353
>>
>> And the reason - that's a movqi using move.w.
>
> Can this problem also happen on older (pre-ccmode) GCC versions? Or was
> this only an issue of the ccmode conversion?

This was an error in the conversion (I think).

> What about the compare constraint errors? Are those also present on
> older GCC versions but never surfaced?

Those were present, but presumably nothing ever tried to rerecognize a
compare insn after reload (unlike jumps) so you wouldn't get a crash. I
haven't checked whether it could have produced invalid assembly - I'm
guessing probably not.


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 2/4] The main m68k cc0 conversion
  2019-11-25 14:46               ` John Paul Adrian Glaubitz
@ 2019-11-29 17:32                 ` Segher Boessenkool
  0 siblings, 0 replies; 87+ messages in thread
From: Segher Boessenkool @ 2019-11-29 17:32 UTC (permalink / raw)
  To: John Paul Adrian Glaubitz
  Cc: Tobias Burnus, Bernd Schmidt, Jeff Law, gcc-patches

On Mon, Nov 25, 2019 at 03:44:44PM +0100, John Paul Adrian Glaubitz wrote:
> On 11/25/19 3:40 PM, Segher Boessenkool wrote:
> > On Mon, Nov 25, 2019 at 01:38:53PM +0100, Tobias Burnus wrote:
> >> Thanks for the m68k work! Can you also update 
> >> https://gcc.gnu.org/backends.html ?
> > 
> >> PS: I wonder whether some other archs also should be updated on that web 
> >> page.
> > 
> > Possibly.  Probably?
> > 
> > But, do you have any particular suggestions?
> 
> For m68k, it should be added that a free simulator is available as qemu
> has gained full emulation support for m68k as compared to the previous
> ColdFire-only emulation, i.e. the question mark in the "S" column should
> be removed.
> 
> Same applies to i386, s390 and tilegx. These are all supported by qemu.

I've done this now (my first commit to the new git repo, wow that was
easy to do :-) )  Thanks for the suggestion!


Segher

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-17 16:19 Mikael Pettersson
  2019-11-17 16:58 ` Andreas Schwab
@ 2019-11-21 14:36 ` John Paul Adrian Glaubitz
  1 sibling, 0 replies; 87+ messages in thread
From: John Paul Adrian Glaubitz @ 2019-11-21 14:36 UTC (permalink / raw)
  To: Bernd Schmidt, 8736em8mp7.fsf,
	CAM43=SM3sAYrchnFUAEMhJCVQDe5+XXk4AooPSAHJ5XzN4hhhQ,
	962cf853-0809-f6ea-fbf7-48ac161e0cc6,
	CAM43=SNYtxVSQ0p8+xLtF7Xt4YC72u6fC=uVhaKWdhsJ3sVeTA,
	CAM43=SNYTYPC0b0igOLKCzopRNAsbhMvBywg=E2bYiY1MuUf=Q,
	b2907cb5-7ec9-a084-bb9f-08eafbbcd201,
	CAM43=SOGB6kf3=ChOrPGbc3mUSDkrRG0Fnq4-KtrgWASm+78jg,
	cb301ecc-fa10-bc73-92a9-dbb02a959032,
	21a75622-4af0-6f70-875e-60920af5e073,
	5a6841a0-fe62-da5e-13be-4bf324e4057f
  Cc: Matthias Klose, Richard Earnshaw, Mikael Pettersson,
	Andreas Schwab, gcc-patches

Hi Bernd!

This should work:

# binary default
deb http://ftp.ports.debian.org/debian-ports/ unstable main
deb http://incoming.ports.debian.org/buildd/ unstable main
deb http://ftp.ports.debian.org/debian-ports/ unreleased main

# source
deb-src http://ftp.debian.org/debian/ unstable main
deb-src http://incoming.debian.org/debian-buildd/ buildd-unstable main

The two lines starting with incoming are optional. They will just help getting newly
built packages faster.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaubitz@debian.org
`. `'   Freie Universitaet Berlin - glaubitz@physik.fu-berlin.de
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-21 12:32                   ` Matthias Klose
@ 2019-11-21 14:02                     ` Bernd Schmidt
  0 siblings, 0 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-21 14:02 UTC (permalink / raw)
  To: Matthias Klose, Richard Earnshaw, Mikael Pettersson
  Cc: Andreas Schwab, GCC Patches

On 11/21/19 1:30 PM, Matthias Klose wrote:
> 
> that would be apt build-dep gcc-9. The former would only install the build
> dependencies of the gcc-defaults package.

That gets me

E: You must put some 'source' URIs in your sources.list

where /etc/apt/sources.list looks like

  deb http://ftp.ports.debian.org/debian-ports sid main
  deb-src http://ftp.ports.debian.org/debian-ports sid main

which googling suggests is what I want?


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-20 22:18                 ` Richard Earnshaw
@ 2019-11-21 12:32                   ` Matthias Klose
  2019-11-21 14:02                     ` Bernd Schmidt
  0 siblings, 1 reply; 87+ messages in thread
From: Matthias Klose @ 2019-11-21 12:32 UTC (permalink / raw)
  To: Richard Earnshaw, Bernd Schmidt, Mikael Pettersson
  Cc: Andreas Schwab, GCC Patches

On 20.11.19 22:38, Richard Earnshaw wrote:
> On 20/11/2019 20:48, Bernd Schmidt wrote:
>> On 11/20/19 8:27 PM, Mikael Pettersson wrote:
>>> On Wed, Nov 20, 2019 at 3:16 PM Bernd Schmidt <bernds_cb1@t-online.de> wrote:
>>>> Probably best to just run tests on stage1 and hope something shows up.
>>>
>>> Ok, how do I did that?  I've always just done 'make -k check' after
>>> full bootstraps.
>>> I assume the stage 1 artifacts are the ones in the prev-* directories.
>>
>> There's a --disable-bootstrap configure option.
>>
>>>> What distro are you using for native builds? The m68k debian I'm using
>>>> does not have an installable gcc package.
>>>
>>> I run a bespoke distro on m68k and sparc64, derived from Fedora but
>>> massively cut down in size, with target patches done by myself or
>>> ported from Debian and Gentoo as necessary.
>>>
>>> Debian/m68k not having a gcc package?  That sounds odd; I see e.g. a
>>> gcc-9 in http://ftp.ports.debian.org/debian-ports/pool-m68k/main/g/
>>
>> Turns out I wasn't sufficiently familiar with how debian works. I was
>> missing an "apt update" step. I kind of assumed a package like gcc would
>> install out of the box (others did, things like emacs).
>>
>>
>> Bernd
>>
> 
> If you're building gcc on debian/ubuntu you probably also want
> 
>   apt build-dep gcc
> 
> to install all the packages needed for building the compiler.

that would be apt build-dep gcc-9. The former would only install the build
dependencies of the gcc-defaults package.

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-20 20:50               ` Bernd Schmidt
@ 2019-11-20 22:18                 ` Richard Earnshaw
  2019-11-21 12:32                   ` Matthias Klose
  0 siblings, 1 reply; 87+ messages in thread
From: Richard Earnshaw @ 2019-11-20 22:18 UTC (permalink / raw)
  To: Bernd Schmidt, Mikael Pettersson; +Cc: Andreas Schwab, GCC Patches

On 20/11/2019 20:48, Bernd Schmidt wrote:
> On 11/20/19 8:27 PM, Mikael Pettersson wrote:
>> On Wed, Nov 20, 2019 at 3:16 PM Bernd Schmidt <bernds_cb1@t-online.de> wrote:
>>> Probably best to just run tests on stage1 and hope something shows up.
>>
>> Ok, how do I did that?  I've always just done 'make -k check' after
>> full bootstraps.
>> I assume the stage 1 artifacts are the ones in the prev-* directories.
> 
> There's a --disable-bootstrap configure option.
> 
>>> What distro are you using for native builds? The m68k debian I'm using
>>> does not have an installable gcc package.
>>
>> I run a bespoke distro on m68k and sparc64, derived from Fedora but
>> massively cut down in size, with target patches done by myself or
>> ported from Debian and Gentoo as necessary.
>>
>> Debian/m68k not having a gcc package?  That sounds odd; I see e.g. a
>> gcc-9 in http://ftp.ports.debian.org/debian-ports/pool-m68k/main/g/
> 
> Turns out I wasn't sufficiently familiar with how debian works. I was
> missing an "apt update" step. I kind of assumed a package like gcc would
> install out of the box (others did, things like emacs).
> 
> 
> Bernd
> 

If you're building gcc on debian/ubuntu you probably also want

  apt build-dep gcc

to install all the packages needed for building the compiler.

R.

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-20 20:04             ` Mikael Pettersson
  2019-11-20 20:29               ` Jeff Law
@ 2019-11-20 20:50               ` Bernd Schmidt
  2019-11-20 22:18                 ` Richard Earnshaw
  1 sibling, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-20 20:50 UTC (permalink / raw)
  To: Mikael Pettersson; +Cc: Andreas Schwab, GCC Patches

On 11/20/19 8:27 PM, Mikael Pettersson wrote:
> On Wed, Nov 20, 2019 at 3:16 PM Bernd Schmidt <bernds_cb1@t-online.de> wrote:
>> Probably best to just run tests on stage1 and hope something shows up.
> 
> Ok, how do I did that?  I've always just done 'make -k check' after
> full bootstraps.
> I assume the stage 1 artifacts are the ones in the prev-* directories.

There's a --disable-bootstrap configure option.

>> What distro are you using for native builds? The m68k debian I'm using
>> does not have an installable gcc package.
> 
> I run a bespoke distro on m68k and sparc64, derived from Fedora but
> massively cut down in size, with target patches done by myself or
> ported from Debian and Gentoo as necessary.
> 
> Debian/m68k not having a gcc package?  That sounds odd; I see e.g. a
> gcc-9 in http://ftp.ports.debian.org/debian-ports/pool-m68k/main/g/

Turns out I wasn't sufficiently familiar with how debian works. I was
missing an "apt update" step. I kind of assumed a package like gcc would
install out of the box (others did, things like emacs).


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-20 20:04             ` Mikael Pettersson
@ 2019-11-20 20:29               ` Jeff Law
  2019-11-20 20:50               ` Bernd Schmidt
  1 sibling, 0 replies; 87+ messages in thread
From: Jeff Law @ 2019-11-20 20:29 UTC (permalink / raw)
  To: Mikael Pettersson, Bernd Schmidt; +Cc: Andreas Schwab, GCC Patches

On 11/20/19 12:27 PM, Mikael Pettersson wrote:
> On Wed, Nov 20, 2019 at 3:16 PM Bernd Schmidt
> <bernds_cb1@t-online.de> wrote:
>> 
>> On 11/20/19 2:50 PM, Mikael Pettersson wrote:
>>> On Mon, Nov 18, 2019 at 9:57 PM Mikael Pettersson
>>> <mikpelinux@gmail.com> wrote:
>>>> 
>>>> On Mon, Nov 18, 2019 at 8:31 PM Bernd Schmidt
>>>> <bernds_cb1@t-online.de> wrote:
>>>>> 
>>>>> Hi Mikael,
>>>>> 
>>>>>> This fixed the problem, thanks.
>>>>> 
>>>>> Could you also run the testsuite to see if you can reproduce
>>>>> the g++.old-deja failures Andreas reported?
>>>> 
>>>> Yes, but it will probably take another week before the native 
>>>> bootstrap (on aranym) and test suite run is finished.  It's
>>>> currently in stage 2.
>> 
>> Ugh, that suggests the stage2 compiler was miscompiled. That would
>> be nasty to track down.
>> 
>> Probably best to just run tests on stage1 and hope something shows
>> up.
> 
> Ok, how do I did that?  I've always just done 'make -k check' after 
> full bootstraps. I assume the stage 1 artifacts are the ones in the
> prev-* directories.
I do something like this


make all-gcc && make all-target-libgcc
cd gcc
make check-gcc


Jeff

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-20 14:29           ` Bernd Schmidt
  2019-11-20 16:59             ` Jeff Law
@ 2019-11-20 20:04             ` Mikael Pettersson
  2019-11-20 20:29               ` Jeff Law
  2019-11-20 20:50               ` Bernd Schmidt
  1 sibling, 2 replies; 87+ messages in thread
From: Mikael Pettersson @ 2019-11-20 20:04 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: Andreas Schwab, GCC Patches

On Wed, Nov 20, 2019 at 3:16 PM Bernd Schmidt <bernds_cb1@t-online.de> wrote:
>
> On 11/20/19 2:50 PM, Mikael Pettersson wrote:
> > On Mon, Nov 18, 2019 at 9:57 PM Mikael Pettersson <mikpelinux@gmail.com> wrote:
> >>
> >> On Mon, Nov 18, 2019 at 8:31 PM Bernd Schmidt <bernds_cb1@t-online.de> wrote:
> >>>
> >>> Hi Mikael,
> >>>
> >>>> This fixed the problem, thanks.
> >>>
> >>> Could you also run the testsuite to see if you can reproduce the
> >>> g++.old-deja failures Andreas reported?
> >>
> >> Yes, but it will probably take another week before the native
> >> bootstrap (on aranym) and test suite run is finished.  It's currently
> >> in stage 2.
>
> Ugh, that suggests the stage2 compiler was miscompiled. That would be
> nasty to track down.
>
> Probably best to just run tests on stage1 and hope something shows up.

Ok, how do I did that?  I've always just done 'make -k check' after
full bootstraps.
I assume the stage 1 artifacts are the ones in the prev-* directories.

> What distro are you using for native builds? The m68k debian I'm using
> does not have an installable gcc package.

I run a bespoke distro on m68k and sparc64, derived from Fedora but
massively cut down in size, with target patches done by myself or
ported from Debian and Gentoo as necessary.

Debian/m68k not having a gcc package?  That sounds odd; I see e.g. a
gcc-9 in http://ftp.ports.debian.org/debian-ports/pool-m68k/main/g/

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-20 14:29           ` Bernd Schmidt
@ 2019-11-20 16:59             ` Jeff Law
  2019-11-20 20:04             ` Mikael Pettersson
  1 sibling, 0 replies; 87+ messages in thread
From: Jeff Law @ 2019-11-20 16:59 UTC (permalink / raw)
  To: Bernd Schmidt, Mikael Pettersson; +Cc: Andreas Schwab, GCC Patches

On 11/20/19 7:16 AM, Bernd Schmidt wrote:
> On 11/20/19 2:50 PM, Mikael Pettersson wrote:
>> On Mon, Nov 18, 2019 at 9:57 PM Mikael Pettersson <mikpelinux@gmail.com> wrote:
>>>
>>> On Mon, Nov 18, 2019 at 8:31 PM Bernd Schmidt <bernds_cb1@t-online.de> wrote:
>>>>
>>>> Hi Mikael,
>>>>
>>>>> This fixed the problem, thanks.
>>>>
>>>> Could you also run the testsuite to see if you can reproduce the
>>>> g++.old-deja failures Andreas reported?
>>>
>>> Yes, but it will probably take another week before the native
>>> bootstrap (on aranym) and test suite run is finished.  It's currently
>>> in stage 2.
> 
> Ugh, that suggests the stage2 compiler was miscompiled. That would be
> nasty to track down.
> 
> Probably best to just run tests on stage1 and hope something shows up.
> 
> What distro are you using for native builds? The m68k debian I'm using
> does not have an installable gcc package.
Definitely agreed, best place to start is with teh stage1 testresults
and see if we can nail it down that way.

Debugging user mode qemu bits is *painful*.  For that we may ultimately
be better off with Aranym.

jeff

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-20 13:52         ` Mikael Pettersson
@ 2019-11-20 14:29           ` Bernd Schmidt
  2019-11-20 16:59             ` Jeff Law
  2019-11-20 20:04             ` Mikael Pettersson
  0 siblings, 2 replies; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-20 14:29 UTC (permalink / raw)
  To: Mikael Pettersson; +Cc: Andreas Schwab, GCC Patches

On 11/20/19 2:50 PM, Mikael Pettersson wrote:
> On Mon, Nov 18, 2019 at 9:57 PM Mikael Pettersson <mikpelinux@gmail.com> wrote:
>>
>> On Mon, Nov 18, 2019 at 8:31 PM Bernd Schmidt <bernds_cb1@t-online.de> wrote:
>>>
>>> Hi Mikael,
>>>
>>>> This fixed the problem, thanks.
>>>
>>> Could you also run the testsuite to see if you can reproduce the
>>> g++.old-deja failures Andreas reported?
>>
>> Yes, but it will probably take another week before the native
>> bootstrap (on aranym) and test suite run is finished.  It's currently
>> in stage 2.

Ugh, that suggests the stage2 compiler was miscompiled. That would be
nasty to track down.

Probably best to just run tests on stage1 and hope something shows up.

What distro are you using for native builds? The m68k debian I'm using
does not have an installable gcc package.


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-18 20:57       ` Mikael Pettersson
@ 2019-11-20 13:52         ` Mikael Pettersson
  2019-11-20 14:29           ` Bernd Schmidt
  0 siblings, 1 reply; 87+ messages in thread
From: Mikael Pettersson @ 2019-11-20 13:52 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: Andreas Schwab, GCC Patches

On Mon, Nov 18, 2019 at 9:57 PM Mikael Pettersson <mikpelinux@gmail.com> wrote:
>
> On Mon, Nov 18, 2019 at 8:31 PM Bernd Schmidt <bernds_cb1@t-online.de> wrote:
> >
> > Hi Mikael,
> >
> > > This fixed the problem, thanks.
> >
> > Could you also run the testsuite to see if you can reproduce the
> > g++.old-deja failures Andreas reported?
>
> Yes, but it will probably take another week before the native
> bootstrap (on aranym) and test suite run is finished.  It's currently
> in stage 2.

Failed later in stage 2:

/mnt/scratch/objdir10/./gcc/xgcc -B/mnt/scratch/objdir10/./gcc/
-B/mnt/scratch/install10/m68k-unknown-linux-gnu/bin/
-B/mnt/scratch/install10/m68k-unknown-linux-gnu/lib/ -isystem
/mnt/scratch/install10/m68k-unknown-linux-gnu/include -isystem
/mnt/scratch/install10/m68k-unknown-linux-gnu/sys-include
-fno-checking -g -O2 -O2  -g -O2 -DIN_GCC    -W -Wall -Wno-narrowing
-Wwrite-strings -Wcast-qual -Wno-error=format-diag -Wstrict-prototypes
-Wmissing-prototypes -Wno-error=format-diag -Wold-style-definition
-isystem ./include   -fPIC -g -DIN_LIBGCC2 -fbuilding-libgcc
-fno-stack-protector   -fPIC -I. -I. -I../.././gcc
-I/mnt/scratch/gcc-10-20191110/libgcc
-I/mnt/scratch/gcc-10-20191110/libgcc/.
-I/mnt/scratch/gcc-10-20191110/libgcc/../gcc
-I/mnt/scratch/gcc-10-20191110/libgcc/../include  -DHAVE_CC_TLS  -o
_powixf2.o -MT _powixf2.o -MD -MP -MF _powixf2.dep -DL_powixf2 -c
/mnt/scratch/gcc-10-20191110/libgcc/libgcc2.c -fvisibility=hidden
-DHIDE_EXPORTS
/mnt/scratch/gcc-10-20191110/libgcc/libgcc2.c: In function '__powixf2':
/mnt/scratch/gcc-10-20191110/libgcc/libgcc2.c:1888:1: error:
unrecognizable insn:
 1888 | }
      | ^
(insn 116 115 117 13 (parallel [
            (set (reg/f:SI 15 %sp)
                (plus:SI (reg/f:SI 15 %sp)
                    (const_int -12 [0xfffffffffffffff4])))
            (set (reg:XF 18 %fp2)
                (mem/c:XF (reg/f:SI 15 %sp) [3  S12 A8]))
        ]) "/mnt/scratch/gcc-10-20191110/libgcc/libgcc2.c":1888:1 -1
     (nil))
during RTL pass: cprop_hardreg
/mnt/scratch/gcc-10-20191110/libgcc/libgcc2.c:1888:1: internal
compiler error: in extract_insn, at recog.c:2294
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.
Makefile:500: recipe for target '_powixf2.o' failed
make[3]: *** [_powixf2.o] Error 1
make[3]: Leaving directory '/mnt/scratch/objdir10/m68k-unknown-linux-gnu/libgcc'
Makefile:16905: recipe for target 'all-stage2-target-libgcc' failed
make[2]: *** [all-stage2-target-libgcc] Error 2
make[2]: Leaving directory '/mnt/scratch/objdir10'
Makefile:20204: recipe for target 'stage2-bubble' failed
make[1]: *** [stage2-bubble] Error 2
make[1]: Leaving directory '/mnt/scratch/objdir10'
Makefile:20399: recipe for target 'bootstrap' failed
make: *** [bootstrap] Error 2

I'll try to reduce it to a test case later today.

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-18 19:39     ` Bernd Schmidt
@ 2019-11-18 20:57       ` Mikael Pettersson
  2019-11-20 13:52         ` Mikael Pettersson
  0 siblings, 1 reply; 87+ messages in thread
From: Mikael Pettersson @ 2019-11-18 20:57 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: Andreas Schwab, GCC Patches

On Mon, Nov 18, 2019 at 8:31 PM Bernd Schmidt <bernds_cb1@t-online.de> wrote:
>
> Hi Mikael,
>
> > This fixed the problem, thanks.
>
> Could you also run the testsuite to see if you can reproduce the
> g++.old-deja failures Andreas reported?

Yes, but it will probably take another week before the native
bootstrap (on aranym) and test suite run is finished.  It's currently
in stage 2.

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-17 19:45   ` Mikael Pettersson
@ 2019-11-18 19:39     ` Bernd Schmidt
  2019-11-18 20:57       ` Mikael Pettersson
  0 siblings, 1 reply; 87+ messages in thread
From: Bernd Schmidt @ 2019-11-18 19:39 UTC (permalink / raw)
  To: Mikael Pettersson, Andreas Schwab; +Cc: GCC Patches

Hi Mikael,

> This fixed the problem, thanks.

Could you also run the testsuite to see if you can reproduce the
g++.old-deja failures Andreas reported?


Bernd

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-17 16:58 ` Andreas Schwab
  2019-11-17 18:04   ` Jeff Law
@ 2019-11-17 19:45   ` Mikael Pettersson
  2019-11-18 19:39     ` Bernd Schmidt
  1 sibling, 1 reply; 87+ messages in thread
From: Mikael Pettersson @ 2019-11-17 19:45 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Bernd Schmidt, GCC Patches

On Sun, Nov 17, 2019 at 5:57 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
>
> On Nov 17 2019, Mikael Pettersson wrote:
>
> > /tmp/ccJA1qws.s:4828: Error: operands mismatch -- statement `seq %a1' ignored
> > /tmp/ccJA1qws.s:7344: Error: operands mismatch -- statement `seq %a1' ignored
>
> That should fix it:
>
> diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
> index 0cf063aaf84..3efcaad33a4 100644
> --- a/gcc/config/m68k/m68k.md
> +++ b/gcc/config/m68k/m68k.md
> @@ -698,7 +698,7 @@
>  })
>
>  (define_insn "cstore_bftst<mode>_insn"
> -  [(set (match_operand:QI 0 "register_operand")
> +  [(set (match_operand:QI 0 "register_operand" "=d")
>         (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")
>
> Andreas.

This fixed the problem, thanks.

/Mikael

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-17 16:58 ` Andreas Schwab
@ 2019-11-17 18:04   ` Jeff Law
  2019-11-17 19:45   ` Mikael Pettersson
  1 sibling, 0 replies; 87+ messages in thread
From: Jeff Law @ 2019-11-17 18:04 UTC (permalink / raw)
  To: Andreas Schwab, Mikael Pettersson; +Cc: Bernd Schmidt, GCC Patches

On 11/17/19 9:57 AM, Andreas Schwab wrote:
> On Nov 17 2019, Mikael Pettersson wrote:
> 
>> /tmp/ccJA1qws.s:4828: Error: operands mismatch -- statement `seq %a1' ignored
>> /tmp/ccJA1qws.s:7344: Error: operands mismatch -- statement `seq %a1' ignored
> 
> That should fix it:
> 
> diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
> index 0cf063aaf84..3efcaad33a4 100644
> --- a/gcc/config/m68k/m68k.md
> +++ b/gcc/config/m68k/m68k.md
> @@ -698,7 +698,7 @@
>  })
>  
>  (define_insn "cstore_bftst<mode>_insn"
> -  [(set (match_operand:QI 0 "register_operand")
> +  [(set (match_operand:QI 0 "register_operand" "=d")
>  	(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")
OK.

Bernd, presumably you can add this minor bugfix on top of your kit when
you install it?

Jeff

ps.  And to answer a question of Bernd's from a prior message.  I'm not
bootstrapping on real m68k hardware.  I'm using qemu user space
emulation + a native m68k chroot environment.   I've also used Aranym in
the past with good success.  I prefer the former because it's the same
core technology as other targets *and* since I'm just using user mode
emulation I can exploit whatever SMP resources are on the host.

jeff

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
  2019-11-17 16:19 Mikael Pettersson
@ 2019-11-17 16:58 ` Andreas Schwab
  2019-11-17 18:04   ` Jeff Law
  2019-11-17 19:45   ` Mikael Pettersson
  2019-11-21 14:36 ` John Paul Adrian Glaubitz
  1 sibling, 2 replies; 87+ messages in thread
From: Andreas Schwab @ 2019-11-17 16:58 UTC (permalink / raw)
  To: Mikael Pettersson; +Cc: Bernd Schmidt, GCC Patches

On Nov 17 2019, Mikael Pettersson wrote:

> /tmp/ccJA1qws.s:4828: Error: operands mismatch -- statement `seq %a1' ignored
> /tmp/ccJA1qws.s:7344: Error: operands mismatch -- statement `seq %a1' ignored

That should fix it:

diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 0cf063aaf84..3efcaad33a4 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -698,7 +698,7 @@
 })
 
 (define_insn "cstore_bftst<mode>_insn"
-  [(set (match_operand:QI 0 "register_operand")
+  [(set (match_operand:QI 0 "register_operand" "=d")
 	(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")

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 87+ messages in thread

* Re: [PATCH 0/4] Eliminate cc0 from m68k
@ 2019-11-17 16:19 Mikael Pettersson
  2019-11-17 16:58 ` Andreas Schwab
  2019-11-21 14:36 ` John Paul Adrian Glaubitz
  0 siblings, 2 replies; 87+ messages in thread
From: Mikael Pettersson @ 2019-11-17 16:19 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

On Wed, 13 Nov 2019 14:04:59 +0100, Bernd Schmidt
<bernds_cb1@t-online.de> wrote:
> This is a set of patches to convert m68k so that it no longer uses cc0.

Thank you for doing this.  I attempted a native bootstrap of
gcc-10-20191110 (r278028) plus the five patches posted so far on
m68k-linux (aranym), but it failed in stage 2:

/mnt/scratch/objdir10/./prev-gcc/xg++
-B/mnt/scratch/objdir10/./prev-gcc/
-B/mnt/scratch/install10/m68k-unknown-linux-gnu/bin/ -nostdinc++
-B/mnt/scratch/objdir10/prev-m68k-unknown-linux-gnu/libstdc++-v3/src/.libs
-B/mnt/scratch/objdir10/prev-m68k-unknown-linux-gnu/libstdc++-v3/libsupc++/.libs
 -I/mnt/scratch/objdir10/prev-m68k-unknown-linux-gnu/libstdc++-v3/include/m68k-unknown-linux-gnu
 -I/mnt/scratch/objdir10/prev-m68k-unknown-linux-gnu/libstdc++-v3/include
 -I/mnt/scratch/gcc-10-20191110/libstdc++-v3/libsupc++
-L/mnt/scratch/objdir10/prev-m68k-unknown-linux-gnu/libstdc++-v3/src/.libs
-L/mnt/scratch/objdir10/prev-m68k-unknown-linux-gnu/libstdc++-v3/libsupc++/.libs
-fno-PIE -c   -g -O2 -fno-checking -gtoggle -DIN_GCC
-fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall
-Wno-narrowing -Wwrite-strings -Wcast-qual -Wno-error=format-diag
-Wmissing-format-attribute -Woverloaded-virtual -pedantic
-Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror
-DHAVE_CONFIG_H -I. -I. -I/mnt/scratch/gcc-10-20191110/gcc
-I/mnt/scratch/gcc-10-20191110/gcc/.
-I/mnt/scratch/gcc-10-20191110/gcc/../include
-I/mnt/scratch/gcc-10-20191110/gcc/../libcpp/include
-I/mnt/scratch/gcc-10-20191110/gcc/../libdecnumber
-I/mnt/scratch/gcc-10-20191110/gcc/../libdecnumber/dpd
-I../libdecnumber -I/mnt/scratch/gcc-10-20191110/gcc/../libbacktrace
-o dbxout.o -MT dbxout.o -MMD -MP -MF ./.deps/dbxout.TPo
/mnt/scratch/gcc-10-20191110/gcc/dbxout.c
/tmp/ccJA1qws.s: Assembler messages:
/tmp/ccJA1qws.s:4828: Error: operands mismatch -- statement `seq %a1' ignored
/tmp/ccJA1qws.s:7344: Error: operands mismatch -- statement `seq %a1' ignored
Makefile:1118: recipe for target 'dbxout.o' failed
make[3]: *** [dbxout.o] Error 1
make[3]: Leaving directory '/mnt/scratch/objdir10/gcc'
Makefile:4740: recipe for target 'all-stage2-gcc' failed
make[2]: *** [all-stage2-gcc] Error 2
make[2]: Leaving directory '/mnt/scratch/objdir10'
Makefile:20204: recipe for target 'stage2-bubble' failed
make[1]: *** [stage2-bubble] Error 2
make[1]: Leaving directory '/mnt/scratch/objdir10'
Makefile:20399: recipe for target 'bootstrap' failed
make: *** [bootstrap] Error 2

An Scc instruction cannot have an address register as destination operand.

I don't have a reduced test case, but the error can be reproduced by
building a cross gcc to m68k-linux and then using that to build a
native gcc for m68k-linux.

/Mikael

^ permalink raw reply	[flat|nested] 87+ messages in thread

end of thread, other threads:[~2019-11-29 17:24 UTC | newest]

Thread overview: 87+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-13 13:08 [PATCH 0/4] Eliminate cc0 from m68k Bernd Schmidt
2019-11-13 13:09 ` [PATCH 1/4] Preliminary m68k patches Bernd Schmidt
2019-11-13 20:37   ` Jeff Law
2019-11-14 12:25     ` Bernd Schmidt
2019-11-17 18:27       ` Jeff Law
2019-11-18 16:52       ` Jeff Law
2019-11-13 13:13 ` [PATCH 2/4] The main m68k cc0 conversion Bernd Schmidt
2019-11-13 13:29   ` Bernd Schmidt
2019-11-17 18:00     ` Jeff Law
     [not found]       ` <5bba50b1-f8de-42fb-1057-208b52c847fb@t-online.de>
2019-11-18 17:42         ` Bernd Schmidt
2019-11-18 17:55           ` Jeff Law
2019-11-23 17:36     ` John Paul Adrian Glaubitz
2019-11-23 19:54       ` Jeff Law
2019-11-23 20:53         ` Oleg Endo
2019-11-24 18:09           ` Jeff Law
2019-11-23 22:34         ` Bernd Schmidt
2019-11-24 10:25           ` Bernd Schmidt
2019-11-25 11:37             ` Andreas Schwab
2019-11-25 12:33               ` Bernd Schmidt
2019-11-25 13:51                 ` Andreas Schwab
2019-11-28 20:00             ` Gunther Nikl
2019-11-28 20:45               ` Bernd Schmidt
2019-11-25 12:34         ` Bernd Schmidt
2019-11-25 12:38           ` John Paul Adrian Glaubitz
2019-11-25 12:39             ` Bernd Schmidt
2019-11-25 12:44               ` John Paul Adrian Glaubitz
2019-11-25 12:40           ` Tobias Burnus
2019-11-25 13:08             ` Bernd Schmidt
2019-11-25 14:42             ` Segher Boessenkool
2019-11-25 14:46               ` John Paul Adrian Glaubitz
2019-11-29 17:32                 ` Segher Boessenkool
2019-11-26  0:49           ` Joseph Myers
2019-11-26  2:22             ` Bernd Schmidt
2019-11-26  2:45               ` Joseph Myers
2019-11-26  5:11                 ` Bernd Schmidt
2019-11-26 23:34                   ` Joseph Myers
2019-11-27  8:45                     ` Richard Biener
2019-11-26  8:04               ` John Paul Adrian Glaubitz
2019-11-13 13:21 ` [PATCH 3/4] Set costs for jumps in combine Bernd Schmidt
2019-11-13 16:26   ` Segher Boessenkool
2019-11-21 13:53     ` Bernd Schmidt
2019-11-22  0:52       ` Segher Boessenkool
2019-11-22  1:09         ` Bernd Schmidt
2019-11-22  2:43         ` Paul Koning
2019-11-22 16:57           ` Segher Boessenkool
2019-11-13 13:24 ` [PATCH 4/4] Fix autoinc cbranch Bernd Schmidt
2019-11-19  0:36   ` Segher Boessenkool
2019-11-24 14:20     ` Bernd Schmidt
2019-11-24 17:48       ` Segher Boessenkool
2019-11-24 19:55         ` Segher Boessenkool
2019-11-24 20:47           ` Bernd Schmidt
2019-11-24 22:20             ` Segher Boessenkool
2019-11-13 18:58 ` [PATCH 0/4] Eliminate cc0 from m68k Segher Boessenkool
2019-11-13 19:07   ` Bernd Schmidt
2019-11-13 19:25     ` Segher Boessenkool
2019-11-15 13:48     ` John Paul Adrian Glaubitz
2019-11-15 14:36       ` John Paul Adrian Glaubitz
2019-11-13 19:41 ` Jeff Law
2019-11-14 15:00   ` Richard Henderson
2019-11-15 13:49 ` Andreas Schwab
2019-11-15 16:34   ` Bernd Schmidt
2019-11-15 16:36     ` Andreas Schwab
2019-11-15 21:41       ` Bernd Schmidt
2019-11-15 22:21         ` Andreas Schwab
2019-11-15 22:22           ` Bernd Schmidt
2019-11-15 22:57             ` Andreas Schwab
2019-11-16  0:17               ` Bernd Schmidt
2019-11-16  8:26                 ` Andreas Schwab
2019-11-16 13:32                   ` Bernd Schmidt
2019-11-16 10:47                 ` Andreas Schwab
2019-11-16 12:16               ` John Paul Adrian Glaubitz
2019-11-17 16:19 Mikael Pettersson
2019-11-17 16:58 ` Andreas Schwab
2019-11-17 18:04   ` Jeff Law
2019-11-17 19:45   ` Mikael Pettersson
2019-11-18 19:39     ` Bernd Schmidt
2019-11-18 20:57       ` Mikael Pettersson
2019-11-20 13:52         ` Mikael Pettersson
2019-11-20 14:29           ` Bernd Schmidt
2019-11-20 16:59             ` Jeff Law
2019-11-20 20:04             ` Mikael Pettersson
2019-11-20 20:29               ` Jeff Law
2019-11-20 20:50               ` Bernd Schmidt
2019-11-20 22:18                 ` Richard Earnshaw
2019-11-21 12:32                   ` Matthias Klose
2019-11-21 14:02                     ` Bernd Schmidt
2019-11-21 14:36 ` John Paul Adrian Glaubitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).