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")))