Mercurial > hg > CbC > CbC_gcc
diff gcc/config/m68k/m68k.md @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
line wrap: on
line diff
--- a/gcc/config/m68k/m68k.md Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/config/m68k/m68k.md Thu Feb 13 11:34:05 2020 +0900 @@ -1,5 +1,5 @@ ;;- Machine description for GNU compiler, Motorola 68000 Version -;; Copyright (C) 1987-2018 Free Software Foundation, Inc. +;; Copyright (C) 1987-2020 Free Software Foundation, Inc. ;; This file is part of GCC. @@ -250,6 +250,18 @@ ;; Alternative is OK for ColdFire. (define_attr "ok_for_coldfire" "yes,no" (const_string "yes")) +;; Instruction sets flags predictably to allow a following comparison to be +;; elided. +;; "no" means we should clear all flag state. "yes" means the destination +;; register is valid. "noov" is similar but does not allow tests that rely +;; on the overflow flag. "unchanged" means the instruction does not set the +;; flags (but we should still verify none of the remembered operands are +;; clobbered). "move" is a special case for which we remember both the +;; destination and the source. "set" is another special case where the +;; instruction pattern already performs the update and no more work is +;; required in postscan_insn. +(define_attr "flags_valid" "no,yes,set,noov,move,unchanged" (const_string "no")) + ;; Define 'enabled' attribute. (define_attr "enabled" "" (cond [(and (match_test "TARGET_COLDFIRE") @@ -303,150 +315,129 @@ DONE; }) -;; We don't want to allow a constant operand for test insns because -;; (set (cc0) (const_int foo)) has no mode information. Such insns will -;; be folded while optimizing anyway. - -(define_insn "tstdi" - [(set (cc0) - (compare (match_operand:DI 0 "nonimmediate_operand" "am,d") - (const_int 0))) - (clobber (match_scratch:SI 1 "=X,d")) - (clobber (match_scratch:DI 2 "=d,X"))] - "" -{ - 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])) - { - cc_status.flags |= CC_REVERSED; /*|*/ - return "neg%.l %R0\;negx%.l %0"; - } - 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)))] +;; 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"))] "" - "tst%.w %0" - [(set_attr "type" "tst")]) - -(define_insn "*tstqi_internal" - [(set (cc0) - (compare (match_operand:QI 0 "nonimmediate_operand" "dm") - (const_int 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])) + { + 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"))] "" - "tst%.b %0" - [(set_attr "type" "tst")]) - -(define_insn "tst<mode>_68881" - [(set (cc0) - (compare (match_operand:FP 0 "general_operand" "f<FP:dreg>m") - (match_operand:FP 1 "const0_operand" "H")))] - "TARGET_68881" -{ - cc_status.flags = CC_IN_68881; - if (FP_REG_P (operands[0])) - return "ftst%.x %0"; - return "ftst%.<FP:prec> %0"; -} - [(set_attr "type" "ftst")]) - -(define_insn "tst<mode>_cf" - [(set (cc0) - (compare (match_operand:FP 0 "general_operand" "f<FP:dreg><Q>U") - (match_operand:FP 1 "const0_operand" "H")))] - "TARGET_COLDFIRE_FPU" -{ - cc_status.flags = CC_IN_68881; - if (FP_REG_P (operands[0])) - return "ftst%.d %0"; - return "ftst%.<FP:prec> %0"; -} - [(set_attr "type" "ftst")]) - - -;; compare instructions. - -(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"))] +{ + 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])) + { + 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 "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"))] "" { - if (rtx_equal_p (operands[0], operands[1])) - return "sub%.l %R2,%R0\;subx%.l %2,%0"; - else - { - cc_status.flags |= CC_REVERSED; /*|*/ - return "sub%.l %R1,%R0\;subx%.l %1,%0"; - } -}) - -(define_insn "cmpdi" - [(set (cc0) - (compare (match_operand:DI 0 "nonimmediate_operand") - (match_operand:DI 1 "general_operand"))) - (clobber (match_scratch:DI 2))] - "" - "") - + 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,40 +447,38 @@ (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_expand "cbranchsi4" - [(set (cc0) - (compare (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:SI 2 "general_operand" ""))) - (set (pc) + 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 (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 "cstoresi4" - [(set (cc0) - (compare (match_operand:SI 2 "nonimmediate_operand" "") - (match_operand:SI 3 "general_operand" ""))) - (set (match_operand:QI 0 "register_operand") +(define_expand "cstore<mode>4" + [(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 @@ -497,315 +486,357 @@ ;; 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,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 +;; 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 "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")]) + +(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" +{ + 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" { - 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_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" +{ + 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_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" { - 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_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" +{ + rtx_code code = GET_CODE (operands[1]); + code = m68k_output_compare_<mode> (operands[2], operands[3], code); + return m68k_output_scc (code); } - [(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)]) + [(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)))] "" - "") - -(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,>") - (match_operand:HI 1 "general_operand" "d,rnm,m,n,>")))] - "!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"; -}) - -(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)]) +{ + 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); +}) + +;; 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)))] - "" - "") - -(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") + "!(REG_P (operands[1]) && !IN_RANGE (INTVAL (operands[2]), 0, 31))" +{ + rtx_code code = GET_CODE (operands[0]); + if (GET_CODE (operands[1]) == MEM) + { + 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); + } + 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" "=d") (match_operator:QI 1 "ordered_comparison_operator" - [(cc0) (const_int 0)]))] - "" - "") - -(define_insn "" - [(set (cc0) - (compare (match_operand:QI 0 "nonimmediate_operand" "dn,dm,>") - (match_operand:QI 1 "general_operand" "dm,nd,>")))] - "!TARGET_COLDFIRE" -{ - 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)) - { - cc_status.flags |= CC_REVERSED; /*|*/ - return "cmp%.b %d0,%d1"; - } - return "cmp%.b %d1,%d0"; -}) - + [(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" "") +;; ??? 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>mF") - (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")))] + && (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 "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[0], <MODE>mode) - || register_operand (operands[1], <MODE>mode))" - "@ - fcmp%.d %1,%0 - fcmp%.<FP:prec> %f1,%0 - fcmp%.<FP:prec> %0,%f1" - [(set_attr "type" "fcmp")]) - -;; Recognizers for btst instructions. - -;; ColdFire/5200 only allows "<Q>" type addresses when the bit position is -;; specified as a constant, so we must disable all patterns that may extract -;; from a MEM at a constant bit position if we can't use this as a constraint. - -(define_insn "" - [(set - (cc0) - (compare (zero_extract:SI (match_operand:QI 0 "memory_src_operand" "oS") - (const_int 1) - (minus:SI (const_int 7) - (match_operand:SI 1 "general_operand" "di"))) - (const_int 0)))] - "!TARGET_COLDFIRE" -{ - return output_btst (operands, operands[1], operands[0], insn, 7); -}) - -;; This is the same as the above pattern except for the constraints. The 'i' -;; has been deleted. - -(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" -{ - return output_btst (operands, operands[1], operands[0], insn, 7); -}) - -(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))" -{ - return output_btst (operands, operands[1], operands[0], insn, 31); -}) - -;; 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 "" - [(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)))] - "" -{ - return output_btst (operands, operands[1], operands[0], insn, 7); -}) - -(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 "register_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 "register_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); -}) - - + && (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 "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))" +{ + 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 "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))" +{ + 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 "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")]) + +;; 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" +{ + 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")]) + ;; move instructions ;; A special case in which it is not desirable @@ -964,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 @@ -976,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" @@ -1052,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" "")) @@ -1070,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" "") @@ -1088,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" "")) @@ -1106,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")) @@ -1200,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") @@ -1340,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") @@ -1461,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<>") @@ -1582,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") @@ -1602,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") @@ -1627,16 +1672,16 @@ "!TARGET_COLDFIRE" { if (GET_CODE (operands[0]) == REG) - { - /* Must clear condition codes, since the move.l bases them on - the entire 32 bits, not just the desired 8 bits. */ - CC_STATUS_INIT; - return "move%.l %1,%0"; - } + return "move%.l %1,%0"; + if (GET_CODE (operands[1]) == MEM) operands[1] = adjust_address (operands[1], QImode, 2); return "move%.w %1,%0"; -}) +} + [(set (attr "flags_valid") + (if_then_else (match_operand 0 "register_operand") + (const_string "no") + (const_string "yes")))]) ;; zero extension instructions @@ -1804,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"; @@ -1830,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"; @@ -1847,8 +1890,6 @@ (clobber (match_scratch:SI 2 "=X,d,d,d"))] "" { - CC_STATUS_INIT; - if (which_alternative == 0) /* Handle alternative 0. */ { @@ -1883,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) @@ -1975,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"; @@ -2004,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"; @@ -2137,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,%!"; }) @@ -2148,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,%!"; }) @@ -2159,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,%!"; }) @@ -2301,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])) @@ -2317,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 @@ -2332,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"; }) @@ -2346,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 @@ -2412,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, @@ -2431,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>") @@ -2476,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") @@ -2561,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])) { @@ -2582,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 @@ -2596,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 @@ -2633,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")) @@ -2645,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 @@ -2682,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") @@ -2709,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")) @@ -2827,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])) @@ -2843,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 @@ -2911,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] @@ -2930,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") @@ -2958,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" "") @@ -3240,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") @@ -3254,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 @@ -3289,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") @@ -3303,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" "") @@ -3483,19 +3514,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 +3541,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 +3556,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 +3583,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 +3597,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" { @@ -3578,19 +3609,16 @@ "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 "nonimmediate_operand" "=d") + (set (match_operand:HI 3 "register_operand" "=d") (umod:HI (match_dup 1) (match_dup 2)))] "!TARGET_COLDFIRE || TARGET_CF_HWDIV" { @@ -3606,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 ""; }) @@ -3644,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") @@ -3669,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")) @@ -3716,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 @@ -3747,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") @@ -3756,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") @@ -3777,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. @@ -3810,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 @@ -3827,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, @@ -3855,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") @@ -3864,49 +3899,56 @@ "TARGET_COLDFIRE" { return output_xorsi3 (operands); -}) +} + [(set_attr "flags_valid" "set")]) (define_insn "xorhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "=dm") (xor:HI (match_operand:HI 1 "general_operand" "%0") (match_operand:HI 2 "general_operand" "dn")))] "!TARGET_COLDFIRE" - "eor%.w %2,%0") + "eor%.w %2,%0" + [(set_attr "flags_valid" "yes")]) (define_insn "" [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm")) (xor:HI (match_dup 0) (match_operand:HI 1 "general_operand" "dn")))] "!TARGET_COLDFIRE" - "eor%.w %1,%0") + "eor%.w %1,%0" + [(set_attr "flags_valid" "yes")]) (define_insn "" [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm")) (xor:HI (match_operand:HI 1 "general_operand" "dn") (match_dup 0)))] "!TARGET_COLDFIRE" - "eor%.w %1,%0") + "eor%.w %1,%0" + [(set_attr "flags_valid" "yes")]) (define_insn "xorqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "=dm") (xor:QI (match_operand:QI 1 "general_operand" "%0") (match_operand:QI 2 "general_operand" "dn")))] "!TARGET_COLDFIRE" - "eor%.b %2,%0") + "eor%.b %2,%0" + [(set_attr "flags_valid" "yes")]) (define_insn "" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm")) (xor:QI (match_dup 0) (match_operand:QI 1 "general_operand" "dn")))] "!TARGET_COLDFIRE" - "eor%.b %1,%0") + "eor%.b %1,%0" + [(set_attr "flags_valid" "yes")]) (define_insn "" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm")) (xor:QI (match_operand:QI 1 "general_operand" "dn") (match_dup 0)))] "!TARGET_COLDFIRE" - "eor%.b %1,%0") + "eor%.b %1,%0" + [(set_attr "flags_valid" "yes")]) ;; negation instructions @@ -3965,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. @@ -4290,20 +4338,14 @@ [(set (match_operand:SI 0 "register_operand" "=d") (clz:SI (match_operand:SI 1 "general_operand" "do")))] "TARGET_68020 && TARGET_BITFIELD" -{ - CC_STATUS_INIT; - return "bfffo %1{#0:#0},%0"; -}) + "bfffo %1{#0:#0},%0") ;; ColdFire ff1 instruction implements clz. (define_insn "*clzsi2_cf" [(set (match_operand:SI 0 "register_operand" "=d") (clz:SI (match_operand:SI 1 "register_operand" "0")))] "ISA_HAS_FF1" -{ - CC_STATUS_INIT; - return "ff1 %0"; -} + "ff1 %0" [(set_attr "type" "ext")]) ;; one complement instructions @@ -4324,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") @@ -4337,25 +4380,29 @@ [(set (match_operand:HI 0 "nonimmediate_operand" "=dm") (not:HI (match_operand:HI 1 "general_operand" "0")))] "!TARGET_COLDFIRE" - "not%.w %0") + "not%.w %0" + [(set_attr "flags_valid" "yes")]) (define_insn "" [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+dm")) (not:HI (match_dup 0)))] "!TARGET_COLDFIRE" - "not%.w %0") + "not%.w %0" + [(set_attr "flags_valid" "yes")]) (define_insn "one_cmplqi2" [(set (match_operand:QI 0 "nonimmediate_operand" "=dm") (not:QI (match_operand:QI 1 "general_operand" "0")))] "!TARGET_COLDFIRE" - "not%.b %0") + "not%.b %0" + [(set_attr "flags_valid" "yes")]) (define_insn "" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+dm")) (not:QI (match_dup 0)))] "!TARGET_COLDFIRE" - "not%.b %0") + "not%.b %0" + [(set_attr "flags_valid" "yes")]) ;; arithmetic shift instructions ;; We don't need the shift memory by 1 bit instruction @@ -4379,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) @@ -4577,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. @@ -4595,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"; }) @@ -4608,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. @@ -4695,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"; }) @@ -4761,7 +4806,6 @@ (const_int 32)))] "" { - CC_STATUS_INIT; if (TARGET_68020) return "move%.l %1,%R0\;smi %0\;extb%.l %0"; else @@ -4775,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); @@ -4808,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) @@ -4858,35 +4900,40 @@ "" "asr%.l %2,%0" [(set_attr "type" "shift") - (set_attr "opy" "2")]) + (set_attr "opy" "2") + (set_attr "flags_valid" "noov")]) (define_insn "ashrhi3" [(set (match_operand:HI 0 "register_operand" "=d") (ashiftrt:HI (match_operand:HI 1 "register_operand" "0") (match_operand:HI 2 "general_operand" "dI")))] "!TARGET_COLDFIRE" - "asr%.w %2,%0") + "asr%.w %2,%0" + [(set_attr "flags_valid" "noov")]) (define_insn "" [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) (ashiftrt:HI (match_dup 0) (match_operand:HI 1 "general_operand" "dI")))] "!TARGET_COLDFIRE" - "asr%.w %1,%0") + "asr%.w %1,%0" + [(set_attr "flags_valid" "noov")]) (define_insn "ashrqi3" [(set (match_operand:QI 0 "register_operand" "=d") (ashiftrt:QI (match_operand:QI 1 "register_operand" "0") (match_operand:QI 2 "general_operand" "dI")))] "!TARGET_COLDFIRE" - "asr%.b %2,%0") + "asr%.b %2,%0" + [(set_attr "flags_valid" "noov")]) (define_insn "" [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) (ashiftrt:QI (match_dup 0) (match_operand:QI 1 "general_operand" "dI")))] "!TARGET_COLDFIRE" - "asr%.b %1,%0") + "asr%.b %1,%0" + [(set_attr "flags_valid" "noov")]) ;; logical shift instructions @@ -4933,7 +4980,6 @@ (const_int 1)))] "!TARGET_COLDFIRE" { - CC_STATUS_INIT; return "lsr%.l #1,%0\;roxr%.l #1,%R0"; }) @@ -5131,7 +5177,6 @@ (const_int 16)))] "!TUNE_68060" { - CC_STATUS_INIT; return "clr%.w %0\;swap %0"; }) @@ -5157,35 +5202,40 @@ "" "lsr%.l %2,%0" [(set_attr "type" "shift") - (set_attr "opy" "2")]) + (set_attr "opy" "2") + (set_attr "flags_valid" "yes")]) (define_insn "lshrhi3" [(set (match_operand:HI 0 "register_operand" "=d") (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") (match_operand:HI 2 "general_operand" "dI")))] "!TARGET_COLDFIRE" - "lsr%.w %2,%0") + "lsr%.w %2,%0" + [(set_attr "flags_valid" "yes")]) (define_insn "" [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) (lshiftrt:HI (match_dup 0) (match_operand:HI 1 "general_operand" "dI")))] "!TARGET_COLDFIRE" - "lsr%.w %1,%0") + "lsr%.w %1,%0" + [(set_attr "flags_valid" "yes")]) (define_insn "lshrqi3" [(set (match_operand:QI 0 "register_operand" "=d") (lshiftrt:QI (match_operand:QI 1 "register_operand" "0") (match_operand:QI 2 "general_operand" "dI")))] "!TARGET_COLDFIRE" - "lsr%.b %2,%0") + "lsr%.b %2,%0" + [(set_attr "flags_valid" "yes")]) (define_insn "" [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) (lshiftrt:QI (match_dup 0) (match_operand:QI 1 "general_operand" "dI")))] "!TARGET_COLDFIRE" - "lsr%.b %1,%0") + "lsr%.b %1,%0" + [(set_attr "flags_valid" "yes")]) ;; rotate instructions @@ -5195,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") @@ -5212,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") @@ -5227,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")) @@ -5242,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") @@ -5257,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")) @@ -5272,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") @@ -5300,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") @@ -5332,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 @@ -5346,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" @@ -5359,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" @@ -5372,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" @@ -5385,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 @@ -5399,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 @@ -5414,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 @@ -5500,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"; @@ -5586,15 +5623,6 @@ (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"; }) @@ -5609,7 +5637,6 @@ || (GET_CODE (operands[1]) == CONST_INT && (~ INTVAL (operands[3]) & ((1 << INTVAL (operands[1]))- 1)) == 0))" { - CC_STATUS_INIT; return "bfchg %0{%b2:%b1}"; }) @@ -5620,7 +5647,6 @@ (const_int 0))] "TARGET_68020 && TARGET_BITFIELD" { - CC_STATUS_INIT; return "bfclr %0{%b2:%b1}"; }) @@ -5631,7 +5657,6 @@ (const_int -1))] "TARGET_68020 && TARGET_BITFIELD" { - CC_STATUS_INIT; return "bfset %0{%b2:%b1}"; }) @@ -5680,15 +5705,6 @@ (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"; }) @@ -5699,7 +5715,6 @@ (const_int 0))] "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)" { - CC_STATUS_INIT; return "bfclr %0{%b2:%b1}"; }) @@ -5710,7 +5725,6 @@ (const_int -1))] "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)" { - CC_STATUS_INIT; return "bfset %0{%b2:%b1}"; }) @@ -5733,58 +5747,6 @@ return "bfins %3,%0{%b2:%b1}"; }) -;; Special patterns for optimizing bit-field instructions. - -(define_insn "*tst_bftst_mem" - [(set (cc0) - (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o") - (match_operand:SI 1 "const_int_operand" "n") - (match_operand:SI 2 "general_operand" "dn")) - (const_int 0)))] - "TARGET_68020 && TARGET_BITFIELD" -{ - if (operands[1] == const1_rtx - && GET_CODE (operands[2]) == CONST_INT) - { - int width = GET_CODE (operands[0]) == REG ? 31 : 7; - return output_btst (operands, - GEN_INT (width - INTVAL (operands[2])), - operands[0], insn, 1000); - /* Pass 1000 as SIGNPOS argument so that btst will - not think we are testing the sign bit for an `and' - and assume that nonzero implies a negative result. */ - } - if (INTVAL (operands[1]) != 32) - cc_status.flags = CC_NOT_NEGATIVE; - return "bftst %0{%b2:%b1}"; -}) - - -;;; now handle the register cases -(define_insn "*tst_bftst_reg" - [(set (cc0) - (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "const_int_operand" "n") - (match_operand:SI 2 "general_operand" "dn")) - (const_int 0)))] - "TARGET_68020 && TARGET_BITFIELD - && !(CONST_INT_P (operands[2]) && !IN_RANGE (INTVAL (operands[2]), 0, 31))" -{ - if (operands[1] == const1_rtx - && GET_CODE (operands[2]) == CONST_INT) - { - int width = GET_CODE (operands[0]) == REG ? 31 : 7; - return output_btst (operands, GEN_INT (width - INTVAL (operands[2])), - operands[0], insn, 1000); - /* Pass 1000 as SIGNPOS argument so that btst will - not think we are testing the sign bit for an `and' - and assume that nonzero implies a negative result. */ - } - if (INTVAL (operands[1]) != 32) - cc_status.flags = CC_NOT_NEGATIVE; - return "bftst %0{%b2:%b1}"; -}) - (define_insn "scc0_di" [(set (match_operand:QI 0 "nonimmediate_operand" "=dm") (match_operator 1 "ordered_comparison_operator" @@ -5822,879 +5784,6 @@ { return output_scc_di (operands[1], operands[2], operands[3], operands[0]); }) - -;; Note that operand 0 of an SCC insn is supported in the hardware as -;; memory, but we cannot allow it to be in memory in case the address -;; needs to be reloaded. - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=d") - (eq:QI (cc0) (const_int 0)))] - "" -{ - cc_status = cc_prev_status; - OUTPUT_JUMP ("seq %0", "fseq %0", "seq %0"); -}) - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=d") - (ne:QI (cc0) (const_int 0)))] - "" -{ - cc_status = cc_prev_status; - OUTPUT_JUMP ("sne %0", "fsne %0", "sne %0"); -}) - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=d") - (gt:QI (cc0) (const_int 0)))] - "" -{ - cc_status = cc_prev_status; - OUTPUT_JUMP ("sgt %0", "fsgt %0", 0); -}) - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=d") - (gtu:QI (cc0) (const_int 0)))] - "" -{ - cc_status = cc_prev_status; - return "shi %0"; -}) - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=d") - (lt:QI (cc0) (const_int 0)))] - "" -{ - cc_status = cc_prev_status; - OUTPUT_JUMP ("slt %0", "fslt %0", "smi %0"); -}) - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=d") - (ltu:QI (cc0) (const_int 0)))] - "" -{ - cc_status = cc_prev_status; - return "scs %0"; -}) - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=d") - (ge:QI (cc0) (const_int 0)))] - "" -{ - cc_status = cc_prev_status; - OUTPUT_JUMP ("sge %0", "fsge %0", "spl %0"); -}) - -(define_insn "*scc" - [(set (match_operand:QI 0 "register_operand" "=d") - (geu:QI (cc0) (const_int 0)))] - "" -{ - cc_status = cc_prev_status; - return "scc %0"; -} - [(set_attr "type" "scc")]) - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=d") - (le:QI (cc0) (const_int 0)))] - "" -{ - cc_status = cc_prev_status; - OUTPUT_JUMP ("sle %0", "fsle %0", 0); -}) - -(define_insn "*sls" - [(set (match_operand:QI 0 "register_operand" "=d") - (leu:QI (cc0) (const_int 0)))] - "" -{ - cc_status = cc_prev_status; - return "sls %0"; -} - [(set_attr "type" "scc")]) - -(define_insn "*sordered_1" - [(set (match_operand:QI 0 "register_operand" "=d") - (ordered:QI (cc0) (const_int 0)))] - "TARGET_68881 && !TUNE_68060" -{ - cc_status = cc_prev_status; - return "fsor %0"; -}) - -(define_insn "*sunordered_1" - [(set (match_operand:QI 0 "register_operand" "=d") - (unordered:QI (cc0) (const_int 0)))] - "TARGET_68881 && !TUNE_68060" -{ - cc_status = cc_prev_status; - return "fsun %0"; -}) - -(define_insn "*suneq_1" - [(set (match_operand:QI 0 "register_operand" "=d") - (uneq:QI (cc0) (const_int 0)))] - "TARGET_68881 && !TUNE_68060" -{ - cc_status = cc_prev_status; - return "fsueq %0"; -}) - -(define_insn "*sunge_1" - [(set (match_operand:QI 0 "register_operand" "=d") - (unge:QI (cc0) (const_int 0)))] - "TARGET_68881 && !TUNE_68060" -{ - cc_status = cc_prev_status; - return "fsuge %0"; -}) - -(define_insn "*sungt_1" - [(set (match_operand:QI 0 "register_operand" "=d") - (ungt:QI (cc0) (const_int 0)))] - "TARGET_68881 && !TUNE_68060" -{ - cc_status = cc_prev_status; - return "fsugt %0"; -}) - -(define_insn "*sunle_1" - [(set (match_operand:QI 0 "register_operand" "=d") - (unle:QI (cc0) (const_int 0)))] - "TARGET_68881 && !TUNE_68060" -{ - cc_status = cc_prev_status; - return "fsule %0"; -}) - -(define_insn "*sunlt_1" - [(set (match_operand:QI 0 "register_operand" "=d") - (unlt:QI (cc0) (const_int 0)))] - "TARGET_68881 && !TUNE_68060" -{ - cc_status = cc_prev_status; - return "fsult %0"; -}) - -(define_insn "*sltgt_1" - [(set (match_operand:QI 0 "register_operand" "=d") - (ltgt:QI (cc0) (const_int 0)))] - "TARGET_68881 && !TUNE_68060" -{ - cc_status = cc_prev_status; - return "fsogl %0"; -}) - -(define_insn "*fsogt_1" - [(set (match_operand:QI 0 "register_operand" "=d") - (not:QI (unle:QI (cc0) (const_int 0))))] - "TARGET_68881 && !TUNE_68060" -{ - cc_status = cc_prev_status; - return "fsogt %0"; -}) - -(define_insn "*fsoge_1" - [(set (match_operand:QI 0 "register_operand" "=d") - (not:QI (unlt:QI (cc0) (const_int 0))))] - "TARGET_68881 && !TUNE_68060" -{ - cc_status = cc_prev_status; - return "fsoge %0"; -}) - -(define_insn "*fsolt_1" - [(set (match_operand:QI 0 "register_operand" "=d") - (not:QI (unge:QI (cc0) (const_int 0))))] - "TARGET_68881 && !TUNE_68060" -{ - cc_status = cc_prev_status; - return "fsolt %0"; -}) - -(define_insn "*fsole_1" - [(set (match_operand:QI 0 "register_operand" "=d") - (not:QI (ungt:QI (cc0) (const_int 0))))] - "TARGET_68881 && !TUNE_68060" -{ - cc_status = cc_prev_status; - return "fsole %0"; -}) - -;; Basic conditional jump instructions. - -(define_insn "beq0_di" - [(set (pc) - (if_then_else (eq (match_operand:DI 0 "general_operand" "d*a,o,<>") - (const_int 0)) - (label_ref (match_operand 1 "" ",,")) - (pc))) - (clobber (match_scratch:SI 2 "=d,&d,d"))] - "" -{ - CC_STATUS_INIT; - if (which_alternative == 2) - return "move%.l %0,%2\;or%.l %0,%2\;jeq %l1"; - if ((cc_prev_status.value1 - && rtx_equal_p (cc_prev_status.value1, operands[0])) - || (cc_prev_status.value2 - && rtx_equal_p (cc_prev_status.value2, operands[0]))) - { - cc_status = cc_prev_status; - return "jeq %l1"; - } - if (GET_CODE (operands[0]) == REG) - operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - else - operands[3] = adjust_address (operands[0], SImode, 4); - if (! ADDRESS_REG_P (operands[0])) - { - if (reg_overlap_mentioned_p (operands[2], operands[0])) - { - if (reg_overlap_mentioned_p (operands[2], operands[3])) - return "or%.l %0,%2\;jeq %l1"; - else - return "or%.l %3,%2\;jeq %l1"; - } - return "move%.l %0,%2\;or%.l %3,%2\;jeq %l1"; - } - operands[4] = gen_label_rtx(); - if (TARGET_68020 || TARGET_COLDFIRE) - output_asm_insn ("tst%.l %0\;jne %l4\;tst%.l %3\;jeq %l1", operands); - else - output_asm_insn ("cmp%.w #0,%0\;jne %l4\;cmp%.w #0,%3\;jeq %l1", operands); - (*targetm.asm_out.internal_label) (asm_out_file, "L", - CODE_LABEL_NUMBER (operands[4])); - return ""; -}) - -(define_insn "bne0_di" - [(set (pc) - (if_then_else (ne (match_operand:DI 0 "general_operand" "d,o,*a") - (const_int 0)) - (label_ref (match_operand 1 "" ",,")) - (pc))) - (clobber (match_scratch:SI 2 "=d,&d,X"))] - "" -{ - if ((cc_prev_status.value1 - && rtx_equal_p (cc_prev_status.value1, operands[0])) - || (cc_prev_status.value2 - && rtx_equal_p (cc_prev_status.value2, operands[0]))) - { - cc_status = cc_prev_status; - return "jne %l1"; - } - CC_STATUS_INIT; - if (GET_CODE (operands[0]) == REG) - operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - else - operands[3] = adjust_address (operands[0], SImode, 4); - if (!ADDRESS_REG_P (operands[0])) - { - if (reg_overlap_mentioned_p (operands[2], operands[0])) - { - if (reg_overlap_mentioned_p (operands[2], operands[3])) - return "or%.l %0,%2\;jne %l1"; - else - return "or%.l %3,%2\;jne %l1"; - } - return "move%.l %0,%2\;or%.l %3,%2\;jne %l1"; - } - if (TARGET_68020 || TARGET_COLDFIRE) - return "tst%.l %0\;jne %l1\;tst%.l %3\;jne %l1"; - else - return "cmp%.w #0,%0\;jne %l1\;cmp%.w #0,%3\;jne %l1"; -}) - -(define_insn "bge0_di" - [(set (pc) - (if_then_else (ge (match_operand:DI 0 "general_operand" "ro") - (const_int 0)) - (label_ref (match_operand 1 "" "")) - (pc)))] - "" -{ - if ((cc_prev_status.value1 - && rtx_equal_p (cc_prev_status.value1, operands[0])) - || (cc_prev_status.value2 - && rtx_equal_p (cc_prev_status.value2, operands[0]))) - { - cc_status = cc_prev_status; - return cc_status.flags & CC_REVERSED ? "jle %l1" : "jpl %l1"; - } - CC_STATUS_INIT; - if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (operands[0])) - output_asm_insn("tst%.l %0", operands); - else - { - /* On an address reg, cmpw may replace cmpl. */ - output_asm_insn("cmp%.w #0,%0", operands); - } - return "jpl %l1"; -}) - -(define_insn "blt0_di" - [(set (pc) - (if_then_else (lt (match_operand:DI 0 "general_operand" "ro") - (const_int 0)) - (label_ref (match_operand 1 "" "")) - (pc)))] - "" -{ - if ((cc_prev_status.value1 - && rtx_equal_p (cc_prev_status.value1, operands[0])) - || (cc_prev_status.value2 - && rtx_equal_p (cc_prev_status.value2, operands[0]))) - { - cc_status = cc_prev_status; - return cc_status.flags & CC_REVERSED ? "jgt %l1" : "jmi %l1"; - } - CC_STATUS_INIT; - if (TARGET_68020 || TARGET_COLDFIRE || ! ADDRESS_REG_P (operands[0])) - output_asm_insn("tst%.l %0", operands); - else - { - /* On an address reg, cmpw may replace cmpl. */ - output_asm_insn("cmp%.w #0,%0", operands); - } - return "jmi %l1"; -}) - -(define_insn "beq" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -{ - OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0"); -} - [(set_attr "type" "bcc")]) - -(define_insn "bne" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -{ - OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0"); -} - [(set_attr "type" "bcc")]) - -(define_insn "bgt" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) - { - cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; - return 0; - } - - OUTPUT_JUMP ("jgt %l0", "fjgt %l0", 0); -} - [(set_attr "type" "bcc")]) - -(define_insn "bgtu" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) - { - cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; - return 0; - } - - return "jhi %l0"; -} - [(set_attr "type" "bcc")]) - -(define_insn "blt" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) - { - cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; - return 0; - } - - OUTPUT_JUMP ("jlt %l0", "fjlt %l0", "jmi %l0"); -} - [(set_attr "type" "bcc")]) - -(define_insn "bltu" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) - { - cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; - return 0; - } - - return "jcs %l0"; -} - [(set_attr "type" "bcc")]) - -(define_insn "bge" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) - { - cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; - return 0; - } - - OUTPUT_JUMP ("jge %l0", "fjge %l0", "jpl %l0"); -}) - -(define_insn "bgeu" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) - { - cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; - return 0; - } - - return "jcc %l0"; -} - [(set_attr "type" "bcc")]) - -(define_insn "ble" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) - { - cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; - return 0; - } - - OUTPUT_JUMP ("jle %l0", "fjle %l0", 0); -} - [(set_attr "type" "bcc")]) - -(define_insn "bleu" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) - { - cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; - return 0; - } - - return "jls %l0"; -} - [(set_attr "type" "bcc")]) - -(define_insn "bordered" - [(set (pc) - (if_then_else (ordered (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjor %l0"; -} - [(set_attr "type" "fbcc")]) - -(define_insn "bunordered" - [(set (pc) - (if_then_else (unordered (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjun %l0"; -} - [(set_attr "type" "fbcc")]) - -(define_insn "buneq" - [(set (pc) - (if_then_else (uneq (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjueq %l0"; -} - [(set_attr "type" "fbcc")]) - -(define_insn "bunge" - [(set (pc) - (if_then_else (unge (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjuge %l0"; -} - [(set_attr "type" "fbcc")]) - -(define_insn "bungt" - [(set (pc) - (if_then_else (ungt (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjugt %l0"; -} - [(set_attr "type" "fbcc")]) - -(define_insn "bunle" - [(set (pc) - (if_then_else (unle (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjule %l0"; -} - [(set_attr "type" "fbcc")]) - -(define_insn "bunlt" - [(set (pc) - (if_then_else (unlt (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjult %l0"; -} - [(set_attr "type" "fbcc")]) - -(define_insn "bltgt" - [(set (pc) - (if_then_else (ltgt (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjogl %l0"; -} - [(set_attr "type" "fbcc")]) - -;; Negated conditional jump instructions. - -(define_insn "*beq_rev" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" -{ - OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0"); -} - [(set_attr "type" "bcc")]) - -(define_insn "*bne_rev" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" -{ - OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0"); -} - [(set_attr "type" "bcc")]) - -(define_insn "*bgt_rev" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0) - { - cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; - return 0; - } - - OUTPUT_JUMP ("jle %l0", "fjngt %l0", 0); -} - [(set_attr "type" "bcc")]) - -(define_insn "*bgtu_rev" - [(set (pc) - (if_then_else (gtu (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; - } - - return "jls %l0"; -} - [(set_attr "type" "bcc")]) - -(define_insn "*blt_rev" - [(set (pc) - (if_then_else (lt (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 ("jge %l0", "fjnlt %l0", "jpl %l0"); -} - [(set_attr "type" "bcc")]) - -(define_insn "*bltu_rev" - [(set (pc) - (if_then_else (ltu (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; - } - - return "jcc %l0"; -} - [(set_attr "type" "bcc")]) - -(define_insn "*bge_rev" - [(set (pc) - (if_then_else (ge (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 ("jlt %l0", "fjnge %l0", "jmi %l0"); -} - [(set_attr "type" "bcc")]) - -(define_insn "*bgeu_rev" - [(set (pc) - (if_then_else (geu (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; - } - - return "jcs %l0"; -} - [(set_attr "type" "bcc")]) - -(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 "*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; - } - - return "jhi %l0"; -} - [(set_attr "type" "bcc")]) - -(define_insn "*bordered_rev" - [(set (pc) - (if_then_else (ordered (cc0) (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjun %l0"; -} - [(set_attr "type" "fbcc")]) - -(define_insn "*bunordered_rev" - [(set (pc) - (if_then_else (unordered (cc0) (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjor %l0"; -} - [(set_attr "type" "fbcc")]) - -(define_insn "*buneq_rev" - [(set (pc) - (if_then_else (uneq (cc0) (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjogl %l0"; -} - [(set_attr "type" "fbcc")]) - -(define_insn "*bunge_rev" - [(set (pc) - (if_then_else (unge (cc0) (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "TARGET_HARD_FLOAT" -{ - 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" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjole %l0"; -} - [(set_attr "type" "fbcc")]) - -(define_insn "*bunle_rev" - [(set (pc) - (if_then_else (unle (cc0) (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjogt %l0"; -} - [(set_attr "type" "fbcc")]) - -(define_insn "*bunlt_rev" - [(set (pc) - (if_then_else (unlt (cc0) (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjoge %l0"; -} - [(set_attr "type" "fbcc")]) - -(define_insn "*bltgt_rev" - [(set (pc) - (if_then_else (ltgt (cc0) (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "TARGET_HARD_FLOAT" -{ - gcc_assert (cc_prev_status.flags & CC_IN_68881); - return "fjueq %l0"; -} - [(set_attr "type" "fbcc")]) ;; Unconditional and other jump instructions (define_insn "jump" @@ -6779,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) @@ -6799,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) @@ -6822,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) @@ -6857,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) @@ -7004,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)] @@ -7379,97 +6466,56 @@ ;; ;; 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" - [(cc0) (const_int 0)]) - (label_ref (match_operand 2 "" "")) - (pc))) - (parallel - [(set (pc) - (if_then_else - (ne (match_operand:HI 0 "register_operand" "") - (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)]) + [(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 [(set (pc) (if_then_else - (ne (match_operand:SI 0 "register_operand" "") + (ne (match_operand:DBCC 0 "register_operand" "") (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); + (plus:DBCC (match_dup 0) + (const_int -1)))])] + "!TARGET_COLDFIRE && DATA_REG_P (operands[0])" +{ + 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 [(set (pc) (if_then_else - (ge (plus:HI (match_operand:HI 0 "register_operand" "") - (const_int -1)) + (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: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); + (plus:DBCC (match_dup 0) + (const_int -1)))])] + "!TARGET_COLDFIRE && DATA_REG_P (operands[0])" +{ + 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)]) - (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") @@ -7480,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"; @@ -7512,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"; @@ -7583,64 +6623,52 @@ 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")]) -(define_expand "ctrapdi4" +;; ??? 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_insn "ctrap<mode>4" [(trap_if (match_operator 0 "ordered_comparison_operator" - [(cc0) (const_int 0)]) - (match_operand:SI 3 "const1_operand" ""))] - "TARGET_68020" -{ - 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" - "") - -(define_insn "*conditional_trap" + [(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" +{ + 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 "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"; @@ -7735,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]) @@ -7747,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]));") @@ -7756,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 @@ -7769,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)))] " { @@ -7779,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 @@ -7790,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 @@ -7811,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)))] " { @@ -7820,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 @@ -7831,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)); }") @@ -7841,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]) @@ -7852,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)))] "")