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
            * 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 "";
-})
-
 
 (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")))

Reply via email to