OSDN Git Service

Merge cond-optab branch.
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 12 May 2009 09:43:48 +0000 (09:43 +0000)
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 12 May 2009 09:43:48 +0000 (09:43 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147425 138bc75d-0d04-0410-961f-82ee72b054a4

145 files changed:
gcc/ChangeLog
gcc/combine.c
gcc/config/alpha/alpha-protos.h
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/alpha.md
gcc/config/alpha/predicates.md
gcc/config/arc/arc.c
gcc/config/arc/arc.h
gcc/config/arc/arc.md
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/arm/arm.md
gcc/config/arm/predicates.md
gcc/config/avr/avr-protos.h
gcc/config/avr/avr.c
gcc/config/avr/avr.md
gcc/config/bfin/bfin.c
gcc/config/bfin/bfin.h
gcc/config/bfin/bfin.md
gcc/config/bfin/predicates.md
gcc/config/cris/cris.c
gcc/config/cris/cris.md
gcc/config/crx/crx-protos.h
gcc/config/crx/crx.c
gcc/config/crx/crx.h
gcc/config/crx/crx.md
gcc/config/fr30/fr30.c
gcc/config/fr30/fr30.h
gcc/config/fr30/fr30.md
gcc/config/frv/frv-protos.h
gcc/config/frv/frv.c
gcc/config/frv/frv.h
gcc/config/frv/frv.md
gcc/config/h8300/h8300-protos.h
gcc/config/h8300/h8300.c
gcc/config/h8300/h8300.md
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/config/ia64/ia64-protos.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.md
gcc/config/ia64/predicates.md
gcc/config/iq2000/iq2000-protos.h
gcc/config/iq2000/iq2000.c
gcc/config/iq2000/iq2000.h
gcc/config/iq2000/iq2000.md
gcc/config/iq2000/predicates.md
gcc/config/m32c/cond.md
gcc/config/m32c/m32c-protos.h
gcc/config/m32c/m32c.c
gcc/config/m32c/m32c.md
gcc/config/m32r/m32r-protos.h
gcc/config/m32r/m32r.c
gcc/config/m32r/m32r.h
gcc/config/m32r/m32r.md
gcc/config/m68hc11/m68hc11.c
gcc/config/m68hc11/m68hc11.h
gcc/config/m68hc11/m68hc11.md
gcc/config/m68k/constraints.md
gcc/config/m68k/m68k.c
gcc/config/m68k/m68k.h
gcc/config/m68k/m68k.md
gcc/config/m68k/predicates.md
gcc/config/mcore/mcore-protos.h
gcc/config/mcore/mcore.c
gcc/config/mcore/mcore.md
gcc/config/mips/mips-protos.h
gcc/config/mips/mips-ps-3d.md
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.md
gcc/config/mips/predicates.md
gcc/config/mmix/mmix-protos.h
gcc/config/mmix/mmix.c
gcc/config/mmix/mmix.h
gcc/config/mmix/mmix.md
gcc/config/mmix/predicates.md
gcc/config/mn10300/mn10300.c
gcc/config/mn10300/mn10300.md
gcc/config/pa/pa-protos.h
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/pa/pa.md
gcc/config/pdp11/pdp11-protos.h
gcc/config/pdp11/pdp11.c
gcc/config/pdp11/pdp11.h
gcc/config/pdp11/pdp11.md
gcc/config/picochip/picochip.md
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/config/s390/predicates.md
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/s390/s390.md
gcc/config/score/score-conv.h
gcc/config/score/score-protos.h
gcc/config/score/score.c
gcc/config/score/score.md
gcc/config/score/score3.c
gcc/config/score/score3.h
gcc/config/score/score7.c
gcc/config/score/score7.h
gcc/config/sh/predicates.md
gcc/config/sh/sh-protos.h
gcc/config/sh/sh.c
gcc/config/sh/sh.md
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/sparc/sparc.md
gcc/config/spu/spu-protos.h
gcc/config/spu/spu.c
gcc/config/spu/spu.h
gcc/config/spu/spu.md
gcc/config/stormy16/stormy16-protos.h
gcc/config/stormy16/stormy16.c
gcc/config/stormy16/stormy16.h
gcc/config/stormy16/stormy16.md
gcc/config/v850/v850.c
gcc/config/v850/v850.md
gcc/config/vax/vax-protos.h
gcc/config/vax/vax.c
gcc/config/vax/vax.h
gcc/config/vax/vax.md
gcc/config/xtensa/predicates.md
gcc/config/xtensa/xtensa-protos.h
gcc/config/xtensa/xtensa.c
gcc/config/xtensa/xtensa.h
gcc/config/xtensa/xtensa.md
gcc/doc/md.texi
gcc/doc/tm.texi
gcc/dojump.c
gcc/expmed.c
gcc/expr.h
gcc/final.c
gcc/genopinit.c
gcc/ifcvt.c
gcc/optabs.c
gcc/optabs.h
gcc/simplify-rtx.c

index 9388421..cbe7b30 100644 (file)
@@ -1,5 +1,572 @@
 2009-05-12  Paolo Bonzini  <bonzini@gnu.org>
 
+        * dojump.c (compare_from_rtx): Delete.
+        * expmed.c (emit_store_flag): Only try cstore_optab.  Canonicalize
+        any MODE_CC mode to the cstorecc4 pattern.  Use prepare_operand, fail
+       if the comparison does not satisfy the predicate; test predicates for
+       operands 2 and 3 of a cstore pattern.  Don't try cstore optab
+       further if one existing pattern fails.
+        * expr.h (compare_from_rtx): Delete.
+       (prepare_operand): Declare it.
+        * optabs.c: Change "lib call" to "libcall" throughout.
+       (bcc_gen_fctn, setcc_gen_code, trap_rtx,
+        HAVE_conditional_trap, emit_cmp_insn): Delete.
+        (can_compare_p): Delete cmp_optab case.
+       (prepare_float_lib_cmp): Return an rtx and a machine mode.
+        Accept other parameters by value.
+        (prepare_operand): Make non-static.
+        (prepare_cmp_insn): Return an rtx and a machine mode.  Accept
+        other parameters by value.  Try to widen operands here based on
+        an optab_methods argument and looking at cbranch_optab.
+        (emit_cmp_and_jump_insn_1): Accept test and mode, remove widening loop.
+       Use cbranch_optab directly.
+        (emit_cmp_and_jump_insns): Fix comment.  Adjust call to prepare_cmp_insn
+       and emit_cmp_and_jump_insn_1, remove obsolete assertion.
+        (emit_conditional_move, emit_conditional_add): Inline what's needed
+        of compare_from_rtx, using new prepare_cmp_insn for the rest.
+        (init_optabs): Init cmp_optab with UNKNOWN, cbranch_optab
+        with COMPARE.  Move cmov_optab and cstore_optab above
+        with cbranch_optab, move cmp_optab down with ucmp_optab,
+        remove tst_otpab.  Do not initialize trap_rtx.
+        (gen_cond_trap): Do it here.  Use ctrap_optab.  Test predicate
+       for trap code.  Do not check HAVE_conditional_trap.  Use
+       prepare_cmp_insn.  Accept no predicate for operand 3.
+        * optabs.h (OTI_cmp): Mark as used only for libcalls.
+        (OTI_ctrap, ctrap_optab): New.
+        (tst_optab): Delete.
+        (bcc_gen_fctn, setcc_gen_code, emit_cmp_insn): Delete.
+        * ifcvt.c (find_if_header): Replace HAVE_conditional_trap
+        with lookup of ctrap_optab.
+        * genopinit.c (cmp_optab, tst_optab, bcc_gen_fctn,
+        setcc_gen_code): Delete.
+        (ctrap_optab): New.
+
+        * combine.c (combine_simplify_rtx, simplify_set): Do not
+        special case comparing against zero for cc0 machines.
+       * simplify-rtx.c (simplify_binary_operation_1): Never remove
+       COMPARE on cc0 machines.
+       (simplify_relational_operation): Return a new expression when
+       a COMPARE could be removed.
+        * final.c (final_scan_insn): Compare cc_status values
+        against LHS of a (compare FOO (const_int 0)) cc0 source.
+        Also check if cc_status.value is the full compare.
+
+        * doc/md.texi (bCC, sCC, tstMM, cmpMM): Delete.
+        (cstoreMM4): Document.
+       (conditional_trap): Document ctrapMM4 instead.
+        (sync_compare_and_swapMM): Refer to cbranchcc4.
+       (Dependent Patterns): Eliminate obsolete information referring to
+       the old jump optimization phase.
+        (Canonicalization): Include cbranchcc4 case, omit canonicalization
+       of compares with 0 on cc0 machines.
+       (Jump Patterns): Refer to MODE_CC jump patterns preferably,
+       avoiding references to cc0.  Remove text about storing operands
+       in cmpMM.
+       * doc/tm.texi (Condition Codes): Include blurb on different
+       condition code representations, separate into subsections for
+       CC0, MODE_CC and conditional execution.
+
+        * config/alpha/alpha-protos.h (alpha_emit_conditional_branch,
+        alpha_emit_setcc): Accept operands and a machine mode.
+        * config/alpha/alpha.c (alpha_emit_conditional_branch):
+        Get code/op0/op1 from operands, use machine mode argument
+        instead of alpha_compare.fp_p.  Emit the branch here.
+        (alpha_emit_setcc): Likewise, and return boolean.
+        (alpha_emit_conditional_move): Likewise.  Assert that
+        cmp_op_mode == cmp_mode, and simplify accordingly.
+        * config/alpha/alpha.h (struct alpha_compare, alpha_compare): Delete.
+        * config/alpha/alpha.md (cmpdf, cmptf, cmpdi, bCC, sCC): Delete.
+        (cbranchdf4, cbranchtf4, cbranchdi4, cstoredf4, cstoretf4,
+        cstoredi4): Delete.
+        (stack probe test): Use cbranchdi4.
+        * config/alpha/predicates.md (alpha_cbranch_operator): New.
+
+        * config/arc/arc.c (gen_compare_reg): Do not emit cmp. 
+        * config/arc/arc.h (movsicc, movsfcc): Use it.
+        (movdicc, *movdicc_insn, movdfcc, *movdfcc_insn): Remove.
+        (cbranchsi4, cstoresi4): New.
+        (cmpsi, bCC and sCC expanders): Remove. 
+
+        * config/arm/arm.c (arm_compare_op0, arm_compare_op1): Delete.
+        * config/arm/arm.h (arm_compare_op0, arm_compare_op1): Delete.
+        * config/arm/predicates.md (arm_comparison_operator): Only include
+        floating-point operators if there is a hardware floating-point unit.
+        * config/arm/arm.md (cbranchsi4, cstoresi4): Enable for TARGET_32BIT,
+        deferring to cbranch_cc and cstore_cc respectively.
+        (cbranchsf4, cbranchdf4, cbranchdi4, cstoresf4, cstoredf4, cstoredi4,
+        cbranch_cc, cstore_cc): New.
+        (movsicc, movsfcc, movdfcc): Do not use arm_compare_op0 and
+       arm_compare_op1.
+        (bCC, sCC, cmpsi, cmpsf, cmpdf, cmpdi): Delete.
+
+        * config/avr/avr-protos.h (out_tstsi, out_tsthi): Adjust prototype.
+        * config/avr/avr.c (out_tstsi, out_tsthi): Get the tested operand
+        as an argument.
+        (adjust_insn_length): Adjust calls.
+        (avr_reorg): Handle (compare (foo) (const_int 0)).
+        * config/avr/avr.md (tstqi, tsthi, tstsi): Remove.
+        (*negated_tstqi, *negated_tsthi, *negated_tstsi): Unmacroize.
+        (*reversed_tsthi, *reversed_tstsi): Add a scratch for simplicity.
+        (cmpqi, cmphi, cmpsi): Prepend asterisk, fuse tst[qhs]i here.
+        (bCC): Remove.
+        (cbranchqi4, cbranchhi4, cbranchsi4): New.
+       (tst -> sbrc/sbrs peephole2, cpse peephole): Wrap RHS with COMPARE.
+
+        * config/bfin/bfin.md (cmpbi, cmpsi, bCC, sCC): Delete.
+        (cbranchsi4, cstorebi4, cstoresi4): New.
+       (movbisi): This insn is duplicate, split it to zero_extend.
+        * config/bfin/bfin.c (bfin_compare_op0, bfin_compare_op1): Delete
+        (bfin_gen_compare): Do not use them.  Emit VOIDmode SET, not BImode.
+        (bfin_optimize_loop): Use cbranch expander.
+        * config/bfin/bfin.h (bfin_compare_op0, bfin_compare_op1): Delete.
+        * config/bfin/predicates.md (bfin_cbranch_operator): Rename to...
+        (bfin_bimode_comparison_operator): ... this.
+        (bfin_direct_comparison_operator): New.
+        * config/cris/cris.c (cris_normal_notice_update_cc): Look
+        inside (compare FOO (const_int 0)).
+        (cris_rtx_costs): Handle ZERO_EXTRACT.
+        * config/cris/cris.md (tstdi, tst<mode>, cmpdi): Delete.
+        (*tstdi_non_v32): Fold in *cmpdi_non_v32.
+        (*tstdi_v32): Delete.
+        (*cmpdi_non_v32): Add M alternative for operand 1.
+        (cmpsi, cmp<mode>): Make private.
+        (*tstsi, *tst<mode>_cmp, *tst<mode>_non_cmp, *btst): Wrap
+        LHS with COMPARE.
+        (cbranch<mode>4, cbranchdi4, cstore<mode>4): New.
+
+        * config/crx/crx.md (cstore<mode>4, cbranchcc4): New.
+        (cmp<mode>, bCOND_internal, b<code>, s<code>): Delete.
+        (cbranch<mode>4, sCOND_internal): Use ordered_comparison_operator.
+       (cc_reg_operand): New.
+       (any_cond): Delete.
+        * config/crx/crx.c (crx_compare_op0, crx_compare_op1,
+        crx_expand_compare, crx_expand_branch, crx_expand_scond): Delete.
+        * config/crx/crx.h (crx_compare_op0, crx_compare_op1): Delete.
+        * config/crx/crx-protos.h (crx_expand_compare, crx_expand_branch,
+        crx_expand_scond): Delete.
+
+        * config/fr30/fr30.md (cmp<mode>, bCC): Delete.
+        (cbranchsi4): New.
+        * config/fr30/fr30.c (fr30_compare_op0, fr30_compare_op1): Delete
+        * config/fr30/fr30.h (fr30_compare_op0, fr30_compare_op1): Delete.
+
+        * config/frv/frv.md (cbranchsi4, cbranchsf4, cbranchdf4,
+        cstoresi4, cstoresf4, cstoredf4): New.
+        (cmpdi, cmpsi, cmpsf, cmpdf, bCC, sCC): Remove.
+        * config/frv/frv-protos.h (frv_emit_cbranch, frv_emit_scc):
+        Receive the entire operands array.
+        * config/frv/frv.h (frv_compare_op0,
+        frv_compare_op1): Delete.
+        * config/frv/frv.c (frv_compare_op0,
+        frv_compare_op1): Delete.
+        * config/frv/frv-protos.h (frv_emit_cbranch, frv_emit_scc):
+        Get test/op0/op1 from the operands array.
+        (frv_emit_cond_move): Get test/op0/op1 from the test_rtx.
+
+        * config/h8300/h8300-protos.h (h8300_expand_branch): Accept operands.
+        (h8300_expand_store): New.
+        * config/h8300/h8300.c (h8300_rtx_costs): Handle (compare FOO
+        (const_int 0)).
+        (h8300_expand_branch): Emit compare here.  Adjust for new arguments.
+        (h8300_expand_store): New.
+        * config/h8300/h8300.md (btst combine patterns): Wrap with COMPARE
+        or do not try to produce (set (cc0) REG).
+        (peepholes): Wrap arguments with COMPARE.  Add a peephole to
+        change a compare into a move to a scratch register.  Disable some
+        peepholes when comparing with zero.
+        (tstsi, tsthi, tstsi, cmpqi): Make private.
+        (cmphi): Delete.
+        (bCC, sCC): Delete.
+        (cbranchqi4, cbranchhi4, cbranchsi4, cstoreqi4, cstorehi4,
+        cstoresi4): New.
+
+       * config/i386/i386.c (ix86_expand_int_movcc, ix86_expand_int_addcc,
+       ix86_expand_fp_movcc): Set ix86_compare_op0 and ix86_compare_op1.
+       (ix86_emit_i387_log1p): Use gen_cbranchxf4.
+       (ix86_emit_i387_log1p): Use cbranchxf2.
+       (ix86_expand_setcc): Return void.
+       * config/i386/i386-protos.h (ix86_expand_setcc): Return void.
+       * config/i386/i386.md (cmpti, cmpdi, cmpsi, cmphi, cmpqi, cmpxf,
+       cmp<MODEF>, cmpcc): Remove.
+       (cbranchti4, cbranchdi4, cbranchsi4, cbranchhi4, cbranchqi4, cbranchxf4,
+       cbranch<MODEF>4, cbranchcc4, cstoredi4, cstoresi4, cstorehi4,
+       cstoreqi4, cstorexf4, cstore<MODEF>4, cstorecc): New.
+       (sCC and bCC expanders): Remove.
+       (stack_protect_test): Use cbranchcc4.
+
+        * config/ia64/ia64-protos.h (ia64_compare_op0, ia64_compare_op1):
+        Delete.
+        (ia64_expand_compare): Accept three rtx by reference and return void.
+        * config/ia64/ia64.c (ia64_compare_op0, ia64_compare_op1): Delete.
+        (ia64_expand_compare): Replace op0/op1 with *op0/*op1.  Get code
+        from *expr.  Update *expr with the BImode comparison to do.
+        * config/ia64/ia64.md (cmpbi, cmpsi, cmpdi, cmpsf, cmpdf, cmpxf,
+        cmptf, bCC, sCC, conditional_trap): Delete.
+        (cbranchbi4, cbranchsi4, cbranchdi4, cbranchsf4, cbranchdf4, 
+        cbranchxf4, cbranchtf4, cstorebi4, cstoresi4, cstoredi4, cstoresf4,
+        cstoredf4, cstorexf4, cstoretf4, ctrapbi4, ctrapsi4, ctrapdi4,
+        ctrapsf4, ctrapdf4, ctrapxf4, ctraptf4): New.
+        * config/ia64/predicates.md (ia64_cbranch_operator): New.
+
+        * config/iq2000/iq2000-protos.h (gen_conditional_branch): Change
+        type of last argument.
+        * config/iq2000/iq2000.c (branch_cmp, branch_type): Remove.
+        (gen_conditional_branch): Get code/cmp0/cmp1 from operands,
+        use machine mode argument instead of branch_type.  Remove dead
+        code for floating-point comparisons.
+        * config/iq2000/iq2000.h (branch_cmp, branch_type): Remove.
+        * config/iq2000/iq2000.md (cmpsi, cmpdi, cmpsf, cmpdf, tstsi,
+        bCC): Remove.
+        (cbranchsi4, cstoresi4): New.
+        * config/iq2000/predicates.md (reg_or_const_operand): New.
+
+        * config/m32c/m32c.md (cbranch splitter): Use match_op_dup.
+        * config/m32c/m32c.md (any_cond, gl_cond): Delete.
+        (b<code>_op): Rewrite to...
+        (bcc_op): ... this, using match_operator.
+        (s<code>_op): Rewrite to...
+        (scc_op): ... this, using match_operator.
+        (s<code>_24_op): Rewrite to...
+        (scc_op_24): ... this, using match_operator.
+        (s<code>_<mode>): Rewrite to...
+        (cstore<mode>4): ... this, using match_operator.
+        (s<code>_<mode>_24): Rewrite to...
+        (cstore<mode>4_24): ... this, using match_operator.
+        * config/m32c/m32c-protos.h (m32c_cmp_flg_0, m32c_pend_compare,
+        m32c_unpend_compare, m32c_expand_scc): Delete.
+        * config/m32c/m32c.c (compare_op0, compare_op1, m32c_cmp_flg_0,
+        m32c_pend_compare, m32c_unpend_compare, m32c_expand_scc): Delete.
+        (m32c_expand_movcc): Change NE to EQ if necessary.
+        (m32c_init_libfuncs): Modify cstore optab instead of setcc_gen_code.
+
+        * config/m32r/m32r-protos.h (gen_cond_store): New.
+        * config/m32r/m32r.c (m32r_compare_op0, m32r_compare_op1): Delete.
+        (gen_cond_store): New, from sCC patterns.
+        (m32r_expand_block_move): Use cbranchsi4.
+        * config/m32r/m32r.h (m32r_compare_op0, m32r_compare_op1): Delete.
+        * config/m32r/m32r.md (cmpsi, bCC, sCC): Delete.
+        (cbranchsi4, cstoresi4): New.
+        
+        * config/m68hc11/m68hc11.c (m68hc11_compare_op0, m68hc11_compare_op1):
+        Delete.
+        (m68hc11_rtx_costs_1, m68hc11_rtx_costs): Handle ZERO_EXTRACT.
+       (m68hc11_notice_update_cc): Look into a compare with 0.
+        * config/m68hc11/m68hc11.h (m68hc11_compare_op0, m68hc11_compare_op1):
+        Delete.
+        * config/m68hc11/m68hc11.md (tstsi, tsthi, tstqi, cmpsi,
+        cmphi, cmpqi, bCC): Delete.
+        (cbranchsi4, cbranchhi4, cbranchqi4): New.
+        (tstqi_1, tstqi_z_used, tstqi_1, bitcmpqi, bitcmpqi_z_used,
+        bitcmpqi_12, bitcmphi, various splits and peephole2s): Wrap cc0<-reg
+        sets with COMPARE.
+
+        * config/m68k/predicates.md (m68k_cstore_comparison_operator,
+        const0_operand, const1_operand, m68k_subword_comparison_operand): New.
+        * config/m68k/constraints.md (H): New.
+        * config/m68k/m68k.md (tstdi): Remove define_expand, use name for
+        the define_insn below.
+        (tstsi, tsthi, tst<FP:mode>, cmphi, cmpqi, cmp<FP:mode>): Delete.
+        (*tstsi_internal_68020_cf, *tstsi_internal, *tsthi_internal,
+        *tstqi_internal, tst<mode>_6881, tst<mode>_cf, many unnamed
+        patterns): Wrap RHS with COMPARE.
+        (tst<FP>_68881, tst<FP>_cf): Use const0_operand.
+        (*cmpdi_internal): Name this pattern.
+        (cmpdi): Change to define_insn.
+        (cbranchdi4, cstoredi4, cbranchsi4, cstoresi4, cbranchhi4, cstorehi4,
+        cbranchqi4, cstoreqi4, cbranch<FP:mode>4, cstore<FP:mode>4): New.
+        (scc0_di, scc0_di_5200, scc_di): Use the ordered_comparison_operator
+        predicate.
+        (seq, sne, sgt, sgtu, slt, sltu, sge, sgeu, sle, sleu, sordered,
+        sunordered, suneq, sunge, sungt, sunle, sunlt, sltgt): Delete
+        (conditional_trap): Change to...
+        (ctrapdi4, ctrapsi4, ctraphi4, ctrapqi4): ... these.
+        (*conditional_trap): Use the ordered_comparison_operator and
+        const1_operand predicates.
+        * config/m68k/m68k.c (m68k_last_compare_had_fp_operands): Delete.
+        (m68k_expand_prologue): Use ctrapsi4 instead of cmpsi+conditional_trap.
+        (m68k_rtx_costs): Look for ZERO_EXTRACT in a COMPARE.
+        * config/m68k/m68k.h (m68k_last_compare_had_fp_operands): Delete.
+
+        * config/mcore/mcore-protos.h (arch_compare_op0, arch_compare_op1,
+        mcore_modify_comparison, mcore_gen_compare_reg): Remove.
+        (mcore_gen_compare): New. 
+        * config/mcore/mcore.c (arch_compare_op0, arch_compare_op1): Delete.
+        (mcore_modify_comparison, mcore_gen_compare_reg): Fold into...
+        (mcore_gen_compare): ... this.
+        * config/mcore/mcore.md (cmpsi, bCC, sCC): Remove.
+        (cbranchsi4, cstoresi4): New, using mcore_gen_compare.
+        (stack probe pattern): Use cbranchsi4.
+
+        * config/mips/predicates.md (mips_cstore_operator): New.
+        * config/mips/mips-ps-3d.md (movv2sfcc): Do not use cmp_operands.
+        * config/mips/mips.md (any_cond): Delete.
+        (conditional_trap): Rename to ctrap<GPR:mode>4.  Adjust predicates,
+        always succeed.
+        (fixuns_truncdfsi2, fixuns_truncdfdi2, fixuns_truncsfsi2,
+        fixuns_truncsfdi2): Use cbranch patterns.
+        (cmp<GPR:mode>, cmp<SCALARF:mode>): Delete. 
+        (b<code>): Change to cbranch<GPR:mode>4 and cbranch<SCALARF:mode>4.
+        Adjust call to mips_expand_conditional_branch.
+        (seq, sne, slt<u>, sle<u>, sgt<u>, sge<u>): Change to cstore<GPR:mode>4.
+        * config/mips/mips-protos.h (mips_expand_conditional_branch,
+        mips_expand_scc, mips_expand_conditional_trap): Adjust prototypes.
+        * config/mips/mips.c (cmp_operands): Delete.
+        (mips_emit_compare): Get comparison operands from *op0/*op1.
+        (mips_expand_scc): Get code/op0/op1/target from operands.  Assert
+        that it succeeds.  Use op0/op1 instead of cmp_operands.
+        (mips_expand_conditional_branch, mips_expand_conditional_move,
+        mips_expand_conditional_trap): Likewise.
+        (mips_block_move_loop): Use cbranch patterns. 
+        * config/mips/mips.h (cmp_operands): Delete.
+
+        * config/mmix/mmix.c (mmix_valid_comparison): Delete.
+        (mmix_gen_compare_reg): Just return a register in the right CC mode.
+        * config/mmix/mmix.h (mmix_compare_op0, mmix_compare_op1): New.
+        * config/mmix/mmix.md (cmpdi, cmpdf): Remove.
+        (*cmpcc_folded): Rename to...
+        (*cmpdi_folded): this.
+        (*cmpcc): Rename to...
+        (*cmps): ... this.
+        (movdfcc, movdicc): Adjust for new semantics of mmix_gen_compare_reg.
+        (bCC): Remove.
+        (cbranchdi4): New.
+        (cbranchdf4): New.  Handle invalid comparisons here.
+        * config/mmix/predicates.md (float_comparison_operator): New.
+
+        * config/mn10300/mn10300.c (mn10300_rtx_costs): Consider 0 and
+        zero_extract to be cheap in (compare (zero_extract) (const_int 0).
+        * config/mn10300/mn10300.md (tst): Delete.
+        (*tst_extqisi_am33, *tst_extqisi, *tst_exthisi_am33, *tst_exthisi):
+        Name these patterns and wrap RHS in a compare.
+        (*cmpsi): Make this pattern private.  Include tst.
+        (*cmpsf): Make this pattern private.
+        (and and zero_extract cc0 set): Wrap RHS in a COMPARE.
+        (compare with zero peepholes): Likewise.
+        (bCC): Remove.
+        (cbranchsi4, cbranchsf4): New.
+        (casesi): Use cbranchsi4.
+
+        * config/pa/pa.c (hppa_compare_op0, hppa_compare_op1,
+        hppa_branch_type): Delete.
+        (return_addr_rtx): Use cbranchsi4.
+        (emit_bcond_fp): Accept all operands.  Replace CODE with NE.
+        Emit CCFPmode comparison here.
+        (gen_cmp_fp): Delete, now part of emit_bcond_fp.
+        * config/pa/pa.h (enum cmp_type, hppa_compare_op0, hppa_compare_op1,
+        hppa_branch_type): Delete.
+        * config/pa/pa.md (cmpdi, cmpsi, cmpsf, cmpdf, sCC, bCC): Delete.
+        (movsicc, movdicc): Remove references to hppa_compare_op0,
+        hppa_compare_op1 and compare_from_rtx.
+        (cbranchdi4, cbranchsi4, cbranchsf4, cbranchdf4, cstoresi4): New.
+        (casesi): Use cbranchsi4.
+
+        * config/pdp11/pdp11-protos.h (output_jump): Change prototype.
+        * config/pdp11/pdp11.c (output_jump): Embed opcodes here.
+        * config/pdp11/pdp11.md (register_or_const0_operand): New.
+        (cmpdf, cmphi, cmpqi): Make private.  Add tst alternatives.
+        (cmpsi, tstsi, tstdf, tsthi, tstqi): Delete.
+        (bCC): Delete.
+        (cbranchdf4, cbranchhi4, cbranchqi4): New.
+        (*branch, *branch_inverted): New.
+
+        * config/picochip/picochip.md (cbranchhi4): Use
+        ordered_comparison_operator.
+        (cmphi, bCC): Remove.
+
+        * config/rs6000/predicates.md (rs6000_cbranch_operator): New.
+        (trap_comparison_operator): Delete.
+        * config/rs6000/rs6000-protos.h (rs6000_emit_sCOND,
+        rs6000_emit_cbranch): Accept mode and operands.
+        * config/rs6000/rs6000.c (rs6000_compare_op0, rs6000_compare_op1,
+        rs6000_compare_fp_p): Delete.   
+        (rs6000_generate_compare): Accept mode and comparison.  Extract code
+        and op0/op1 from there.  Replace references to rs6000_compare_op0
+        and rs6000_compare_op1.
+        (rs6000_emit_sCOND): Adjust call to rs6000_generate_compare and
+        extract result from passed operands.
+        (rs6000_emit_cbranch): Adjust call to rs6000_generate_compare and
+        extract loc from passed operands.
+        (rs6000_emit_cmove): Likewise.
+        * config/rs6000/rs6000.h (rs6000_compare_op0, rs6000_compare_op1,
+        rs6000_compare_fp_p): Delete.
+        * config/rs6000/rs6000.md (cmp<GPR>, cmp<FP>, bCC, sCC): Delete.
+        (cbranch<GPR>4, cbranch<FP>4): New.
+        (cstore<mode>4): New.  Consolidate here all choices about when to use
+        portable or specialized sCC sequences.
+        (stack_protect_test): Use cbranchsi4.
+        (conditional_trap): Replace with ctrap<GPR>4.
+        (conditional trap insn): Replace trap_comparison_operator with
+        ordered_comparison_operator. 
+
+        * config/s390/s390.c (s390_compare_op0, s390_compare_op1): Delete.
+        (s390_emit_prologue): Use ctrap.
+        * config/s390/s390.h (s390_compare_op0, s390_compare_op1): Delete.
+        * config/s390/predicates.md (s390_eqne_operator, s390_scond_operator):
+        New predicates replacing...
+        * config/s390/s390.md (COMPARE, SCOND): ... these iterators.
+        (cmp<GPR>, cmp<FP>, cmpcc): Delete.
+        (trunc patterns): Use emit_cmp_and_jump_insns instead of cmp/branch.
+        (add<mode>cc): Do not use s390_compare_op0/op1.
+        (s<code>): Change to...
+        (cstore<mode>4): ... this. Do not use s390_compare_op0/op1.
+        (seq): Change to...
+        (cstorecc4): ... this.  Handle EQ or NE equally.
+        (*sne): Un-privatize for use in cstorecc4.
+        (b<code>): Change to...
+        (cbranch<GPR>4, cbranch<FP>4, cbranchcc4): ... these.
+        (conditional_trap): Replace with...
+        (ctrap<GPR>4, ctrap<FP>4): ... these.
+        (stack_protect): Use cbranchcc4.
+
+        * config/score/score-conv.h (cmp_op0, cmp_op1): Delete.
+        * config/score/score-protos.h (score_gen_cmp): Delete.
+        * config/score/score.c (cmp_op0, cmp_op1, score_gen_cmp): Delete.
+        (score_block_move-loop): Use cbranchsi4.
+        * config/score/score.md (cbranchsi4): New.
+        (cmpsi, bCC): Delete.
+        * config/score/score3.c (cmp_op0, cmp_op1, score3_gen_cmp): Delete.
+        (score3_movsicc): Use ops[1] operands instead of cmp_op0/cmp_op1.
+        * config/score/score7.c (cmp_op0, cmp_op1, score7_gen_cmp): Delete.
+        (score7_movsicc): Use ops[1] operands instead of cmp_op0/cmp_op1.
+        * config/score/score3.h (score3_gen_cmp): Delete.
+        * config/score/score7.h (score7_gen_cmp): Delete.
+
+        * config/sh/sh-protos.h (prepare_scc_operands): Rename to...
+        (sh_emit_scc_to_t): ... this.  Return void.
+        (from_compare): Rename to...
+        (sh_emit_compare_and_branch): ... this.
+        (sh_emit_compare_and_set): New.
+        (sh_expand_t_scc): Accept operands.
+        * config/sh/predicates.md (sh_float_comparison_operator): New.
+        * config/sh/sh.c (sh_compare_op0, sh_compare_op1): Delete.
+        (prepare_scc_operands): Rename to...
+        (sh_emit_scc_to_t): ... this.  Return void.  Get op0/op1 from arguments.
+        (sh_emit_cheap_store_flag): New.
+       (sh_emit_set_t_insn): New.
+        (from_compare): Rename to...
+        (sh_emit_compare_and_branch): ... this.  Accept mode.  Rewrite
+        handling of TARGET_SH2E floating point to avoid recursive call.
+        Generate branch here.
+        (sh_emit_compare_and_set): New.
+        (sh_expand_t_scc): Get op0/op1 from arguments.
+        (sh_emit_cheap_store_flag): New.
+        * config/sh/sh.md (cbranchdi4, cbranchsi4): Include -mno-cbranchdi
+        cases.
+       (cbranchdi4_i): Use an "I08" constraint instead of an "i" constraint.
+        (cmpsi, cmpdi, cmpsf, cmpdf): Delete.
+        (movsicc, movdicc): Do nothing when it recreated operands from
+        sh_compare_*. Use sh_emit_cheap_store_flag.  Adjust call to
+        prepare_scc_operands (now sh_emit_scc_to_t).
+        (udivdi3): Use cstoresi4.
+        (beq_media, bne_media, bge_media, bgtu_media, bgeu_media, beq,
+        bne, bgt, blt, ble, bge, bgtu, bltu, bgeu, bleu, bunordered):
+        Delete.
+        (cbranchint4_media, cbranchfp4_media): New.
+        (casesi): Use cbranchdi4.
+        (seq, slt, sle, sgt, sge, sgtu, sltu, sgeu, sne, sleu, sunordered):
+        Delete.
+        (cstore4_media, cstoresi4, cstoredi4, cstoresf4, cstoredf4): New.
+        (movnegt): Remove second operand.
+        (cbranchsf4, cbranchdf4): New.
+        (stack_protect): Use cbranchdi4/cbranchsi4.
+
+        * config/sparc/sparc.c (sparc_compare_op0, sparc_compare_op1): Delete.
+        (gen_compare_reg): Accept comparison, extract part of it to...
+        (gen_compare_reg_1): ... this. 
+        (gen_compare_operator): Delete.
+        (gen_v9_scc): Accept separate destination, comparison code and arms.
+        Do not use sparc_compare_op0/sparc_compare_op1.
+        (emit_scc_insn, emit_conditional_branch_insn): New.
+        (emit_v9_brxx): Make static.  Remove useless assertion.
+        (sparc_emit_float_lib_cmp): Return RTL instead of calling emit_cmp_insn.
+        (sparc_expand_compare_and_swap_12): Use gen_compare_reg_1+cbranchcc4.
+        * config/sparc/sparc-protos.h (gen_compare_reg,
+       sparc_emit_float_lib_cmp): Adjust prototype.
+       (emit_scc_insn, emit_conditional_branch_insn): New.
+       (gen_v9_scc, emit_v9_brxx_insn, gen_compare_operator): Delete.
+        * config/sparc/sparc.h (sparc_compare_op0, sparc_compare_op1): Delete.
+        * config/sparc/sparc.md (P, I, F, V32, V32I, V64, V64I): Move all
+        iterators to the top.
+        (cmpsi, cmpdi, cmpsf, cmpdf, cmptf, seqsi_special_extend,
+        snesi_special_extend, sCC, bCC, seqdi_special_trunc,
+       snedi_special_trunc): Delete.
+       (seqdi_special, snedi_special): Use expansion of seqdi_special_trunc
+       and snedi_special_trunc.
+        (cstoresi4, cstoredi4, cstore<F:mode>4, cbranchcc4, cbranchsi4,
+        cbranchdi4, cbranch<F:mode>4): New.
+        (mov<I:mode>cc, mov<F:mode>cc): Handle sparc_emit_float_lib_cmp
+        here.  Use gen_compare_reg instead of gen_compare_operator.
+        (conditional_trap): Replace with...
+        (ctrapsi4, ctrapdi4): ... this.
+        (stack_protect_test): Use cbranchcc4.
+
+        * config/spu/spu-protos.h (spu_emit_branch_or_set): Change second
+        argument to rtx.
+        * config/spu/spu.c (spu_compare_op0, spu_compare_op1): Remove. 
+        (spu_emit_branch_or_set): Get code/op0/op1 from second argument.
+        Change spu_compare_op0/op1 to op0/op1 throughout.  Get target
+        from operands[0] or operands[3] depending on is_set.
+        * config/spu/spu.h (spu_compare_op0, spu_compare_op1): Remove.
+        * config/spu/spu.md (cmp<mode:VQHSI>, cmp<mode:DTI>, cmp<mode:VSF>,
+        cmpdf, bCC), sCC: Remove.
+        (cbranch<mode:VQHSI>4, cbranch<mode:DTI>, cbranch<mode:VSF>4, 
+        cbranchdf4, cstore<mode:VQHSI>4, cstore<mode:DTI>, cstore<mode:VSF>4,
+        cstoredf4): New.
+        (mov<mode>cc): Accept ordered_comparison_operator, adjust call to
+        spu_emit_branch_or_set.
+
+        * config/stormy16/stormy16-protos.h (xstormy16_emit_cbranch):
+        Add two arguments.
+        * config/stormy16/stormy16.h (xstormy16_compare_op0,
+        xstormy16_compare_op1): Delete.
+        * config/stormy16/stormy16.c (xstormy16_compare_op0,
+        xstormy16_compare_op1): Delete. 
+        (xstormy16_emit_cbranch): Get op0/op1 from the new arguments.
+        Adjust calls.
+        * config/stormy16/stormy16.md (cbranchsi4, cbranchhi4): New.
+        (cmphi, cmpsi, bCC): Remove.
+
+        * config/v850/v850.md (tstsi, cmpsi): Fold into...
+        (*cmpsi): ... this one.
+        (cbranchsi4, cstoresi4): New.
+        (bCC expanders): Delete.
+        (sCC insns): Fold into...
+        (*setcc): ... this one.
+        (casesi): Do not use gen_cmpsi and gen_bgtu. 
+       (various splits): Wrap "naked" RHS of a cc0 set with COMPARE.
+       (movsicc): Simplify.
+       * config/v850/v850.c (v850_rtx_costs): Handle ZERO_EXTRACT in COMPARE.
+
+        * config/vax/vax-protos.h (cond_name): New.
+        (vax_output_conditional_branch): Remove.
+        * config/vax/vax.c (cond_name): New.
+        (vax_output_conditional_branch): Remove.
+        * config/vax/vax.h (PRINT_OPERAND): Dispatch %c to cond_name.
+        * config/vax/vax.md (tst<VAXint>, tst<VAXfp>): Remove.
+        (cmp<VAXint>, cmp<VAXfp>): Privatize.  Add constraints for tst.
+        (bit<VAXint>): Wrap source with (compare).
+        (b<code> and following unnamed pattern): Rename to *branch and
+        *branch_reversed.  Change macroization to match_operator.
+        (cbranch<VAXint>4, cbranch<VAXfp>4): New.
+
+        * config/xtensa/predicates.md (xtensa_cstoresi_operator): New.
+        * config/xtensa/xtensa-protos.h (xtensa_expand_conditional_branch):
+        Change last argument to machine_mode.
+        (xtensa_expand_scc): Add machine_mode argument.
+        * config/xtensa/xtensa.c (branch_cmp, branch_type): Remove.
+        (gen_conditional_move, xtensa_expand_conditional_branch,
+        xtensa_expand_scc, xtensa_expand_conditional_move): Use mode
+        instead of branch_type, fetch cmp0/cmp1/test_code from operands[].
+        Adjust operand numbers.
+        * config/xtensa/xtensa.h (enum cmp_type, branch_cmp, branch_type):
+        Delete.
+        * config/xtensa/xtensa.md (any_cond, any_scc): Delete.
+        (cmpsi, cmpsf, b<code>, s<code>): Delete.
+        (cbranchsi4, cbranchsf4, cstoresi4, cstoresf4): New.
+
+2009-05-12  Paolo Bonzini  <bonzini@gnu.org>
+
        * optabs.c (prepare_cmp_insn): Temporarily disable test that
        causes spurious differences between trunk and cond-optab branch.
 
index 0c06b2d..7cdf396 100644 (file)
@@ -4906,24 +4906,6 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
        return gen_lowpart (mode, XEXP (x, 0));
       break;
 
-#ifdef HAVE_cc0
-    case COMPARE:
-      /* Convert (compare FOO (const_int 0)) to FOO unless we aren't
-        using cc0, in which case we want to leave it as a COMPARE
-        so we can distinguish it from a register-register-copy.  */
-      if (XEXP (x, 1) == const0_rtx)
-       return XEXP (x, 0);
-
-      /* x - 0 is the same as x unless x's mode has signed zeros and
-        allows rounding towards -infinity.  Under those conditions,
-        0 - 0 is -0.  */
-      if (!(HONOR_SIGNED_ZEROS (GET_MODE (XEXP (x, 0)))
-           && HONOR_SIGN_DEPENDENT_ROUNDING (GET_MODE (XEXP (x, 0))))
-         && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 0))))
-       return XEXP (x, 0);
-      break;
-#endif
-
     case CONST:
       /* (const (const X)) can become (const X).  Do it this way rather than
         returning the inner CONST since CONST can be shared with a
@@ -5758,17 +5740,6 @@ simplify_set (rtx x)
       if (other_changed)
        undobuf.other_insn = other_insn;
 
-#ifdef HAVE_cc0
-      /* If we are now comparing against zero, change our source if
-        needed.  If we do not use cc0, we always have a COMPARE.  */
-      if (op1 == const0_rtx && dest == cc0_rtx)
-       {
-         SUBST (SET_SRC (x), op0);
-         src = op0;
-       }
-      else
-#endif
-
       /* Otherwise, if we didn't previously have a COMPARE in the
         correct mode, we need one.  */
       if (GET_CODE (src) != COMPARE || GET_MODE (src) != compare_mode)
index 66c68ae..7a12d49 100644 (file)
@@ -88,8 +88,8 @@ extern int check_float_value (enum machine_mode, REAL_VALUE_TYPE *, int);
 #endif
 
 #ifdef RTX_CODE
-extern rtx alpha_emit_conditional_branch (enum rtx_code);
-extern rtx alpha_emit_setcc (enum rtx_code);
+extern void alpha_emit_conditional_branch (rtx[], enum machine_mode);
+extern bool alpha_emit_setcc (rtx[], enum machine_mode);
 extern int alpha_split_conditional_move (enum rtx_code, rtx, rtx, rtx, rtx);
 extern void alpha_emit_xfloating_arith (enum rtx_code, rtx[]);
 extern void alpha_emit_xfloating_cvt (enum rtx_code, rtx[]);
index bb6542a..512599d 100644 (file)
@@ -81,11 +81,6 @@ enum alpha_fp_rounding_mode alpha_fprm;
 
 enum alpha_fp_trap_mode alpha_fptm;
 
-/* Save information from a "cmpxx" operation until the branch or scc is
-   emitted.  */
-
-struct alpha_compare alpha_compare;
-
 /* Nonzero if inside of a function, because the Alpha asm can't
    handle .files inside of functions.  */
 
@@ -2424,19 +2419,20 @@ alpha_emit_floatuns (rtx operands[2])
 
 /* Generate the comparison for a conditional branch.  */
 
-rtx
-alpha_emit_conditional_branch (enum rtx_code code)
+void
+alpha_emit_conditional_branch (rtx operands[], enum machine_mode cmp_mode)
 {
   enum rtx_code cmp_code, branch_code;
-  enum machine_mode cmp_mode, branch_mode = VOIDmode;
-  rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
+  enum machine_mode branch_mode = VOIDmode;
+  enum rtx_code code = GET_CODE (operands[0]);
+  rtx op0 = operands[1], op1 = operands[2];
   rtx tem;
 
-  if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
+  if (cmp_mode == TFmode)
     {
       op0 = alpha_emit_xfloating_compare (&code, op0, op1);
       op1 = const0_rtx;
-      alpha_compare.fp_p = 0;
+      cmp_mode = DImode;
     }
 
   /* The general case: fold the comparison code to the types of compares
@@ -2457,7 +2453,7 @@ alpha_emit_conditional_branch (enum rtx_code code)
 
     case GE:  case GT: case GEU:  case GTU:
       /* For FP, we swap them, for INT, we reverse them.  */
-      if (alpha_compare.fp_p)
+      if (cmp_mode == DFmode)
        {
          cmp_code = swap_condition (code);
          branch_code = NE;
@@ -2474,9 +2470,8 @@ alpha_emit_conditional_branch (enum rtx_code code)
       gcc_unreachable ();
     }
 
-  if (alpha_compare.fp_p)
+  if (cmp_mode == DFmode)
     {
-      cmp_mode = DFmode;
       if (flag_unsafe_math_optimizations && cmp_code != UNORDERED)
        {
          /* When we are not as concerned about non-finite values, and we
@@ -2501,8 +2496,6 @@ alpha_emit_conditional_branch (enum rtx_code code)
     }
   else
     {
-      cmp_mode = DImode;
-
       /* The following optimizations are only for signed compares.  */
       if (code != LEU && code != LTU && code != GEU && code != GTU)
        {
@@ -2544,36 +2537,38 @@ alpha_emit_conditional_branch (enum rtx_code code)
       emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
     }
 
-  /* Zero the operands.  */
-  memset (&alpha_compare, 0, sizeof (alpha_compare));
-
-  /* Return the branch comparison.  */
-  return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
+  /* Emit the branch instruction.  */
+  tem = gen_rtx_SET (VOIDmode, pc_rtx,
+                    gen_rtx_IF_THEN_ELSE (VOIDmode,
+                                          gen_rtx_fmt_ee (branch_code,
+                                                          branch_mode, tem,
+                                                          CONST0_RTX (cmp_mode)),
+                                          gen_rtx_LABEL_REF (VOIDmode,
+                                                             operands[3]),
+                                          pc_rtx));
+  emit_jump_insn (tem);
 }
 
 /* Certain simplifications can be done to make invalid setcc operations
    valid.  Return the final comparison, or NULL if we can't work.  */
 
-rtx
-alpha_emit_setcc (enum rtx_code code)
+bool
+alpha_emit_setcc (rtx operands[], enum machine_mode cmp_mode)
 {
   enum rtx_code cmp_code;
-  rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
-  int fp_p = alpha_compare.fp_p;
+  enum rtx_code code = GET_CODE (operands[1]);
+  rtx op0 = operands[2], op1 = operands[3];
   rtx tmp;
 
-  /* Zero the operands.  */
-  memset (&alpha_compare, 0, sizeof (alpha_compare));
-
-  if (fp_p && GET_MODE (op0) == TFmode)
+  if (cmp_mode == TFmode)
     {
       op0 = alpha_emit_xfloating_compare (&code, op0, op1);
       op1 = const0_rtx;
-      fp_p = 0;
+      cmp_mode = DImode;
     }
 
-  if (fp_p && !TARGET_FIX)
-    return NULL_RTX;
+  if (cmp_mode == DFmode && !TARGET_FIX)
+    return 0;
 
   /* The general case: fold the comparison code to the types of compares
      that we have, choosing the branch as necessary.  */
@@ -2584,12 +2579,12 @@ alpha_emit_setcc (enum rtx_code code)
     case EQ:  case LE:  case LT:  case LEU:  case LTU:
     case UNORDERED:
       /* We have these compares.  */
-      if (fp_p)
+      if (cmp_mode == DFmode)
        cmp_code = code, code = NE;
       break;
 
     case NE:
-      if (!fp_p && op1 == const0_rtx)
+      if (cmp_mode == DImode && op1 == const0_rtx)
        break;
       /* FALLTHRU */
 
@@ -2601,10 +2596,10 @@ alpha_emit_setcc (enum rtx_code code)
     case GE:  case GT: case GEU:  case GTU:
       /* These normally need swapping, but for integer zero we have
         special patterns that recognize swapped operands.  */
-      if (!fp_p && op1 == const0_rtx)
+      if (cmp_mode == DImode && op1 == const0_rtx)
        break;
       code = swap_condition (code);
-      if (fp_p)
+      if (cmp_mode == DFmode)
        cmp_code = code, code = NE;
       tmp = op0, op0 = op1, op1 = tmp;
       break;
@@ -2613,7 +2608,7 @@ alpha_emit_setcc (enum rtx_code code)
       gcc_unreachable ();
     }
 
-  if (!fp_p)
+  if (cmp_mode == DImode)
     {
       if (!register_operand (op0, DImode))
        op0 = force_reg (DImode, op0);
@@ -2624,18 +2619,18 @@ alpha_emit_setcc (enum rtx_code code)
   /* Emit an initial compare instruction, if necessary.  */
   if (cmp_code != UNKNOWN)
     {
-      enum machine_mode mode = fp_p ? DFmode : DImode;
-
-      tmp = gen_reg_rtx (mode);
+      tmp = gen_reg_rtx (cmp_mode);
       emit_insn (gen_rtx_SET (VOIDmode, tmp,
-                             gen_rtx_fmt_ee (cmp_code, mode, op0, op1)));
+                             gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1)));
 
-      op0 = fp_p ? gen_lowpart (DImode, tmp) : tmp;
+      op0 = cmp_mode == DImode ? gen_lowpart (DImode, tmp) : tmp;
       op1 = const0_rtx;
     }
 
-  /* Return the setcc comparison.  */
-  return gen_rtx_fmt_ee (code, DImode, op0, op1);
+  /* Emit the setcc instruction.  */
+  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+                         gen_rtx_fmt_ee (code, DImode, op0, op1)));
+  return true;
 }
 
 
@@ -2651,20 +2646,17 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
 {
   enum rtx_code code = GET_CODE (cmp);
   enum rtx_code cmov_code = NE;
-  rtx op0 = alpha_compare.op0;
-  rtx op1 = alpha_compare.op1;
-  int fp_p = alpha_compare.fp_p;
+  rtx op0 = XEXP (cmp, 0);
+  rtx op1 = XEXP (cmp, 1);
   enum machine_mode cmp_mode
     = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
-  enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
   enum machine_mode cmov_mode = VOIDmode;
   int local_fast_math = flag_unsafe_math_optimizations;
   rtx tem;
 
-  /* Zero the operands.  */
-  memset (&alpha_compare, 0, sizeof (alpha_compare));
+  gcc_assert (cmp_mode == DFmode || cmp_mode == DImode);
 
-  if (fp_p != FLOAT_MODE_P (mode))
+  if (FLOAT_MODE_P (cmp_mode) != FLOAT_MODE_P (mode))
     {
       enum rtx_code cmp_code;
 
@@ -2691,7 +2683,7 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
        case GE: case GT: case GEU: case GTU:
          /* These normally need swapping, but for integer zero we have
             special patterns that recognize swapped operands.  */
-         if (!fp_p && op1 == const0_rtx)
+         if (cmp_mode == DImode && op1 == const0_rtx)
            cmp_code = code, code = NE;
          else
            {
@@ -2705,22 +2697,21 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
          gcc_unreachable ();
        }
 
-      tem = gen_reg_rtx (cmp_op_mode);
+      tem = gen_reg_rtx (cmp_mode);
       emit_insn (gen_rtx_SET (VOIDmode, tem,
-                             gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
+                             gen_rtx_fmt_ee (cmp_code, cmp_mode,
                                              op0, op1)));
 
-      cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
-      op0 = gen_lowpart (cmp_op_mode, tem);
-      op1 = CONST0_RTX (cmp_op_mode);
-      fp_p = !fp_p;
+      cmp_mode = cmp_mode == DImode ? DFmode : DImode;
+      op0 = gen_lowpart (cmp_mode, tem);
+      op1 = CONST0_RTX (cmp_mode);
       local_fast_math = 1;
     }
 
   /* We may be able to use a conditional move directly.
      This avoids emitting spurious compares.  */
   if (signed_comparison_operator (cmp, VOIDmode)
-      && (!fp_p || local_fast_math)
+      && (cmp_mode == DImode || local_fast_math)
       && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
     return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
 
@@ -2757,7 +2748,7 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
       gcc_unreachable ();
     }
 
-  if (!fp_p)
+  if (cmp_mode == DImode)
     {
       if (!reg_or_0_operand (op0, DImode))
        op0 = force_reg (DImode, op0);
@@ -2768,12 +2759,12 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
   /* ??? We mark the branch mode to be CCmode to prevent the compare
      and cmov from being combined, since the compare insn follows IEEE
      rules that the cmov does not.  */
-  if (fp_p && !local_fast_math)
+  if (cmp_mode == DFmode && !local_fast_math)
     cmov_mode = CCmode;
 
-  tem = gen_reg_rtx (cmp_op_mode);
-  emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
-  return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
+  tem = gen_reg_rtx (cmp_mode);
+  emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_mode, op0, op1));
+  return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_mode));
 }
 
 /* Simplify a conditional move of two constants into a setcc with
index f33e8e6..ed9bd74 100644 (file)
@@ -803,24 +803,6 @@ extern int alpha_memory_latency;
 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)   \
   function_arg((CUM), (MODE), (TYPE), (NAMED))
 
-/* Try to output insns to set TARGET equal to the constant C if it can be
-   done in less than N insns.  Do all computations in MODE.  Returns the place
-   where the output has been placed if it can be done and the insns have been
-   emitted.  If it would take more than N insns, zero is returned and no
-   insns and emitted.  */
-
-/* Define the information needed to generate branch and scc insns.  This is
-   stored from the compare operation.  Note that we can't use "rtx" here
-   since it hasn't been defined!  */
-
-struct alpha_compare
-{
-  struct rtx_def *op0, *op1;
-  int fp_p;
-};
-
-extern struct alpha_compare alpha_compare;
-
 /* Make (or fake) .linkage entry for function call.
    IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.  */
 
index 543ed53..e6a0578 100644 (file)
 ;; These are the main define_expand's used to make conditional branches
 ;; and compares.
 
-(define_expand "cmpdf"
-  [(set (cc0) (compare (match_operand:DF 0 "reg_or_0_operand" "")
-                      (match_operand:DF 1 "reg_or_0_operand" "")))]
+(define_expand "cbranchdf4"
+  [(use (match_operator 0 "alpha_cbranch_operator"
+         [(match_operand:DF 1 "reg_or_0_operand" "")
+          (match_operand:DF 2 "reg_or_0_operand" "")]))
+   (use (match_operand 3 ""))]
   "TARGET_FP"
-{
-  alpha_compare.op0 = operands[0];
-  alpha_compare.op1 = operands[1];
-  alpha_compare.fp_p = 1;
-  DONE;
-})
+  { alpha_emit_conditional_branch (operands, DFmode); DONE; })
 
-(define_expand "cmptf"
-  [(set (cc0) (compare (match_operand:TF 0 "general_operand" "")
-                      (match_operand:TF 1 "general_operand" "")))]
+(define_expand "cbranchtf4"
+  [(use (match_operator 0 "alpha_cbranch_operator"
+         [(match_operand:TF 1 "general_operand")
+          (match_operand:TF 2 "general_operand")]))
+   (use (match_operand 3 ""))]
   "TARGET_HAS_XFLOATING_LIBS"
-{
-  alpha_compare.op0 = operands[0];
-  alpha_compare.op1 = operands[1];
-  alpha_compare.fp_p = 1;
-  DONE;
-})
-
-(define_expand "cmpdi"
-  [(set (cc0) (compare (match_operand:DI 0 "some_operand" "")
-                      (match_operand:DI 1 "some_operand" "")))]
-  ""
-{
-  alpha_compare.op0 = operands[0];
-  alpha_compare.op1 = operands[1];
-  alpha_compare.fp_p = 0;
-  DONE;
-})
-
-(define_expand "beq"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (EQ); }")
-
-(define_expand "bne"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (NE); }")
-
-(define_expand "blt"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (LT); }")
+  { alpha_emit_conditional_branch (operands, TFmode); DONE; })
 
-(define_expand "ble"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (LE); }")
-
-(define_expand "bgt"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
+(define_expand "cbranchdi4"
+  [(use (match_operator 0 "alpha_cbranch_operator"
+         [(match_operand:DI 1 "some_operand")
+          (match_operand:DI 2 "some_operand")]))
+   (use (match_operand 3 ""))]
   ""
-  "{ operands[1] = alpha_emit_conditional_branch (GT); }")
+  { alpha_emit_conditional_branch (operands, DImode); DONE; })
 
-(define_expand "bge"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (GE); }")
-
-(define_expand "bltu"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (LTU); }")
-
-(define_expand "bleu"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (LEU); }")
-
-(define_expand "bgtu"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (GTU); }")
-
-(define_expand "bgeu"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (GEU); }")
-
-(define_expand "bunordered"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (UNORDERED); }")
-
-(define_expand "bordered"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{ operands[1] = alpha_emit_conditional_branch (ORDERED); }")
-
-(define_expand "seq"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (EQ)) == NULL_RTX) FAIL; }")
-
-(define_expand "sne"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (NE)) == NULL_RTX) FAIL; }")
-
-(define_expand "slt"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (LT)) == NULL_RTX) FAIL; }")
-
-(define_expand "sle"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (LE)) == NULL_RTX) FAIL; }")
-
-(define_expand "sgt"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (GT)) == NULL_RTX) FAIL; }")
-
-(define_expand "sge"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (GE)) == NULL_RTX) FAIL; }")
-
-(define_expand "sltu"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (LTU)) == NULL_RTX) FAIL; }")
-
-(define_expand "sleu"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (LEU)) == NULL_RTX) FAIL; }")
-
-(define_expand "sgtu"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (GTU)) == NULL_RTX) FAIL; }")
-
-(define_expand "sgeu"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (GEU)) == NULL_RTX) FAIL; }")
+(define_expand "cstoredf4"
+  [(use (match_operator:DI 1 "alpha_cbranch_operator"
+         [(match_operand:DF 2 "reg_or_0_operand")
+          (match_operand:DF 3 "reg_or_0_operand")]))
+   (clobber (match_operand:DI 0 "register_operand"))]
+  "TARGET_FP"
+  { if (!alpha_emit_setcc (operands, DFmode)) FAIL; else DONE; })
 
-(define_expand "sunordered"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
-  ""
-  "{ if ((operands[1] = alpha_emit_setcc (UNORDERED)) == NULL_RTX) FAIL; }")
+(define_expand "cstoretf4"
+  [(use (match_operator:DI 1 "alpha_cbranch_operator"
+         [(match_operand:TF 2 "general_operand")
+          (match_operand:TF 3 "general_operand")]))
+   (clobber (match_operand:DI 0 "register_operand"))]
+  "TARGET_HAS_XFLOATING_LIBS"
+  { if (!alpha_emit_setcc (operands, TFmode)) FAIL; else DONE; })
 
-(define_expand "sordered"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_dup 1))]
+(define_expand "cstoredi4"
+  [(use (match_operator:DI 1 "alpha_cbranch_operator"
+         [(match_operand:DI 2 "some_operand")
+          (match_operand:DI 3 "some_operand")]))
+   (clobber (match_operand:DI 0 "register_operand"))]
   ""
-  "{ if ((operands[1] = alpha_emit_setcc (ORDERED)) == NULL_RTX) FAIL; }")
+  { if (!alpha_emit_setcc (operands, DImode)) FAIL; else DONE; })
 \f
 ;; These are the main define_expand's used to make conditional moves.
 
       rtx loop_label = gen_label_rtx ();
       rtx want = gen_reg_rtx (Pmode);
       rtx tmp = gen_reg_rtx (Pmode);
-      rtx memref;
+      rtx memref, test;
 
       emit_insn (gen_subdi3 (want, stack_pointer_rtx,
                             force_reg (Pmode, operands[1])));
       if (!CONST_INT_P (operands[1]))
        {
          out_label = gen_label_rtx ();
-         emit_insn (gen_cmpdi (want, tmp));
-         emit_jump_insn (gen_bgeu (out_label));
+         test = gen_rtx_GEU (VOIDmode, want, tmp);
+         emit_jump_insn (gen_cbranchdi4 (test, want, tmp, out_label));
        }
 
       emit_label (loop_label);
       MEM_VOLATILE_P (memref) = 1;
       emit_move_insn (memref, const0_rtx);
       emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
-      emit_insn (gen_cmpdi (tmp, want));
-      emit_jump_insn (gen_bgtu (loop_label));
+      test = gen_rtx_GTU (VOIDmode, tmp, want);
+      emit_jump_insn (gen_cbranchdi4 (test, tmp, want, loop_label));
 
       memref = gen_rtx_MEM (DImode, want);
       MEM_VOLATILE_P (memref) = 1;
index 425134a..ec11eaa 100644 (file)
   (and (match_code "reg")
        (match_operand 0 "register_operand")))
 
+;; Return 1 if OP is a valid Alpha comparison operator for "cbranch"
+;; instructions.
+(define_predicate "alpha_cbranch_operator"
+  (ior (match_operand 0 "ordered_comparison_operator")
+       (match_code "ordered,unordered")))
+
 ;; Return 1 if OP is a valid Alpha comparison operator for "cmp" style
 ;; instructions.
 (define_predicate "alpha_comparison_operator"
index 3f81f61..1f456b6 100644 (file)
@@ -49,10 +49,6 @@ int arc_cpu_type;
    cpu (or NULL).  */
 const char *arc_mangle_cpu;
 
-/* Save the operands last given to a compare for use when we
-   generate a scc or bcc insn.  */
-rtx arc_compare_op0, arc_compare_op1;
-
 /* Name of text, data, and rodata sections used in varasm.c.  */
 const char *arc_text_section;
 const char *arc_data_section;
@@ -729,21 +725,14 @@ proper_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
 \f
 /* Misc. utilities.  */
 
-/* X and Y are two things to compare using CODE.  Emit the compare insn and
-   return the rtx for the cc reg in the proper mode.  */
+/* X and Y are two things to compare using CODE.  Return the rtx
+   for the cc reg in the proper mode.  */
 
 rtx
 gen_compare_reg (enum rtx_code code, rtx x, rtx y)
 {
   enum machine_mode mode = SELECT_CC_MODE (code, x, y);
-  rtx cc_reg;
-
-  cc_reg = gen_rtx_REG (mode, 61);
-
-  emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
-                         gen_rtx_COMPARE (mode, x, y)));
-
-  return cc_reg;
+  return gen_rtx_REG (mode, 61);
 }
 
 /* Return 1 if VALUE, a const_double, will fit in a limm (4 byte number).
index db6829b..4153ad6 100644 (file)
@@ -1067,11 +1067,6 @@ do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", 1 << (LOG)); } while (0)
 /* ??? Not defined in tm.texi.  */
 #define SETJMP_VIA_SAVE_AREA
 \f
-/* Define the information needed to generate branch and scc insns.  This is
-   stored from the compare operation.  Note that we can't use "rtx" here
-   since it hasn't been defined!  */
-extern struct rtx_def *arc_compare_op0, *arc_compare_op1;
-
 /* ARC function types.  */
 enum arc_function_type {
   ARC_FUNCTION_UNKNOWN, ARC_FUNCTION_NORMAL,
index b67984b..09e47da 100644 (file)
   "
 {
   enum rtx_code code = GET_CODE (operands[1]);
-  rtx ccreg
-    = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
-                  61);
-
-  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+  rtx cc_reg = gen_compare_reg (code, XEXP (operands[1], 0),
+                               XEXP (operands[1], 1));
+  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
 }")
 
-;(define_expand "movdicc"
-;  [(set (match_operand:DI 0 "register_operand" "")
-;      (if_then_else:DI (match_operand 1 "comparison_operator" "")
-;                       (match_operand:DI 2 "nonmemory_operand" "")
-;                       (match_operand:DI 3 "register_operand" "")))]
-;  "0 /* ??? this would work better if we had cmpdi */"
-;  "
-;{
-;  enum rtx_code code = GET_CODE (operands[1]);
-;  rtx ccreg
-;   = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
-;                 61);
-;
-;  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
-;}")
-
 (define_expand "movsfcc"
   [(set (match_operand:SF 0 "register_operand" "")
        (if_then_else:SF (match_operand 1 "comparison_operator" "")
   "
 {
   enum rtx_code code = GET_CODE (operands[1]);
-  rtx ccreg
-    = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
-                  61);
-
-  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+  rtx cc_reg = gen_compare_reg (code, XEXP (operands[1], 0),
+                               XEXP (operands[1], 1));
+  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
 }")
 
-;(define_expand "movdfcc"
-;  [(set (match_operand:DF 0 "register_operand" "")
-;      (if_then_else:DF (match_operand 1 "comparison_operator" "")
-;                       (match_operand:DF 2 "nonmemory_operand" "")
-;                       (match_operand:DF 3 "register_operand" "")))]
-;  "0 /* ??? can generate less efficient code if constants involved */"
-;  "
-;{
-; enum rtx_code code = GET_CODE (operands[1]);
-; rtx ccreg
-;   = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
-;                 61);
-;
-;  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
-;}")
-
 (define_insn "*movsicc_insn"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
   "mov.%d1 %0,%S2"
   [(set_attr "type" "cmove")])
 
-; ??? This doesn't properly handle constants.
-;(define_insn "*movdicc_insn"
-;  [(set (match_operand:DI 0 "register_operand" "=r,r")
-;      (if_then_else:DI (match_operand 1 "comparison_operator" "")
-;                       (match_operand:DI 2 "nonmemory_operand" "r,Ji")
-;                       (match_operand:DI 3 "register_operand" "0,0")))]
-;  "0"
-;  "*
-;{
-;  switch (which_alternative)
-;    {
-;    case 0 :
-;      /* We normally copy the low-numbered register first.  However, if
-;       the first register operand 0 is the same as the second register of
-;       operand 1, we must copy in the opposite order.  */
-;      if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
-;      return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
-;      else
-;      return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
-;    case 1 :
-;      return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
-;    }
-;}"
-;  [(set_attr "type" "cmove,cmove")
-;   (set_attr "length" "2,4")])
-
 (define_insn "*movsfcc_insn"
   [(set (match_operand:SF 0 "register_operand" "=r,r")
        (if_then_else:SF (match_operand 1 "comparison_operator" "")
    mov.%d1 %0,%2 ; %A2"
   [(set_attr "type" "cmove,cmove")])
 
-;(define_insn "*movdfcc_insn"
-;  [(set (match_operand:DF 0 "register_operand" "=r,r")
-;      (if_then_else:DF (match_operand 1 "comparison_operator" "")
-;                       (match_operand:DF 2 "nonmemory_operand" "r,E")
-;                       (match_operand:DF 3 "register_operand" "0,0")))]
-;  "0"
-;  "*
-;{
-;  switch (which_alternative)
-;    {
-;    case 0 :
-;      /* We normally copy the low-numbered register first.  However, if
-;       the first register operand 0 is the same as the second register of
-;       operand 1, we must copy in the opposite order.  */
-;      if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
-;      return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
-;      else
-;      return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
-;    case 1 :
-;      return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\";
-;    }
-;}"
-;  [(set_attr "type" "cmove,cmove")
-;   (set_attr "length" "2,4")])
 \f
 ;; Zero extension instructions.
 ;; ??? We don't support volatile memrefs here, but I'm not sure why.
 ;; Compare instructions.
 ;; This controls RTL generation and register allocation.
 
-;; We generate RTL for comparisons and branches by having the cmpxx 
-;; patterns store away the operands.  Then, the scc and bcc patterns
-;; emit RTL for both the compare and the branch.
-
-(define_expand "cmpsi"
-  [(set (reg:CC 61)
-       (compare:CC (match_operand:SI 0 "register_operand" "")
-                   (match_operand:SI 1 "nonmemory_operand" "")))]
-  ""
-  "
-{
-  arc_compare_op0 = operands[0];
-  arc_compare_op1 = operands[1];
-  DONE;
-}")
-
 ;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
 ;; This assumes sub.f 0,symbol,0 is a valid insn.
 ;; Note that "sub.f 0,r0,1" is an 8 byte insn.  To avoid unnecessarily
    sub.f 0,%0,%1"
   [(set_attr "type" "compare,compare,compare")])
 
-;; Next come the scc insns.
-
-(define_expand "seq"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (eq:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
-}")
+;; Next come the scc insn and its expander.
 
-(define_expand "sne"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (ne:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sgt"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (gt:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sle"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (le:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sge"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (ge:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "slt"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (lt:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sgtu"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (gtu:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sleu"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (leu:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sgeu"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (geu:SI (match_dup 1) (const_int 0)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sltu"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (ltu:SI (match_dup 1) (const_int 0)))]
+(define_expand "cstoresi4"
+  [(set (match_dup 4)
+        (match_op_dup 5
+         [(match_operand:SI 2 "register_operand" "")
+          (match_operand:SI 3 "nonmemory_operand" "")]))
+   (set (match_operand:SI 0 "register_operand")
+        (match_operator:SI 1 "ordered_comparison_operator"
+        [(match_dup 4)
+         (const_int 0)]))]
   ""
   "
 {
-  operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
+  operands[4] = gen_compare_reg (GET_CODE (operands[1]),
+                                operands[2], operands[3]);
+  operands[5] = gen_rtx_fmt_ee (COMPARE,
+                               GET_MODE (operands[4]),
+                               operands[2], operands[3]);
 }")
 
 (define_insn "*scc_insn"
 \f
 ;; These control RTL generation for conditional jump insns
 
-(define_expand "beq"
-  [(set (pc)
-       (if_then_else (eq (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bne"
-  [(set (pc)
-       (if_then_else (ne (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bgt"
-  [(set (pc)
-       (if_then_else (gt (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "ble"
-  [(set (pc)
-       (if_then_else (le (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bge"
-  [(set (pc)
-       (if_then_else (ge (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "blt"
-  [(set (pc)
-       (if_then_else (lt (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bgtu"
-  [(set (pc)
-       (if_then_else (gtu (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bleu"
-  [(set (pc)
-       (if_then_else (leu (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bgeu"
-  [(set (pc)
-       (if_then_else (geu (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bltu"
-  [(set (pc)
-       (if_then_else (ltu (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
+(define_expand "cbranchsi4"
+  [(set (match_dup 4)
+        (match_op_dup 5
+        [(match_operand:SI 1 "register_operand" "")
+          (match_operand:SI 2 "nonmemory_operand" "")]))
+   (set (pc)
+        (if_then_else
+              (match_operator 0 "ordered_comparison_operator"
+              [(match_dup 4)
+               (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
   ""
   "
 {
-  operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
+  operands[4] = gen_compare_reg (GET_CODE (operands[0]),
+                                operands[1], operands[2]);
+  operands[5] = gen_rtx_fmt_ee (COMPARE,
+                               GET_MODE (operands[4]),
+                               operands[1], operands[2]);
 }")
 
 ;; Now match both normal and inverted jump.
index 1d9b426..18e009d 100644 (file)
@@ -418,10 +418,6 @@ extern FILE * asm_out_file;
 /* True if we are currently building a constant table.  */
 int making_const_table;
 
-/* Define the information needed to generate branch insns.  This is
-   stored from the compare operation.  */
-rtx arm_compare_op0, arm_compare_op1;
-
 /* The processor for which instructions should be scheduled.  */
 enum processor_type arm_tune = arm_none;
 
index e7bc7a7..e043090 100644 (file)
@@ -124,10 +124,6 @@ extern arm_cc arm_current_cc;
 extern int arm_target_label;
 extern int arm_ccfsm_state;
 extern GTY(()) rtx arm_target_insn;
-/* Define the information needed to generate branch insns.  This is
-   stored from the compare operation.  */
-extern GTY(()) rtx arm_compare_op0;
-extern GTY(()) rtx arm_compare_op1;
 /* The label of the current constant pool.  */
 extern rtx pool_vector_label;
 /* Set to 1 when a return insn is output, this means that the epilogue
index 8018652..b18173e 100644 (file)
                (match_operand:SI 2 "nonmemory_operand" "")])
              (label_ref (match_operand 3 "" ""))
              (pc)))]
-  "TARGET_THUMB1"
+  "TARGET_THUMB1 || TARGET_32BIT"
   "
+  if (!TARGET_THUMB1)
+    {
+      if (!arm_add_operand (operands[2], SImode))
+       operands[2] = force_reg (SImode, operands[2]);
+      emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
+                                     operands[3]));
+      DONE;
+    }
   if (thumb1_cmpneg_operand (operands[2], SImode))
     {
       emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
     operands[2] = force_reg (SImode, operands[2]);
   ")
 
+(define_expand "cbranchsf4"
+  [(set (pc) (if_then_else
+             (match_operator 0 "arm_comparison_operator"
+              [(match_operand:SF 1 "s_register_operand" "")
+               (match_operand:SF 2 "arm_float_compare_operand" "")])
+             (label_ref (match_operand 3 "" ""))
+             (pc)))]
+  "TARGET_32BIT && TARGET_HARD_FLOAT"
+  "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
+                                  operands[3])); DONE;"
+)
+
+(define_expand "cbranchdf4"
+  [(set (pc) (if_then_else
+             (match_operator 0 "arm_comparison_operator"
+              [(match_operand:DF 1 "s_register_operand" "")
+               (match_operand:DF 2 "arm_float_compare_operand" "")])
+             (label_ref (match_operand 3 "" ""))
+             (pc)))]
+  "TARGET_32BIT && TARGET_HARD_FLOAT"
+  "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
+                                  operands[3])); DONE;"
+)
+
+;; this uses the Cirrus DI compare instruction
+(define_expand "cbranchdi4"
+  [(set (pc) (if_then_else
+             (match_operator 0 "arm_comparison_operator"
+              [(match_operand:DI 1 "cirrus_fp_register" "")
+               (match_operand:DI 2 "cirrus_fp_register" "")])
+             (label_ref (match_operand 3 "" ""))
+             (pc)))]
+  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
+  "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
+                                  operands[3])); DONE;"
+)
+
 (define_insn "*cbranchsi4_insn"
   [(set (pc) (if_then_else
              (match_operator 0 "arm_comparison_operator"
 
 ;; Comparison and test insns
 
-(define_expand "cmpsi"
-  [(match_operand:SI 0 "s_register_operand" "")
-   (match_operand:SI 1 "arm_add_operand" "")]
-  "TARGET_32BIT"
-  "{
-    arm_compare_op0 = operands[0];
-    arm_compare_op1 = operands[1];
-    DONE;
-  }"
-)
-
-(define_expand "cmpsf"
-  [(match_operand:SF 0 "s_register_operand" "")
-   (match_operand:SF 1 "arm_float_compare_operand" "")]
-  "TARGET_32BIT && TARGET_HARD_FLOAT"
-  "
-  arm_compare_op0 = operands[0];
-  arm_compare_op1 = operands[1];
-  DONE;
-  "
-)
-
-(define_expand "cmpdf"
-  [(match_operand:DF 0 "s_register_operand" "")
-   (match_operand:DF 1 "arm_float_compare_operand" "")]
-  "TARGET_32BIT && TARGET_HARD_FLOAT"
-  "
-  arm_compare_op0 = operands[0];
-  arm_compare_op1 = operands[1];
-  DONE;
-  "
-)
-
 (define_insn "*arm_cmpsi_insn"
   [(set (reg:CC CC_REGNUM)
        (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
    (set_attr "cirrus" "compare")]
 )
 
-;; Cirrus DI compare instruction
-(define_expand "cmpdi"
-  [(match_operand:DI 0 "cirrus_fp_register" "")
-   (match_operand:DI 1 "cirrus_fp_register" "")]
-  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
-  "{
-     arm_compare_op0 = operands[0];
-     arm_compare_op1 = operands[1];
-     DONE;
-   }")
-
 (define_insn "*cirrus_cmpdi"
   [(set (reg:CC CC_REGNUM)
        (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
 \f
 ;; Conditional branch insns
 
-(define_expand "beq"
-  [(set (pc)
-       (if_then_else (eq (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bne"
+(define_expand "cbranch_cc"
   [(set (pc)
-       (if_then_else (ne (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bgt"
-  [(set (pc)
-       (if_then_else (gt (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
+       (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
+                                           (match_operand 2 "" "")])
+                     (label_ref (match_operand 3 "" ""))
                      (pc)))]
   "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "ble"
-  [(set (pc)
-       (if_then_else (le (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bge"
-  [(set (pc)
-       (if_then_else (ge (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "blt"
-  [(set (pc)
-       (if_then_else (lt (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bgtu"
-  [(set (pc)
-       (if_then_else (gtu (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bleu"
-  [(set (pc)
-       (if_then_else (leu (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bgeu"
-  [(set (pc)
-       (if_then_else (geu (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bltu"
-  [(set (pc)
-       (if_then_else (ltu (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bunordered"
-  [(set (pc)
-       (if_then_else (unordered (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
-                                     arm_compare_op1);"
-)
-
-(define_expand "bordered"
-  [(set (pc)
-       (if_then_else (ordered (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
-                                     arm_compare_op1);"
-)
-
-(define_expand "bungt"
-  [(set (pc)
-       (if_then_else (ungt (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bunlt"
-  [(set (pc)
-       (if_then_else (unlt (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bunge"
-  [(set (pc)
-       (if_then_else (unge (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bunle"
-  [(set (pc)
-       (if_then_else (unle (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);"
-)
-
-;; The following two patterns need two branch instructions, since there is
-;; no single instruction that will handle all cases.
-(define_expand "buneq"
-  [(set (pc)
-       (if_then_else (uneq (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bltgt"
-  [(set (pc)
-       (if_then_else (ltgt (match_dup 1) (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);"
+  "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
+                                     operands[1], operands[2]);
+   operands[2] = const0_rtx;"
 )
 
 ;;
 
 ; scc insns
 
-(define_expand "seq"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (eq:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sne"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (ne:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sgt"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (gt:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sle"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (le:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sge"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (ge:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "slt"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (lt:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sgtu"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (gtu:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sleu"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (leu:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sgeu"
+(define_expand "cstore_cc"
   [(set (match_operand:SI 0 "s_register_operand" "")
-       (geu:SI (match_dup 1) (const_int 0)))]
+       (match_operator:SI 1 "" [(match_operand 2 "" "")
+                                (match_operand 3 "" "")]))]
   "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sltu"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (ltu:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT"
-  "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sunordered"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (unordered:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
-                                     arm_compare_op1);"
-)
-
-(define_expand "sordered"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (ordered:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
-                                     arm_compare_op1);"
-)
-
-(define_expand "sungt"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (ungt:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
-                                     arm_compare_op1);"
-)
-
-(define_expand "sunge"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (unge:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
-                                     arm_compare_op1);"
-)
-
-(define_expand "sunlt"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (unlt:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
-                                     arm_compare_op1);"
-)
-
-(define_expand "sunle"
-  [(set (match_operand:SI 0 "s_register_operand" "")
-       (unle:SI (match_dup 1) (const_int 0)))]
-  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-  "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
-                                     arm_compare_op1);"
+  "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
+                                     operands[2], operands[3]);
+   operands[3] = const0_rtx;"
 )
 
-;;; DO NOT add patterns for SUNEQ or SLTGT, these can't be represented with
-;;; simple ARM instructions. 
-;
-; (define_expand "suneq"
-;   [(set (match_operand:SI 0 "s_register_operand" "")
-;      (uneq:SI (match_dup 1) (const_int 0)))]
-;   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-;   "gcc_unreachable ();"
-; )
-;
-; (define_expand "sltgt"
-;   [(set (match_operand:SI 0 "s_register_operand" "")
-;      (ltgt:SI (match_dup 1) (const_int 0)))]
-;   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-;   "gcc_unreachable ();"
-; )
-
 (define_insn "*mov_scc"
   [(set (match_operand:SI 0 "s_register_operand" "=r")
        (match_operator:SI 1 "arm_comparison_operator"
        (match_operator:SI 1 "arm_comparison_operator"
         [(match_operand:SI 2 "s_register_operand" "")
          (match_operand:SI 3 "reg_or_int_operand" "")]))]
-  "TARGET_THUMB1"
+  "TARGET_32BIT || TARGET_THUMB1"
   "{
   rtx op3, scratch, scratch2;
 
+  if (!TARGET_THUMB1)
+    {
+      if (!arm_add_operand (operands[3], SImode))
+       operands[3] = force_reg (SImode, operands[3]);
+      emit_insn (gen_cstore_cc (operands[0], operands[1],
+                               operands[2], operands[3]));
+      DONE;
+    }
+
   if (operands[3] == const0_rtx)
     {
       switch (GET_CODE (operands[1]))
   DONE;
 }")
 
+(define_expand "cstoresf4"
+  [(set (match_operand:SI 0 "s_register_operand" "")
+       (match_operator:SI 1 "arm_comparison_operator"
+        [(match_operand:SF 2 "s_register_operand" "")
+         (match_operand:SF 3 "arm_float_compare_operand" "")]))]
+  "TARGET_32BIT && TARGET_HARD_FLOAT"
+  "emit_insn (gen_cstore_cc (operands[0], operands[1],
+                            operands[2], operands[3])); DONE;"
+)
+
+(define_expand "cstoredf4"
+  [(set (match_operand:SI 0 "s_register_operand" "")
+       (match_operator:SI 1 "arm_comparison_operator"
+        [(match_operand:DF 2 "s_register_operand" "")
+         (match_operand:DF 3 "arm_float_compare_operand" "")]))]
+  "TARGET_32BIT && TARGET_HARD_FLOAT"
+  "emit_insn (gen_cstore_cc (operands[0], operands[1],
+                            operands[2], operands[3])); DONE;"
+)
+
+;; this uses the Cirrus DI compare instruction
+(define_expand "cstoredi4"
+  [(set (match_operand:SI 0 "s_register_operand" "")
+       (match_operator:SI 1 "arm_comparison_operator"
+        [(match_operand:DI 2 "cirrus_fp_register" "")
+         (match_operand:DI 3 "cirrus_fp_register" "")]))]
+  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
+  "emit_insn (gen_cstore_cc (operands[0], operands[1],
+                            operands[2], operands[3])); DONE;"
+)
+
+
 (define_expand "cstoresi_eq0_thumb1"
   [(parallel
     [(set (match_operand:SI 0 "s_register_operand" "")
     if (code == UNEQ || code == LTGT)
       FAIL;
 
-    ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
+    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
+                                XEXP (operands[1], 1));
     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
   }"
 )
         || (!arm_float_add_operand (operands[3], SFmode)))
       operands[3] = force_reg (SFmode, operands[3]);
 
-    ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
+    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
+                                XEXP (operands[1], 1));
     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
   }"
 )
     if (code == UNEQ || code == LTGT)
       FAIL;
 
-    ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
+    ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
+                                XEXP (operands[1], 1));
     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
   }"
 )
index c7d6335..b45faf4 100644 (file)
 (define_special_predicate "equality_operator"
   (match_code "eq,ne"))
 
-;; True for comparisons other than LTGT or UNEQ.
+;; True for integer comparisons and, if FP is active, for comparisons
+;; other than LTGT or UNEQ.
 (define_special_predicate "arm_comparison_operator"
-  (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt"))
+  (ior (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu")
+       (and (match_test "TARGET_32BIT && TARGET_HARD_FLOAT
+                        && (TARGET_FPA || TARGET_VFP)")
+            (match_code "unordered,ordered,unlt,unle,unge,ungt"))))
 
 (define_special_predicate "minmax_operator"
   (and (match_code "smin,smax,umin,umax")
index 4424690..f4d2119 100644 (file)
@@ -72,8 +72,8 @@ extern const char *out_movhi_mr_r (rtx insn, rtx op[], int *l);
 extern const char *out_movsi_r_mr (rtx insn, rtx op[], int *l);
 extern const char *out_movsi_mr_r (rtx insn, rtx op[], int *l);
 extern const char *output_movsisf (rtx insn, rtx operands[], int *l);
-extern const char *out_tstsi (rtx insn, int *l);
-extern const char *out_tsthi (rtx insn, int *l);
+extern const char *out_tstsi (rtx insn, rtx src, int *l);
+extern const char *out_tsthi (rtx insn, rtx src, int *l);
 extern const char *ret_cond_branch (rtx x, int len, int reverse);
 
 extern const char *ashlqi3_out (rtx insn, rtx operands[], int *len);
index 6bcc8e8..4811b92 100644 (file)
@@ -2915,21 +2915,21 @@ compare_eq_p (rtx insn)
 /* Output test instruction for HImode.  */
 
 const char *
-out_tsthi (rtx insn, int *l)
+out_tsthi (rtx insn, rtx op, int *l)
 {
   if (compare_sign_p (insn))
     {
       if (l) *l = 1;
       return AS1 (tst,%B0);
     }
-  if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
+  if (reg_unused_after (insn, op)
       && compare_eq_p (insn))
     {
       /* Faster than sbiw if we can clobber the operand.  */
       if (l) *l = 1;
       return AS2 (or,%A0,%B0);
     }
-  if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
+  if (test_hard_reg_class (ADDW_REGS, op))
     {
       if (l) *l = 1;
       return AS2 (sbiw,%0,0);
@@ -2943,14 +2943,14 @@ out_tsthi (rtx insn, int *l)
 /* Output test instruction for SImode.  */
 
 const char *
-out_tstsi (rtx insn, int *l)
+out_tstsi (rtx insn, rtx op, int *l)
 {
   if (compare_sign_p (insn))
     {
       if (l) *l = 1;
       return AS1 (tst,%D0);
     }
-  if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
+  if (test_hard_reg_class (ADDW_REGS, op))
     {
       if (l) *l = 3;
       return (AS2 (sbiw,%A0,0) CR_TAB
@@ -4367,8 +4367,8 @@ adjust_insn_length (rtx insn, int len)
        {
          switch (GET_MODE (op[1]))
            {
-           case HImode: out_tsthi (insn,&len); break;
-           case SImode: out_tstsi (insn,&len); break;
+           case HImode: out_tsthi (insn, op[1], &len); break;
+           case SImode: out_tstsi (insn, op[1], &len); break;
            default: break;
            }
        }
@@ -5734,6 +5734,21 @@ avr_reorg (void)
                  XEXP (pattern,1) = x;
                  INSN_CODE (next) = -1;
                }
+             else if (true_regnum (XEXP (pattern, 0)) >= 0
+                      && XEXP (pattern, 1) == const0_rtx)
+               {
+                 /* This is a tst insn, we can reverse it.  */
+                 rtx next = next_real_insn (insn);
+                 rtx pat = PATTERN (next);
+                 rtx src = SET_SRC (pat);
+                 rtx t = XEXP (src,0);
+    
+                 PUT_CODE (t, swap_condition (GET_CODE (t)));
+                 XEXP (pattern, 1) = XEXP (pattern, 0);
+                 XEXP (pattern, 0) = const0_rtx;
+                 INSN_CODE (next) = -1;
+                 INSN_CODE (insn) = -1;
+               }
              else if (true_regnum (XEXP (pattern,0)) >= 0
                       && GET_CODE (XEXP (pattern,1)) == CONST_INT)
                {
@@ -5753,20 +5768,6 @@ avr_reorg (void)
                    }
                }
            }
-         else if (true_regnum (SET_SRC (pattern)) >= 0)
-           {
-             /* This is a tst insn */
-             rtx next = next_real_insn (insn);
-             rtx pat = PATTERN (next);
-             rtx src = SET_SRC (pat);
-             rtx t = XEXP (src,0);
-
-             PUT_CODE (t, swap_condition (GET_CODE (t)));
-             SET_SRC (pattern) = gen_rtx_COMPARE (GET_MODE (SET_SRC (pattern)), const0_rtx,
-                                              SET_SRC (pattern));
-             INSN_CODE (next) = -1;
-             INSN_CODE (insn) = -1;
-           }
        }
     }
 }
index 269e2c5..86a217d 100644 (file)
 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
 ;; compare
 
-(define_insn "tstqi"
+; Optimize negated tests into reverse compare if overflow is undefined.
+(define_insn "*negated_tstqi"
   [(set (cc0)
-        (match_operand:QI 0 "register_operand" "r"))]
-  ""
-  "tst %0"
+        (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
+                (const_int 0)))]
+  "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
+  "cp __zero_reg__,%0"
   [(set_attr "cc" "compare")
    (set_attr "length" "1")])
 
 (define_insn "*reversed_tstqi"
   [(set (cc0)
-        (compare (const_int 0)  
+        (compare (const_int 0)
                 (match_operand:QI 0 "register_operand" "r")))]
   ""
   "cp __zero_reg__,%0"
-  [(set_attr "cc" "compare")
  (set_attr "length" "1")])
+[(set_attr "cc" "compare")
(set_attr "length" "2")])
 
-(define_insn "tsthi"
+(define_insn "*negated_tsthi"
   [(set (cc0)
-        (match_operand:HI 0 "register_operand" "!w,r"))]
-  ""
-  "* return out_tsthi (insn,NULL);"
-[(set_attr "cc" "compare,compare")
- (set_attr "length" "1,2")])
+        (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
+                (const_int 0)))]
+  "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
+  "cp __zero_reg__,%A0
+       cpc __zero_reg__,%B0"
+[(set_attr "cc" "compare")
+ (set_attr "length" "2")])
 
+;; Leave here the clobber used by the cmphi pattern for simplicity, even
+;; though it is unused, because this pattern is synthesized by avr_reorg.
 (define_insn "*reversed_tsthi"
   [(set (cc0)
         (compare (const_int 0)
-                (match_operand:HI 0 "register_operand" "r")))]
+                (match_operand:HI 0 "register_operand" "r")))
+   (clobber (match_scratch:QI 1 "=X"))]
   ""
   "cp __zero_reg__,%A0
        cpc __zero_reg__,%B0"
 [(set_attr "cc" "compare")
  (set_attr "length" "2")])
 
-(define_insn "tstsi"
+(define_insn "*negated_tstsi"
   [(set (cc0)
-        (match_operand:SI 0 "register_operand" "r"))]
-  ""
-  "* return out_tstsi (insn,NULL);"
+        (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
+                (const_int 0)))]
+  "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
+  "cp __zero_reg__,%A0
+       cpc __zero_reg__,%B0
+       cpc __zero_reg__,%C0
+       cpc __zero_reg__,%D0"
   [(set_attr "cc" "compare")
    (set_attr "length" "4")])
 
 (define_insn "*reversed_tstsi"
   [(set (cc0)
-        (compare (const_int 0)  
-                (match_operand:SI 0 "register_operand" "r")))]
+        (compare (const_int 0)
+                (match_operand:SI 0 "register_operand" "r")))
+   (clobber (match_scratch:QI 1 "=X"))]
   ""
   "cp __zero_reg__,%A0
        cpc __zero_reg__,%B0
    (set_attr "length" "4")])
 
 
-(define_insn "cmpqi"
+(define_insn "*cmpqi"
   [(set (cc0)
-        (compare (match_operand:QI 0 "register_operand"  "r,d")
-                (match_operand:QI 1 "nonmemory_operand" "r,i")))]
+        (compare (match_operand:QI 0 "register_operand"  "r,r,d")
+                (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
   ""
   "@
+       tst %0
        cp %0,%1
        cpi %0,lo8(%1)"
-  [(set_attr "cc" "compare,compare")
-   (set_attr "length" "1,1")])
+  [(set_attr "cc" "compare,compare,compare")
+   (set_attr "length" "1,1,1")])
 
 (define_insn "*cmpqi_sign_extend"
   [(set (cc0)
   [(set_attr "cc" "compare")
    (set_attr "length" "1")])
 
-(define_insn "cmphi"
+(define_insn "*cmphi"
   [(set (cc0)
-       (compare (match_operand:HI 0 "register_operand"  "r,d,d,r,r")
-                (match_operand:HI 1 "nonmemory_operand" "r,M,i,M,i")))
-   (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
+       (compare (match_operand:HI 0 "register_operand"  "!w,r,r,d,d,r,r")
+                (match_operand:HI 1 "nonmemory_operand" "L,L,r,M,i,M,i")))
+   (clobber (match_scratch:QI 2 "=X,X,X,X,&d,&d,&d"))]
   ""
   "*{
   switch (which_alternative)
     {
-    case 0:
+    case 0: case 1:
+      return out_tsthi (insn, operands[0], NULL);
+
+    case 2:
       return (AS2 (cp,%A0,%A1) CR_TAB
               AS2 (cpc,%B0,%B1));
-    case 1:
+    case 3:
       if (reg_unused_after (insn, operands[0])
           && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
           && test_hard_reg_class (ADDW_REGS, operands[0]))
        else
         return (AS2 (cpi,%0,%1) CR_TAB
                 AS2 (cpc,%B0,__zero_reg__));
-    case 2:
+    case 4:
       if (reg_unused_after (insn, operands[0]))
         return (AS2 (subi,%0,lo8(%1))  CR_TAB
                 AS2 (sbci,%B0,hi8(%1)));
         return (AS2 (ldi, %2,hi8(%1))  CR_TAB
                AS2 (cpi, %A0,lo8(%1)) CR_TAB
                AS2 (cpc, %B0,%2));
-   case 3:
+   case 5:
       return (AS2 (ldi, %2,lo8(%1))  CR_TAB
              AS2 (cp, %A0,%2) CR_TAB
              AS2 (cpc, %B0,__zero_reg__));
 
-   case 4:
+   case 6:
       return (AS2 (ldi, %2,lo8(%1))  CR_TAB
               AS2 (cp, %A0,%2)       CR_TAB
               AS2 (ldi, %2,hi8(%1)) CR_TAB
     }
   return \"bug\";
 }" 
-  [(set_attr "cc" "compare,compare,compare,compare,compare")
-   (set_attr "length" "2,2,3,3,4")])
+  [(set_attr "cc" "compare,compare,compare,compare,compare,compare,compare")
+   (set_attr "length" "1,2,2,2,3,3,4")])
 
 
-(define_insn "cmpsi"
+(define_insn "*cmpsi"
   [(set (cc0)
-       (compare (match_operand:SI 0 "register_operand"  "r,d,d,r,r")
-                (match_operand:SI 1 "nonmemory_operand" "r,M,i,M,i")))
-   (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
+       (compare (match_operand:SI 0 "register_operand"  "r,r,d,d,r,r")
+                (match_operand:SI 1 "nonmemory_operand" "L,r,M,i,M,i")))
+   (clobber (match_scratch:QI 2 "=X,X,X,&d,&d,&d"))]
   ""
   "*{
   switch (which_alternative)
     {
     case 0:
+      return out_tstsi (insn, operands[0], NULL);
+
+    case 1:
       return (AS2 (cp,%A0,%A1) CR_TAB
               AS2 (cpc,%B0,%B1) CR_TAB
              AS2 (cpc,%C0,%C1) CR_TAB
              AS2 (cpc,%D0,%D1));
-    case 1:
+    case 2:
       if (reg_unused_after (insn, operands[0])
           && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
           && test_hard_reg_class (ADDW_REGS, operands[0]))
                 AS2 (cpc,%B0,__zero_reg__) CR_TAB
                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
                 AS2 (cpc,%D0,__zero_reg__));
-    case 2:
+    case 3:
       if (reg_unused_after (insn, operands[0]))
         return (AS2 (subi,%A0,lo8(%1))  CR_TAB
                 AS2 (sbci,%B0,hi8(%1))  CR_TAB
               AS2 (cpc, %C0,%2)       CR_TAB
               AS2 (ldi, %2,hhi8(%1)) CR_TAB
               AS2 (cpc, %D0,%2));
-    case 3:
+    case 4:
         return (AS2 (ldi,%2,lo8(%1))        CR_TAB
                 AS2 (cp,%A0,%2)            CR_TAB
                 AS2 (cpc,%B0,__zero_reg__) CR_TAB
                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
                 AS2 (cpc,%D0,__zero_reg__));
-    case 4:
+    case 5:
        return (AS2 (ldi, %2,lo8(%1))   CR_TAB
                AS2 (cp, %A0,%2)        CR_TAB
               AS2 (ldi, %2,hi8(%1))  CR_TAB
     }
   return \"bug\";
 }"
-  [(set_attr "cc" "compare,compare,compare,compare,compare")
-   (set_attr "length" "4,4,7,5,8")])
-
-; Optimize negated tests into reverse compare if overflow is undefined.
-(define_insn_and_split "negated_tst<mode>"
- [(set (cc0)
-        (neg:QISI (match_operand:QISI 0 "register_operand")))]
+  [(set_attr "cc" "compare,compare,compare,compare,compare,compare")
+   (set_attr "length" "4,4,4,7,5,8")])
 
-  "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
-  "#"
-  ""
-  [(set (cc0)
-        (compare (const_int 0)  
-                (match_dup 0)))]
-  "")
 
 ;; ----------------------------------------------------------------------
 ;; JUMP INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 ;; Conditional jump instructions
 
-(define_expand "beq"
-  [(set (pc)
-        (if_then_else (eq (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-(define_expand "bne"
-  [(set (pc)
-        (if_then_else (ne (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-(define_expand "bge"
-  [(set (pc)
-        (if_then_else (ge (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-(define_expand "bgeu"
-  [(set (pc)
-        (if_then_else (geu (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-(define_expand "blt"
-  [(set (pc)
-        (if_then_else (lt (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-(define_expand "bltu"
-  [(set (pc)
-        (if_then_else (ltu (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-
-
-/****************************************************************
- AVR not have following conditional jumps: LE,LEU,GT,GTU.
- Convert them all to proper jumps.
-*****************************************************************/
-
-(define_expand "ble"
-  [(set (pc)
-        (if_then_else (le (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
-
-(define_expand "bleu"
-  [(set (pc)
-        (if_then_else (leu (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
+(define_expand "cbranchsi4"
+  [(parallel [(set (cc0)
+                  (compare (match_operand:SI 1 "register_operand" "")
+                           (match_operand:SI 2 "nonmemory_operand" "")))
+             (clobber (match_scratch:QI 4 ""))])
+   (set (pc)
+        (if_then_else
+              (match_operator 0 "ordered_comparison_operator" [(cc0)
+                                                               (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+ "")
+
+(define_expand "cbranchhi4"
+  [(parallel [(set (cc0)
+                  (compare (match_operand:HI 1 "register_operand" "")
+                           (match_operand:HI 2 "nonmemory_operand" "")))
+             (clobber (match_scratch:QI 4 ""))])
+   (set (pc)
+        (if_then_else
+              (match_operator 0 "ordered_comparison_operator" [(cc0)
+                                                               (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+ "")
 
-(define_expand "bgt"
-  [(set (pc)
-        (if_then_else (gt (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
+(define_expand "cbranchqi4"
+  [(set (cc0)
+        (compare (match_operand:QI 1 "register_operand" "")
+                 (match_operand:QI 2 "nonmemory_operand" "")))
+   (set (pc)
+        (if_then_else
+              (match_operator 0 "ordered_comparison_operator" [(cc0)
+                                                               (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+ "")
 
-(define_expand "bgtu"
-  [(set (pc)
-        (if_then_else (gtu (cc0) (const_int 0))
-                      (label_ref (match_operand 0 "" ""))
-                      (pc)))]
-  ""
-  "")
 
 ;; Test a single bit in a QI/HI/SImode register.
 (define_insn "*sbrx_branch"
 
 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
 (define_peephole2
-  [(set (cc0) (match_operand:QI 0 "register_operand" ""))
+  [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
+                      (const_int 0)))
    (set (pc) (if_then_else (ge (cc0) (const_int 0))
                           (label_ref (match_operand 1 "" ""))
                           (pc)))]
   "")
 
 (define_peephole2
-  [(set (cc0) (match_operand:QI 0 "register_operand" ""))
+  [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
+                      (const_int 0)))
    (set (pc) (if_then_else (lt (cc0) (const_int 0))
                           (label_ref (match_operand 1 "" ""))
                           (pc)))]
   "")
 
 (define_peephole2
-  [(set (cc0) (match_operand:HI 0 "register_operand" ""))
+  [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
+                                 (const_int 0)))
+             (clobber (match_operand:HI 2 ""))])
    (set (pc) (if_then_else (ge (cc0) (const_int 0))
                           (label_ref (match_operand 1 "" ""))
                           (pc)))]
   "")
 
 (define_peephole2
-  [(set (cc0) (match_operand:HI 0 "register_operand" ""))
+  [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
+                                 (const_int 0)))
+             (clobber (match_operand:HI 2 ""))])
    (set (pc) (if_then_else (lt (cc0) (const_int 0))
                           (label_ref (match_operand 1 "" ""))
                           (pc)))]
   "")
 
 (define_peephole2
-  [(set (cc0) (match_operand:SI 0 "register_operand" ""))
+  [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
+                                 (const_int 0)))
+             (clobber (match_operand:SI 2 ""))])
    (set (pc) (if_then_else (ge (cc0) (const_int 0))
                           (label_ref (match_operand 1 "" ""))
                           (pc)))]
   "operands[2] = GEN_INT (-2147483647 - 1);")
 
 (define_peephole2
-  [(set (cc0) (match_operand:SI 0 "register_operand" ""))
+  [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
+                                 (const_int 0)))
+             (clobber (match_operand:SI 2 ""))])
    (set (pc) (if_then_else (lt (cc0) (const_int 0))
                           (label_ref (match_operand 1 "" ""))
                           (pc)))]
   [(set_attr "type" "branch")
    (set_attr "cc" "clobber")])
 
+;; ****************************************************************
+;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
+;; Convert them all to proper jumps.
+;; ****************************************************************/
+
 (define_insn "difficult_branch"
   [(set (pc)
         (if_then_else (match_operator 1 "difficult_comparison_operator"
 }")
 
 (define_peephole
-  [(set (cc0) (match_operand:QI 0 "register_operand" ""))
+  [(set (cc0)
+       (compare (match_operand:QI 0 "register_operand" "")
+                (const_int 0)))
    (set (pc)
        (if_then_else (eq (cc0) (const_int 0))
                      (label_ref (match_operand 1 "" ""))
index 077d5c5..ac237d7 100644 (file)
@@ -67,10 +67,6 @@ struct GTY(()) machine_function
   int has_loopreg_clobber;
 };
 
-/* Test and compare insns in bfin.md store the information needed to
-   generate branch and scc insns here.  */
-rtx bfin_compare_op0, bfin_compare_op1;
-
 /* RTX for condition code flag register and RETS register */
 extern GTY(()) rtx bfin_cc_rtx;
 extern GTY(()) rtx bfin_rets_rtx;
@@ -2714,7 +2710,7 @@ rtx
 bfin_gen_compare (rtx cmp, enum machine_mode mode ATTRIBUTE_UNUSED)
 {
   enum rtx_code code1, code2;
-  rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
+  rtx op0 = XEXP (cmp, 0), op1 = XEXP (cmp, 1);
   rtx tem = bfin_cc_rtx;
   enum rtx_code code = GET_CODE (cmp);
 
@@ -2742,7 +2738,7 @@ bfin_gen_compare (rtx cmp, enum machine_mode mode ATTRIBUTE_UNUSED)
        code2 = EQ;
        break;
       }
-      emit_insn (gen_rtx_SET (BImode, tem,
+      emit_insn (gen_rtx_SET (VOIDmode, tem,
                              gen_rtx_fmt_ee (code1, BImode, op0, op1)));
     }
 
@@ -4219,17 +4215,17 @@ bfin_optimize_loop (loop_info loop)
     {
       /* If loop->iter_reg is a DREG or PREG, we can split it here
         without scratch register.  */
-      rtx insn;
+      rtx insn, test;
 
       emit_insn_before (gen_addsi3 (loop->iter_reg,
                                    loop->iter_reg,
                                    constm1_rtx),
                        loop->loop_end);
 
-      emit_insn_before (gen_cmpsi (loop->iter_reg, const0_rtx),
-                       loop->loop_end);
-
-      insn = emit_jump_insn_before (gen_bne (loop->start_label),
+      test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx);
+      insn = emit_jump_insn_before (gen_cbranchsi4 (test,
+                                                   loop->iter_reg, const0_rtx,
+                                                   loop->start_label),
                                    loop->loop_end);
 
       JUMP_LABEL (insn) = loop->start_label;
index d97fe8f..352f4b4 100644 (file)
@@ -1292,7 +1292,6 @@ do {                                              \
 #define ASM_OUTPUT_REG_PUSH(FILE, REGNO) fprintf (FILE, "[SP--] = %s;\n", reg_names[REGNO])
 #define ASM_OUTPUT_REG_POP(FILE, REGNO)  fprintf (FILE, "%s = [SP++];\n", reg_names[REGNO])
 
-extern struct rtx_def *bfin_compare_op0, *bfin_compare_op1;
 extern struct rtx_def *bfin_cc_rtx, *bfin_rets_rtx;
 
 /* This works for GAS and some other assemblers.  */
index 4397b7a..755a0d3 100644 (file)
 ;; Conditional branch patterns
 ;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
 
-;; The only outcome of this pattern is that global variables
-;; bfin_compare_op[01] are set for use in bcond patterns.
-
-(define_expand "cmpbi"
- [(set (cc0) (compare (match_operand:BI 0 "register_operand" "")
-                      (match_operand:BI 1 "immediate_operand" "")))]
- ""
-{
-  bfin_compare_op0 = operands[0];
-  bfin_compare_op1 = operands[1];
-  DONE;
-})
-
-(define_expand "cmpsi"
- [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
-                      (match_operand:SI 1 "reg_or_const_int_operand" "")))]
- ""
-{
-  bfin_compare_op0 = operands[0];
-  bfin_compare_op1 = operands[1];
-  DONE;
-})
-
 (define_insn "compare_eq"
   [(set (match_operand:BI 0 "register_operand" "=C,C")
         (eq:BI (match_operand:SI 1 "register_operand" "d,a")
   "cc =%1<%2 (iu);"
   [(set_attr "type" "compare")])
 
-(define_expand "beq"
-  [(set (match_dup 1) (match_dup 2))
-   (set (pc)
-       (if_then_else (match_dup 3)
-                  (label_ref (match_operand 0 "" ""))
-                  (pc)))]
-  ""
-{
-  rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
-  operands[1] = bfin_cc_rtx;   /* hard register: CC */
-  operands[2] = gen_rtx_EQ (BImode, op0, op1);
-  /* If we have a BImode input, then we already have a compare result, and
-     do not need to emit another comparison.  */
-  if (GET_MODE (bfin_compare_op0) == BImode)
-    {
-      gcc_assert (bfin_compare_op1 == const0_rtx);
-      emit_insn (gen_cbranchbi4 (operands[2], op0, op1, operands[0]));
-      DONE;
-    }
-
-  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "bne"
-  [(set (match_dup 1) (match_dup 2))
-   (set (pc)
-       (if_then_else (match_dup 3)
-                     (label_ref (match_operand 0 "" ""))
-                   (pc)))]
-  ""
-{
-  rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
-  /* If we have a BImode input, then we already have a compare result, and
-     do not need to emit another comparison.  */
-  if (GET_MODE (bfin_compare_op0) == BImode)
-    {
-      rtx cmp = gen_rtx_NE (BImode, op0, op1);
-
-      gcc_assert (bfin_compare_op1 == const0_rtx);
-      emit_insn (gen_cbranchbi4 (cmp, op0, op1, operands[0]));
-      DONE;
-    }
-
-  operands[1] = bfin_cc_rtx;   /* hard register: CC */
-  operands[2] = gen_rtx_EQ (BImode, op0, op1);
-  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "bgt"
-  [(set (match_dup 1) (match_dup 2))
-   (set (pc)
-       (if_then_else (match_dup 3)
-                     (label_ref (match_operand 0 "" ""))
-                   (pc)))]
-  ""
-{
-  operands[1] = bfin_cc_rtx;
-  operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
-  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "bgtu"
-  [(set (match_dup 1) (match_dup 2))
-   (set (pc)
-       (if_then_else (match_dup 3)
-                     (label_ref (match_operand 0 "" ""))
-                   (pc)))]
-  ""
-{
-  operands[1] = bfin_cc_rtx;
-  operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
-  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "blt"
-  [(set (match_dup 1) (match_dup 2))
-   (set (pc)
-       (if_then_else (match_dup 3)
-                     (label_ref (match_operand 0 "" ""))
-                   (pc)))]
-  ""
-{
-  operands[1] = bfin_cc_rtx;
-  operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
-  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "bltu"
-  [(set (match_dup 1) (match_dup 2))
-   (set (pc)
-       (if_then_else (match_dup 3)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-{
-  operands[1] = bfin_cc_rtx;
-  operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
-  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
-})
-
 ;; Same as above, but and CC with the overflow bit generated by the first
 ;; multiplication.
 (define_insn "flag_mul_macv2hi_parts_acconly_andcc0"
    (set_attr "length" "6")
    (set_attr "seq_insns" "multi")])
 
-(define_expand "bge"
-  [(set (match_dup 1) (match_dup 2))
-   (set (pc)
-       (if_then_else (match_dup 3)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-{
-  operands[1] = bfin_cc_rtx;
-  operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
-  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "bgeu"
-  [(set (match_dup 1) (match_dup 2))
-   (set (pc)
-       (if_then_else (match_dup 3)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-{
-  operands[1] = bfin_cc_rtx;
-  operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
-  operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "ble"
-  [(set (match_dup 1) (match_dup 2))
-   (set (pc)
-       (if_then_else (match_dup 3)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-{
-  operands[1] = bfin_cc_rtx;
-  operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
-  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "bleu"
-  [(set (match_dup 1) (match_dup 2))
-   (set (pc)
-       (if_then_else (match_dup 3)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))
-  ]
+(define_expand "cbranchsi4"
+  [(set (pc)
+        (if_then_else (match_operator 0 "ordered_comparison_operator"
+                       [(match_operand:SI 1 "register_operand" "")
+                        (match_operand:SI 2 "reg_or_const_int_operand" "")])
+                   (label_ref (match_operand 3 "" ""))
+                   (pc)))]
   ""
 {
-  operands[1] = bfin_cc_rtx;
-  operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
-  operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
+  rtx bi_compare = bfin_gen_compare (operands[0], SImode);
+  emit_jump_insn (gen_cbranchbi4 (bi_compare, bfin_cc_rtx, CONST0_RTX (BImode),
+                                 operands[3]));
+  DONE;
 })
 
 (define_insn "cbranchbi4"
   [(set (pc)
        (if_then_else
-        (match_operator 0 "bfin_cbranch_operator"
+        (match_operator 0 "bfin_bimode_comparison_operator"
                         [(match_operand:BI 1 "register_operand" "C")
                          (match_operand:BI 2 "immediate_operand" "P0")])
         (label_ref (match_operand 3 "" ""))
 (define_insn "cbranch_predicted_taken"
   [(set (pc)
        (if_then_else
-        (match_operator 0 "bfin_cbranch_operator"
+        (match_operator 0 "bfin_bimode_comparison_operator"
                         [(match_operand:BI 1 "register_operand" "C")
                          (match_operand:BI 2 "immediate_operand" "P0")])
         (label_ref (match_operand 3 "" ""))
 (define_insn "cbranch_with_nops"
   [(set (pc)
        (if_then_else
-        (match_operator 0 "bfin_cbranch_operator"
+        (match_operator 0 "bfin_bimode_comparison_operator"
                         [(match_operand:BI 1 "register_operand" "C")
                          (match_operand:BI 2 "immediate_operand" "P0")])
         (label_ref (match_operand 3 "" ""))
   [(set_attr "type" "brcc")
    (set_attr "length" "8")])
 
-;; setcc insns.  */
-(define_expand "seq"
-  [(set (match_dup 1) (eq:BI (match_dup 2) (match_dup 3)))
-   (set (match_operand:SI 0 "register_operand" "")
-       (ne:SI (match_dup 1) (const_int 0)))]
-  ""
-{
-  operands[2] = bfin_compare_op0;
-  operands[3] = bfin_compare_op1;
-  operands[1] = bfin_cc_rtx;
-})
+;; setcc insns.
 
-(define_expand "slt"
-  [(set (match_dup 1) (lt:BI (match_dup 2) (match_dup 3)))
+(define_expand "cstorebi4"
+  [(set (match_dup 4)
+        (match_operator:BI 1 "bfin_bimode_comparison_operator"
+                       [(match_operand:BI 2 "register_operand" "")
+                        (match_operand:BI 3 "reg_or_const_int_operand" "")]))
    (set (match_operand:SI 0 "register_operand" "")
-       (ne:SI (match_dup 1) (const_int 0)))]
+       (ne:SI (match_dup 4) (const_int 0)))]
   ""
 {
-   operands[2] = bfin_compare_op0;
-   operands[3] = bfin_compare_op1;
-   operands[1] = bfin_cc_rtx;
-})
+  /* It could be expanded as a movbisi instruction, but the portable
+     alternative produces better code.  */
+  if (GET_CODE (operands[1]) == NE)
+    FAIL;
 
-(define_expand "sle"
-  [(set (match_dup 1) (le:BI (match_dup 2) (match_dup 3)))
-   (set (match_operand:SI 0 "register_operand" "")
-       (ne:SI (match_dup 1) (const_int 0)))]
-  ""
-{
-   operands[2] = bfin_compare_op0;
-   operands[3] = bfin_compare_op1;
-   operands[1] = bfin_cc_rtx;
+  operands[4] = bfin_cc_rtx;
 })
 
-(define_expand "sltu"
-  [(set (match_dup 1) (ltu:BI (match_dup 2) (match_dup 3)))
-   (set (match_operand:SI 0 "register_operand" "")
-       (ne:SI (match_dup 1) (const_int 0)))]
+(define_expand "cstoresi4"
+  [(set (match_operand:SI 0 "register_operand")
+        (match_operator:SI 1 "ordered_comparison_operator"
+                       [(match_operand:SI 2 "register_operand" "")
+                        (match_operand:SI 3 "reg_or_const_int_operand" "")]))]
   ""
 {
-   operands[2] = bfin_compare_op0;
-   operands[3] = bfin_compare_op1;
-   operands[1] = bfin_cc_rtx;
-})
+  rtx bi_compare, test;
 
-(define_expand "sleu"
-  [(set (match_dup 1) (leu:BI (match_dup 2) (match_dup 3)))
-   (set (match_operand:SI 0 "register_operand" "")
-       (ne:SI (match_dup 1) (const_int 0)))]
-  ""
-{
-   operands[2] = bfin_compare_op0;
-   operands[3] = bfin_compare_op1;
-   operands[1] = bfin_cc_rtx;
+  if (!bfin_direct_comparison_operator (operands[1], SImode))
+    {
+      if (!register_operand (operands[3], SImode)
+         || GET_CODE (operands[1]) == NE)
+       FAIL;
+      test = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
+                            SImode, operands[3], operands[2]);
+    }
+  else
+    test = operands[1];
+
+  bi_compare = bfin_gen_compare (test, SImode);
+  gcc_assert (GET_CODE (bi_compare) == NE);
+  emit_insn (gen_movbisi (operands[0], bfin_cc_rtx));
+  DONE;
 })
 
 (define_insn "nop"
   "CC = %1;"
   [(set_attr "length" "2")])
 
-(define_insn "movbisi"
+(define_insn_and_split "movbisi"
   [(set (match_operand:SI 0 "register_operand" "=d")
        (ne:SI (match_operand:BI 1 "register_operand" "C")
               (const_int 0)))]
   ""
-  "%0 = CC;"
-  [(set_attr "length" "2")])
+  "#"
+  ""
+  [(set (match_operand:SI 0 "register_operand" "")
+       (zero_extend:SI (match_operand:BI 1 "register_operand" "")))]
+  "")
 
 (define_insn "notbi"
   [(set (match_operand:BI 0 "register_operand" "=C")
index 7aac5b0..bce725a 100644 (file)
               && REGNO (op) <= LAST_VIRTUAL_REGISTER));
 })
 
-;; Test for an operator valid in a conditional branch
-(define_predicate "bfin_cbranch_operator"
+;; Test for an operator valid in a BImode conditional branch
+(define_predicate "bfin_bimode_comparison_operator"
   (match_code "eq,ne"))
 
+;; Test for an operator whose result is accessible with movbisi.
+(define_predicate "bfin_direct_comparison_operator"
+  (match_code "eq,lt,le,leu,ltu"))
+
 ;; The following two are used to compute the addrtype attribute.  They return
 ;; true if passed a memory address usable for a 16-bit load or store using a
 ;; P or I register, respectively.  If neither matches, we know we have a
index 2112670..bc634dd 100644 (file)
@@ -1431,13 +1431,18 @@ cris_normal_notice_update_cc (rtx exp, rtx insn)
       if (SET_DEST (exp) == cc0_rtx)
        {
          CC_STATUS_INIT;
-         cc_status.value1 = SET_SRC (exp);
 
-         /* Handle flags for the special btstq on one bit.  */
-         if (GET_CODE (SET_SRC (exp)) == ZERO_EXTRACT
-             && XEXP (SET_SRC (exp), 1) == const1_rtx)
+         if (GET_CODE (SET_SRC (exp)) == COMPARE
+             && XEXP (SET_SRC (exp), 1) == const0_rtx)
+           cc_status.value1 = XEXP (SET_SRC (exp), 0);
+         else
+           cc_status.value1 = SET_SRC (exp);
+
+          /* Handle flags for the special btstq on one bit.  */
+         if (GET_CODE (cc_status.value1) == ZERO_EXTRACT
+             && XEXP (cc_status.value1, 1) == const1_rtx)
            {
-             if (CONST_INT_P (XEXP (SET_SRC (exp), 0)))
+             if (CONST_INT_P (XEXP (cc_status.value1, 0)))
                /* Using cmpq.  */
                cc_status.flags = CC_INVERTED;
              else
@@ -1445,7 +1450,7 @@ cris_normal_notice_update_cc (rtx exp, rtx insn)
                cc_status.flags = CC_Z_IN_NOT_N;
            }
 
-         if (GET_CODE (SET_SRC (exp)) == COMPARE)
+         else if (GET_CODE (SET_SRC (exp)) == COMPARE)
            {
              if (!REG_P (XEXP (SET_SRC (exp), 0))
                  && XEXP (SET_SRC (exp), 1) != const0_rtx)
@@ -1855,6 +1860,11 @@ cris_rtx_costs (rtx x, int code, int outer_code, int *total,
        }
       return false;
 
+    case ZERO_EXTRACT:
+      if (outer_code != COMPARE)
+        return false;
+      /* fall through */
+
     case ZERO_EXTEND: case SIGN_EXTEND:
       *total = rtx_cost (XEXP (x, 0), outer_code, speed);
       return true;
index f4b2128..79eb8da 100644 (file)
 \f
 ;; Test insns.
 
-;; DImode
-;;
-;; Allow register and offsettable mem operands only; post-increment is
-;; not worth the trouble.
-
-(define_expand "tstdi"
-  [(set (cc0) (match_operand:DI 0 "nonimmediate_operand"))]
-  ""
-{
-  if (TARGET_V32 && MEM_P (operands[0]))
-    operands[0] = force_reg (DImode, operands[0]);
-})
-
-(define_insn "*tstdi_non_v32"
-  [(set (cc0)
-       (match_operand:DI 0 "nonimmediate_operand" "r,o"))]
-  "!TARGET_V32"
-  "test.d %M0\;ax\;test.d %H0")
-
-(define_insn "*tstdi_v32"
-  [(set (cc0)
-       (match_operand:DI 0 "register_operand" "r"))]
-  "TARGET_V32"
-  "cmpq 0,%M0\;ax\;cmpq 0,%H0")
-
 ;; No test insns with side-effect on the mem addressing.
 ;;
 ;; See note on cmp-insns with side-effects (or lack of them)
 
 ;; Normal named test patterns from SI on.
 
-(define_insn "tstsi"
+(define_insn "*tstsi"
   [(set (cc0)
-       (match_operand:SI 0 "nonimmediate_operand" "r,Q>,m"))]
+       (compare (match_operand:SI 0 "nonimmediate_operand" "r,Q>,m")
+                (const_int 0)))]
   ""
 {
   if (which_alternative == 0 && TARGET_V32)
 }
   [(set_attr "slottable" "yes,yes,no")])
 
-(define_expand "tst<mode>"
-  [(set (cc0)
-       (match_operand:BW 0 "nonimmediate_operand"))]
-  ""
-  "")
-
 (define_insn "*tst<mode>_cmp"
   [(set (cc0)
-       (match_operand:BW 0 "nonimmediate_operand" "r,Q>,m"))]
+       (compare (match_operand:BW 0 "nonimmediate_operand" "r,Q>,m")
+                (const_int 0)))]
   "cris_cc0_user_requires_cmp (insn)"
   "@
    cmp<m> 0,%0
 
 (define_insn "*tst<mode>_non_cmp"
   [(set (cc0)
-       (match_operand:BW 0 "nonimmediate_operand" "r,Q>,m"))]
+       (compare (match_operand:BW 0 "nonimmediate_operand" "r,Q>,m")
+                (const_int 0)))]
   "!cris_cc0_user_requires_cmp (insn)"
   "@
    move<m> %0,%0
 ;; DImode for anything else but a structure/block-mode.  Just do the
 ;; obvious stuff for the straight-forward constraint letters.
 
-(define_expand "cmpdi"
-  [(set (cc0)
-       (compare (match_operand:DI 0 "nonimmediate_operand" "")
-                (match_operand:DI 1 "general_operand" "")))]
-  ""
-{
-  if (TARGET_V32 && !REG_P (operands[0]))
-    operands[0] = force_reg (DImode, operands[0]);
-  if (TARGET_V32 && MEM_P (operands[1]))
-    operands[1] = force_reg (DImode, operands[1]);
-})
-
 (define_insn "*cmpdi_non_v32"
   [(set (cc0)
-       (compare (match_operand:DI 0 "nonimmediate_operand" "r,r,r,r,r,r,o")
-                (match_operand:DI 1 "general_operand" "Kc,I,P,n,r,o,r")))]
+       (compare (match_operand:DI 0 "nonimmediate_operand" "rm,r,r,r,r,r,r,o")
+                (match_operand:DI 1 "general_operand" "M,Kc,I,P,n,r,o,r")))]
   "!TARGET_V32"
   "@
+   test.d %M0\;ax\;test.d %H0
    cmpq %1,%M0\;ax\;cmpq 0,%H0
    cmpq %1,%M0\;ax\;cmpq -1,%H0
    cmp%e1.%z1 %1,%M0\;ax\;cmpq %H1,%H0
    (set_attr "cc" "rev")])
 \f
 ;; The "normal" compare patterns, from SI on.  Special-cases with zero
-;; should not happen.
+;; are covered above.
 
-(define_insn "cmpsi"
+(define_insn "*cmpsi"
   [(set (cc0)
        (compare
         (match_operand:SI 0 "nonimmediate_operand" "r,r,r, Q>,r,r,m")
   [(set_attr "slottable" "yes,yes,yes,yes,no,no,no")
    (set_attr "cc" "normal,normal,normal,rev,normal,normal,rev")])
 
-(define_insn "cmp<mode>"
+(define_insn "*cmp<mode>"
   [(set (cc0)
        (compare (match_operand:BW 0 "nonimmediate_operand" "r,r, Q>,r,m")
                 (match_operand:BW 1 "general_operand"      "r,Q>,r, g,r")))]
 ;; extends subregs for lower-size modes.  FIXME: Add testcase.
 (define_insn "*btst"
   [(set (cc0)
-       (zero_extract
-        (match_operand:SI 0 "nonmemory_operand" "r, r,r, r,r, r,Kp")
-        (match_operand:SI 1 "const_int_operand" "Kc,n,Kc,n,Kc,n,n")
-        (match_operand:SI 2 "nonmemory_operand" "M, M,Kc,n,r, r,r")))]
+       (compare
+        (zero_extract:SI
+         (match_operand:SI 0 "nonmemory_operand" "r, r,r, r,r, r,Kp")
+         (match_operand:SI 1 "const_int_operand" "Kc,n,Kc,n,Kc,n,n")
+         (match_operand:SI 2 "nonmemory_operand" "M, M,Kc,n,r, r,r"))
+        (const_int 0)))]
   ;; Either it is a single bit, or consecutive ones starting at 0.
   ;; The btst ones depend on stuff in NOTICE_UPDATE_CC.
   "CONST_INT_P (operands[1])
 \f
 ;; Conditional branches.
 
+(define_expand "cbranch<mode>4"
+  [(set (cc0) (compare
+              (match_operand:BWD 1 "nonimmediate_operand")
+              (match_operand:BWD 2 "general_operand")))
+   (set (pc)
+       (if_then_else (match_operator 0 "ordered_comparison_operator"
+                      [(cc0) (const_int 0)])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))]
+  ""
+  "")
+
+(define_expand "cbranchdi4"
+  [(set (cc0)
+       (compare (match_operand:DI 1 "nonimmediate_operand" "")
+                (match_operand:DI 2 "general_operand" "")))
+   (set (pc)
+       (if_then_else (match_operator 0 "ordered_comparison_operator"
+                      [(cc0) (const_int 0)])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))]
+  ""
+{
+  if (TARGET_V32 && !REG_P (operands[1]))
+    operands[1] = force_reg (DImode, operands[1]);
+  if (TARGET_V32 && MEM_P (operands[2]))
+    operands[2] = force_reg (DImode, operands[2]);
+})
+
+
 ;; We suffer from the same overflow-bit-gets-in-the-way problem as
 ;; e.g. m68k, so we have to check if overflow bit is set on all "signed"
 ;; conditions.
 \f
 ;; Set on condition: sCC.
 
+(define_expand "cstoredi4"
+  [(set (cc0) (compare
+              (match_operand:DI 2 "nonimmediate_operand")
+              (match_operand:DI 3 "general_operand")))
+   (set (match_operand:SI 0 "register_operand")
+       (match_operator:SI 1 "ordered_comparison_operator"
+        [(cc0) (const_int 0)]))]
+  ""
+{
+  if (TARGET_V32 && !REG_P (operands[2]))
+    operands[2] = force_reg (DImode, operands[2]);
+  if (TARGET_V32 && MEM_P (operands[3]))
+    operands[3] = force_reg (DImode, operands[3]);
+})
+
+(define_expand "cstore<mode>4"
+  [(set (cc0) (compare
+              (match_operand:BWD 2 "nonimmediate_operand")
+              (match_operand:BWD 3 "general_operand")))
+   (set (match_operand:SI 0 "register_operand")
+       (match_operator:SI 1 "ordered_comparison_operator"
+        [(cc0) (const_int 0)]))]
+  ""
+  "")
+
 ;; Like bCC, we have to check the overflow bit for
 ;; signed conditions.
 
index 0be641d..386fab9 100644 (file)
@@ -62,10 +62,6 @@ extern void crx_print_operand (FILE *, rtx, int);
 extern void crx_print_operand_address (FILE *, rtx);
 
 /* Misc functions called from crx.md.  */
-extern rtx crx_expand_compare (enum rtx_code, enum machine_mode);
-extern void crx_expand_branch (enum rtx_code, rtx);
-extern void crx_expand_scond (enum rtx_code, rtx);
-
 extern void crx_expand_movmem_single (rtx, rtx, rtx, rtx, rtx, unsigned HOST_WIDE_INT *);
 extern int crx_expand_movmem (rtx, rtx, rtx, rtx);
 #endif /* RTX_CODE */
index 6f10afd..cc3248f 100644 (file)
@@ -124,10 +124,6 @@ static enum machine_mode output_memory_reference_mode;
 /* Table of machine attributes.  */
 const struct attribute_spec crx_attribute_table[];
 
-/* Test and compare insns use these globals to generate branch insns.  */
-rtx crx_compare_op0 = NULL_RTX;
-rtx crx_compare_op1 = NULL_RTX;
-
 /*****************************************************************************/
 /* TARGETM FUNCTION PROTOTYPES                                              */
 /*****************************************************************************/
@@ -1217,43 +1213,6 @@ crx_expand_movmem (rtx dstbase, rtx srcbase, rtx count_exp, rtx align_exp)
   return 1;
 }
 
-rtx
-crx_expand_compare (enum rtx_code code, enum machine_mode mode)
-{
-  rtx op0, op1, cc_reg, ret;
-
-  op0 = crx_compare_op0;
-  op1 = crx_compare_op1;
-
-  /* Emit the compare that writes into CC_REGNUM) */
-  cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
-  ret = gen_rtx_COMPARE (CCmode, op0, op1);
-  emit_insn (gen_rtx_SET (VOIDmode, cc_reg, ret));
-  /* debug_rtx (get_last_insn ()); */
-
-  /* Return the rtx for using the result in CC_REGNUM */
-  return gen_rtx_fmt_ee (code, mode, cc_reg, const0_rtx);
-}
-
-void
-crx_expand_branch (enum rtx_code code, rtx label)
-{
-  rtx tmp = crx_expand_compare (code, VOIDmode);
-  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
-                             gen_rtx_LABEL_REF (VOIDmode, label),
-                             pc_rtx);
-  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
-  /* debug_rtx (get_last_insn ()); */
-}
-
-void
-crx_expand_scond (enum rtx_code code, rtx dest)
-{
-  rtx tmp = crx_expand_compare (code, GET_MODE (dest));
-  emit_move_insn (dest, tmp);
-  /* debug_rtx (get_last_insn ()); */
-}
-
 static void
 mpushpop_str (char *stringbuffer, const char *mnemonic, char *mask)
 {
index 69065f3..cac4657 100644 (file)
@@ -520,11 +520,4 @@ struct cumulative_args
 
 #define FUNCTION_MODE  QImode
 
-/*****************************************************************************/
-/* EXTERNAL DECLARATIONS FOR VARIABLES DEFINED IN CRX.C                             */
-/*****************************************************************************/
-
-extern rtx crx_compare_op0;    /* operand 0 for comparisons */
-extern rtx crx_compare_op1;    /* operand 1 for comparisons */
-
 #endif /* ! GCC_CRX_H */
index b965554..229e345 100644 (file)
   (ior (match_code "symbol_ref")
        (match_operand 0 "register_operand")))
 
+(define_predicate "cc_reg_operand"
+  (and (match_code "reg")
+       (match_test "REGNO (op) == CC_REGNUM")))
+
 (define_predicate "nosp_reg_operand"
   (and (match_operand 0 "register_operand")
        (match_test "REGNO (op) != SP_REGNUM")))
 (define_code_iterator mima_oprnd [smax umax smin umin])
 (define_code_attr mimaIsa [(smax "maxs") (umax "maxu") (smin "mins") (umin "minu")])
 
-(define_code_iterator any_cond [eq ne gt gtu lt ltu ge geu le leu])
-
 ;;  Addition Instructions
 
 (define_insn "adddi3"
 
 ;;  Compare and Branch Instructions
 
+(define_insn "cbranchcc4"
+  [(set (pc)
+       (if_then_else (match_operator 0 "ordered_comparison_operator"
+                      [(match_operand:CC 1 "cc_reg_operand" "r")
+                       (match_operand 2 "cst4_operand" "L")])
+                     (label_ref (match_operand 3 ""))
+                     (pc)))]
+  ""
+  "b%d0\t%l3"
+  [(set_attr "length" "6")]
+)
+
 (define_insn "cbranch<mode>4"
   [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
+       (if_then_else (match_operator 0 "ordered_comparison_operator"
                        [(match_operand:CRXIM 1 "register_operand" "r")
                         (match_operand:CRXIM 2 "reg_or_cst4_operand" "rL")])
                      (label_ref (match_operand 3 "" ""))
   [(set_attr "length" "6")]
 )
 
-;;  Compare Instructions
 
-(define_expand "cmp<mode>"
+;;  Scond Instructions
+
+(define_expand "cstore<mode>4"
   [(set (reg:CC CC_REGNUM)
-       (compare:CC (match_operand:CRXIM 0 "register_operand" "")
-                   (match_operand:CRXIM 1 "nonmemory_operand" "")))]
+       (compare:CC (match_operand:CRXIM 2 "register_operand" "")
+                   (match_operand:CRXIM 3 "nonmemory_operand" "")))
+   (set (match_operand:SI 0 "register_operand")
+       (match_operator:SI 1 "ordered_comparison_operator"
+       [(reg:CC CC_REGNUM) (const_int 0)]))]
+  ""
   ""
-  {
-    crx_compare_op0 = operands[0];
-    crx_compare_op1 = operands[1];
-    DONE;
-  }
 )
 
 (define_insn "cmp<mode>_internal"
   [(set_attr "length" "2,<lImmArith>")]
 )
 
-;;  Conditional Branch Instructions
-
-(define_expand "b<code>"
-  [(set (pc)
-       (if_then_else (any_cond (reg:CC CC_REGNUM)
-                               (const_int 0))
-                     (label_ref (match_operand 0 ""))
-                     (pc)))]
-  ""
-  {
-    crx_expand_branch (<CODE>, operands[0]);
-    DONE;
-  }
-)
-
-(define_insn "bCOND_internal"
-  [(set (pc)
-       (if_then_else (match_operator 0 "comparison_operator"
-                       [(reg:CC CC_REGNUM)
-                        (const_int 0)])
-                     (label_ref (match_operand 1 ""))
-                     (pc)))]
-  ""
-  "b%d0\t%l1"
-  [(set_attr "length" "6")]
-)
-
-;;  Scond Instructions
-
-(define_expand "s<code>"
-  [(set (match_operand:SI 0 "register_operand")
-       (any_cond:SI (reg:CC CC_REGNUM) (const_int 0)))]
-  ""
-  {
-    crx_expand_scond (<CODE>, operands[0]);
-    DONE;
-  }
-)
-
 (define_insn "sCOND_internal"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (match_operator:SI 1 "comparison_operator"
+       (match_operator:SI 1 "ordered_comparison_operator"
          [(reg:CC CC_REGNUM) (const_int 0)]))]
   ""
   "s%d1\t%0"
index e7f2e3c..5642c54 100644 (file)
 /*}}}*/
 /*{{{  Function Prologues & Epilogues */ 
 
-/* Define the information needed to generate branch and scc insns.  This is
-   stored from the compare operation.  */
-
-struct rtx_def * fr30_compare_op0;
-struct rtx_def * fr30_compare_op1;
-
 /* The FR30 stack looks like this:
 
              Before call                       After call
index c1e8e0a..b958a67 100644 (file)
@@ -1106,16 +1106,6 @@ fprintf (STREAM, "\t.word .L%d\n", VALUE)
 #endif
 
 /*}}}*/ \f
-/*{{{  Exported variables */ 
-
-/* Define the information needed to generate branch and scc insns.  This is
-   stored from the compare operation.  Note that we can't use "rtx" here
-   since it hasn't been defined!  */
-
-extern struct rtx_def * fr30_compare_op0;
-extern struct rtx_def * fr30_compare_op1;
-
-/*}}}*/ \f
 
 /* Local Variables: */
 /* folded-file: t   */
index a198ea3..fa115c4 100644 (file)
 ;;}}} \f
 ;;{{{ Comparisons 
 
-;; Note, we store the operands in the comparison insns, and use them later
-;; when generating the branch or scc operation.
-
-;; First the routines called by the machine independent part of the compiler
-(define_expand "cmpsi"
-  [(set (reg:CC 16)
-        (compare:CC (match_operand:SI 0 "register_operand"  "")
-                   (match_operand:SI 1 "nonmemory_operand" "")))]
-  ""
-  "{
-  fr30_compare_op0 = operands[0];
-  fr30_compare_op1 = operands[1];
-  DONE;
-  }"
-)
-
-;; Now, the actual comparisons, generated by the branch and/or scc operations
+;; The actual comparisons, generated by the cbranch and/or cstore expanders
 
 (define_insn "*cmpsi_internal"
   [(set (reg:CC 16)
 ;; Define_expands called by the machine independent part of the compiler
 ;; to allocate a new comparison register
 
-(define_expand "beq"
-  [(set (reg:CC 16)
-       (compare:CC (match_dup 1)
-                   (match_dup 2)))
-   (set (pc)
-       (if_then_else (eq:CC (reg:CC 16)
-                            (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{
-  operands[1] = fr30_compare_op0;
-  operands[2] = fr30_compare_op1;
-  }"
-)
-
-(define_expand "bne"
-  [(set (reg:CC 16)
-       (compare:CC (match_dup 1)
-                   (match_dup 2)))
-   (set (pc)
-       (if_then_else (ne:CC (reg:CC 16)
-                            (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{
-  operands[1] = fr30_compare_op0;
-  operands[2] = fr30_compare_op1;
-  }"
-)
-
-(define_expand "blt"
-  [(set (reg:CC 16)
-       (compare:CC (match_dup 1)
-                   (match_dup 2)))
-   (set (pc)
-       (if_then_else (lt:CC (reg:CC 16)
-                            (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{
-  operands[1] = fr30_compare_op0;
-  operands[2] = fr30_compare_op1;
-  }"
-)
-
-(define_expand "ble"
-  [(set (reg:CC 16)
-       (compare:CC (match_dup 1)
-                   (match_dup 2)))
-   (set (pc)
-       (if_then_else (le:CC (reg:CC 16)
-                            (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{
-  operands[1] = fr30_compare_op0;
-  operands[2] = fr30_compare_op1;
-  }"
-)
-
-(define_expand "bgt"
+(define_expand "cbranchsi4"
   [(set (reg:CC 16)
-       (compare:CC (match_dup 1)
-                   (match_dup 2)))
+       (compare:CC (match_operand:SI 1 "register_operand"  "")
+                   (match_operand:SI 2 "nonmemory_operand" "")))
    (set (pc)
-       (if_then_else (gt:CC (reg:CC 16)
-                            (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
+       (if_then_else (match_operator:CC 0 "ordered_comparison_operator"
+                      [(reg:CC 16) (const_int 0)])
+                     (label_ref (match_operand 3 "" ""))
                      (pc)))]
   ""
-  "{
-  operands[1] = fr30_compare_op0;
-  operands[2] = fr30_compare_op1;
-  }"
-)
-
-(define_expand "bge"
-  [(set (reg:CC 16)
-       (compare:CC (match_dup 1)
-                   (match_dup 2)))
-   (set (pc)
-       (if_then_else (ge:CC (reg:CC 16)
-                            (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{
-  operands[1] = fr30_compare_op0;
-  operands[2] = fr30_compare_op1;
-  }"
-)
-
-(define_expand "bltu"
-  [(set (reg:CC 16)
-       (compare:CC (match_dup 1)
-                   (match_dup 2)))
-   (set (pc)
-       (if_then_else (ltu:CC (reg:CC 16)
-                             (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{
-  operands[1] = fr30_compare_op0;
-  operands[2] = fr30_compare_op1;
-  }"
-)
-
-(define_expand "bleu"
-  [(set (reg:CC 16)
-       (compare:CC (match_dup 1)
-                   (match_dup 2)))
-   (set (pc)
-       (if_then_else (leu:CC (reg:CC 16)
-                             (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{
-  operands[1] = fr30_compare_op0;
-  operands[2] = fr30_compare_op1;
-  }"
-)
-
-(define_expand "bgtu"
-  [(set (reg:CC 16)
-       (compare:CC (match_dup 1)
-                   (match_dup 2)))
-   (set (pc)
-       (if_then_else (gtu:CC (reg:CC 16)
-                             (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
   ""
-  "{
-  operands[1] = fr30_compare_op0;
-  operands[2] = fr30_compare_op1;
-  }"
 )
 
-(define_expand "bgeu"
-  [(set (reg:CC 16)
-       (compare:CC (match_dup 1)
-                   (match_dup 2)))
-   (set (pc)
-       (if_then_else (geu:CC (reg:CC 16)
-                             (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "{
-  operands[1] = fr30_compare_op0;
-  operands[2] = fr30_compare_op1;
-  }"
-)
 
 ;; Actual branches.  We must allow for the (label_ref) and the (pc) to be
 ;; swapped.  If they are swapped, it reverses the sense of the branch.
index c34d02c..98ada22 100644 (file)
@@ -81,8 +81,8 @@ extern const char *output_move_single (rtx *, rtx);
 extern const char *output_move_double  (rtx *, rtx);
 extern const char *output_condmove_single
                                        (rtx *, rtx);
-extern int frv_emit_cond_branch                (enum rtx_code, rtx);
-extern int frv_emit_scc                        (enum rtx_code, rtx);
+extern int frv_emit_cond_branch                (rtx *);
+extern int frv_emit_scc                        (rtx *);
 extern rtx frv_split_scc               (rtx, rtx, rtx, rtx, HOST_WIDE_INT);
 extern int frv_emit_cond_move          (rtx, rtx, rtx, rtx);
 extern rtx frv_split_cond_move         (rtx *);
index 4e8c1b2..e547652 100644 (file)
@@ -193,11 +193,6 @@ typedef struct
   int base_offset;
 } frv_frame_accessor_t;
 
-/* Define the information needed to generate branch and scc insns.  This is
-   stored from the compare operation.  */
-rtx frv_compare_op0;
-rtx frv_compare_op1;
-
 /* Conditional execution support gathered together in one structure.  */
 typedef struct
   {
@@ -4768,19 +4763,18 @@ frv_emit_comparison (enum rtx_code test, rtx op0, rtx op1)
 }
 
 \f
-/* Emit code for a conditional branch.  The comparison operands were previously
-   stored in frv_compare_op0 and frv_compare_op1.
-
+/* Emit code for a conditional branch.
    XXX: I originally wanted to add a clobber of a CCR register to use in
    conditional execution, but that confuses the rest of the compiler.  */
 
 int
-frv_emit_cond_branch (enum rtx_code test, rtx label)
+frv_emit_cond_branch (rtx operands[])
 {
   rtx test_rtx;
   rtx label_ref;
   rtx if_else;
-  rtx cc_reg = frv_emit_comparison (test, frv_compare_op0, frv_compare_op1);
+  enum rtx_code test = GET_CODE (operands[0]);
+  rtx cc_reg = frv_emit_comparison (test, operands[1], operands[2]);
   enum machine_mode cc_mode = GET_MODE (cc_reg);
 
   /* Branches generate:
@@ -4788,7 +4782,7 @@ frv_emit_cond_branch (enum rtx_code test, rtx label)
             (if_then_else (<test>, <cc_reg>, (const_int 0))
                            (label_ref <branch_label>)
                            (pc))) */
-  label_ref = gen_rtx_LABEL_REF (VOIDmode, label);
+  label_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
   test_rtx = gen_rtx_fmt_ee (test, cc_mode, cc_reg, const0_rtx);
   if_else = gen_rtx_IF_THEN_ELSE (cc_mode, test_rtx, label_ref, pc_rtx);
   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, if_else));
@@ -4796,23 +4790,23 @@ frv_emit_cond_branch (enum rtx_code test, rtx label)
 }
 
 \f
-/* Emit code to set a gpr to 1/0 based on a comparison.  The comparison
-   operands were previously stored in frv_compare_op0 and frv_compare_op1.  */
+/* Emit code to set a gpr to 1/0 based on a comparison.  */
 
 int
-frv_emit_scc (enum rtx_code test, rtx target)
+frv_emit_scc (rtx operands[])
 {
   rtx set;
   rtx test_rtx;
   rtx clobber;
   rtx cr_reg;
-  rtx cc_reg = frv_emit_comparison (test, frv_compare_op0, frv_compare_op1);
+  enum rtx_code test = GET_CODE (operands[1]);
+  rtx cc_reg = frv_emit_comparison (test, operands[2], operands[3]);
 
   /* SCC instructions generate:
        (parallel [(set <target> (<test>, <cc_reg>, (const_int 0))
                   (clobber (<ccr_reg>))])  */
   test_rtx = gen_rtx_fmt_ee (test, SImode, cc_reg, const0_rtx);
-  set = gen_rtx_SET (VOIDmode, target, test_rtx);
+  set = gen_rtx_SET (VOIDmode, operands[0], test_rtx);
 
   cr_reg = ((TARGET_ALLOC_CC)
            ? gen_reg_rtx (CC_CCRmode)
@@ -4874,7 +4868,8 @@ frv_emit_cond_move (rtx dest, rtx test_rtx, rtx src1, rtx src2)
   rtx cr_reg;
   rtx if_rtx;
   enum rtx_code test = GET_CODE (test_rtx);
-  rtx cc_reg = frv_emit_comparison (test, frv_compare_op0, frv_compare_op1);
+  rtx cc_reg = frv_emit_comparison (test,
+                                   XEXP (test_rtx, 0), XEXP (test_rtx, 1));
   enum machine_mode cc_mode = GET_MODE (cc_reg);
 
   /* Conditional move instructions generate:
index b6fdca4..e510de0 100644 (file)
@@ -2913,9 +2913,6 @@ enum frv_builtins
 /* Enable prototypes on the call rtl functions.  */
 #define MD_CALL_PROTOTYPES 1
 
-extern GTY(()) rtx frv_compare_op0;                    /* operand save for */
-extern GTY(()) rtx frv_compare_op1;                    /* comparison generation */
-
 #define CPU_UNITS_QUERY 1
 
 #ifdef __FRV_FDPIC__
index aadf02c..9315f9b 100644 (file)
 ;; ::
 ;; ::::::::::::::::::::
 
-;; Note, we store the operands in the comparison insns, and use them later
-;; when generating the branch or scc operation.
-
-;; First the routines called by the machine independent part of the compiler
-(define_expand "cmpsi"
-  [(set (cc0)
-        (compare (match_operand:SI 0 "integer_register_operand" "")
-                (match_operand:SI 1 "gpr_or_int10_operand" "")))]
-  ""
-  "
-{
-  frv_compare_op0 = operands[0];
-  frv_compare_op1 = operands[1];
-  DONE;
-}")
-
-;(define_expand "cmpdi"
-;  [(set (cc0)
-;        (compare (match_operand:DI 0 "register_operand" "")
-;               (match_operand:DI 1 "nonmemory_operand" "")))]
-;  ""
-;  "
-;{
-;  frv_compare_op0 = operands[0];
-;  frv_compare_op1 = operands[1];
-;  DONE;
-;}")
-
-(define_expand "cmpsf"
- [(set (cc0)
-       (compare (match_operand:SF 0 "fpr_operand" "")
-                (match_operand:SF 1 "fpr_operand" "")))]
- "TARGET_HARD_FLOAT"
- "
-{
-  frv_compare_op0 = operands[0];
-  frv_compare_op1 = operands[1];
-  DONE;
-}")
-
-(define_expand "cmpdf"
-  [(set (cc0)
-        (compare (match_operand:DF 0 "fpr_operand" "")
-                (match_operand:DF 1 "fpr_operand" "")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
-  "
-{
-  frv_compare_op0 = operands[0];
-  frv_compare_op1 = operands[1];
-  DONE;
-}")
-
-;; Now, the actual comparisons, generated by the branch and/or scc operations
+;; The comparisons are generated by the branch and/or scc operations
 
 (define_insn "cmpsi_cc"
   [(set (match_operand:CC 0 "icc_operand" "=t,t")
 ;; ::::::::::::::::::::
 
 ;; Define_expands called by the machine independent part of the compiler
-;; to allocate a new comparison register.  Each of these named patterns
-;; must be present, and they cannot be amalgamated into one pattern.
-;;
-;; If a fixed condition code register is being used, (as opposed to, say,
-;; using cc0), then the expands should look like this:
-;;
-;; (define_expand "<name_of_test>"
-;;   [(set (reg:CC <number_of_CC_register>)
-;;     (compare:CC (match_dup 1)
-;;                 (match_dup 2)))
-;;    (set (pc)
-;;     (if_then_else (eq:CC (reg:CC <number_of_CC_register>)
-;;                          (const_int 0))
-;;                   (label_ref (match_operand 0 "" ""))
-;;                   (pc)))]
-;;   ""
-;;   "{
-;;     operands[1] = frv_compare_op0;
-;;     operands[2] = frv_compare_op1;
-;;   }"
-;; )
-
-(define_expand "beq"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "
-{
-  if (! frv_emit_cond_branch (EQ, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "bne"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "
-{
-  if (! frv_emit_cond_branch (NE, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "blt"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "
-{
-  if (! frv_emit_cond_branch (LT, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "ble"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "
-{
-  if (! frv_emit_cond_branch (LE, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "bgt"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "
-{
-  if (! frv_emit_cond_branch (GT, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "bge"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "
-{
-  if (! frv_emit_cond_branch (GE, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "bltu"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "
-{
-  if (! frv_emit_cond_branch (LTU, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "bleu"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "
-{
-  if (! frv_emit_cond_branch (LEU, operands[0]))
-    FAIL;
-
-  DONE;
-}")
+;; to allocate a new comparison register.
 
-(define_expand "bgtu"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "
-{
-  if (! frv_emit_cond_branch (GTU, operands[0]))
-    FAIL;
+(define_expand "cbranchdf4"
+  [(use (match_operator 0 "ordered_comparison_operator"
+         [(match_operand:DF 1 "fpr_operand" "")
+          (match_operand:DF 2 "fpr_operand" "")]))
+   (use (match_operand 3 ""))]
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
+  { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); })
 
-  DONE;
-}")
+(define_expand "cbranchsf4"
+  [(use (match_operator 0 "ordered_comparison_operator"
+         [(match_operand:SF 1 "fpr_operand" "")
+          (match_operand:SF 2 "fpr_operand" "")]))
+   (use (match_operand 3 ""))]
+  "TARGET_HARD_FLOAT"
+  { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); })
 
-(define_expand "bgeu"
-  [(use (match_operand 0 "" ""))]
+(define_expand "cbranchsi4"
+  [(use (match_operator 0 "ordered_comparison_operator"
+         [(match_operand:SI 1 "integer_register_operand" "")
+          (match_operand:SI 2 "gpr_or_int10_operand" "")]))
+   (use (match_operand 3 ""))]
   ""
-  "
-{
-  if (! frv_emit_cond_branch (GEU, operands[0]))
-    FAIL;
-
-  DONE;
-}")
+  { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); })
 
 ;; Actual branches.  We must allow for the (label_ref) and the (pc) to be
 ;; swapped.  If they are swapped, it reverses the sense of the branch.
 ;; Define_expands called by the machine independent part of the compiler
 ;; to allocate a new comparison register
 
-(define_expand "seq"
-  [(match_operand:SI 0 "integer_register_operand" "")]
-  "TARGET_SCC"
-  "
-{
-  if (! frv_emit_scc (EQ, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "sne"
-  [(match_operand:SI 0 "integer_register_operand" "")]
-  "TARGET_SCC"
-  "
-{
-  if (! frv_emit_scc (NE, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "slt"
-  [(match_operand:SI 0 "integer_register_operand" "")]
-  "TARGET_SCC"
-  "
-{
-  if (! frv_emit_scc (LT, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "sle"
-  [(match_operand:SI 0 "integer_register_operand" "")]
-  "TARGET_SCC"
-  "
-{
-  if (! frv_emit_scc (LE, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "sgt"
-  [(match_operand:SI 0 "integer_register_operand" "")]
-  "TARGET_SCC"
-  "
-{
-  if (! frv_emit_scc (GT, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "sge"
-  [(match_operand:SI 0 "integer_register_operand" "")]
-  "TARGET_SCC"
-  "
-{
-  if (! frv_emit_scc (GE, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "sltu"
-  [(match_operand:SI 0 "integer_register_operand" "")]
-  "TARGET_SCC"
-  "
-{
-  if (! frv_emit_scc (LTU, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "sleu"
-  [(match_operand:SI 0 "integer_register_operand" "")]
-  "TARGET_SCC"
-  "
-{
-  if (! frv_emit_scc (LEU, operands[0]))
-    FAIL;
-
-  DONE;
-}")
-
-(define_expand "sgtu"
-  [(match_operand:SI 0 "integer_register_operand" "")]
-  "TARGET_SCC"
-  "
-{
-  if (! frv_emit_scc (GTU, operands[0]))
-    FAIL;
-
-  DONE;
-}")
+(define_expand "cstoredf4"
+  [(use (match_operator:SI 1 "ordered_comparison_operator"
+         [(match_operand:DF 2 "fpr_operand")
+          (match_operand:DF 3 "fpr_operand")]))
+   (clobber (match_operand:SI 0 "register_operand"))]
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE"
+  { if (frv_emit_scc (operands)) DONE; else FAIL; })
 
-(define_expand "sgeu"
-  [(match_operand:SI 0 "integer_register_operand" "")]
-  "TARGET_SCC"
-  "
-{
-  if (! frv_emit_scc (GEU, operands[0]))
-    FAIL;
+(define_expand "cstoresf4"
+  [(use (match_operator:SI 1 "ordered_comparison_operator"
+         [(match_operand:SF 2 "fpr_operand")
+          (match_operand:SF 3 "fpr_operand")]))
+   (clobber (match_operand:SI 0 "register_operand"))]
+  "TARGET_HARD_FLOAT"
+  { if (frv_emit_scc (operands)) DONE; else FAIL; })
 
-  DONE;
-}")
+(define_expand "cstoresi4"
+  [(use (match_operator:SI 1 "ordered_comparison_operator"
+         [(match_operand:SI 2 "integer_register_operand")
+          (match_operand:SI 3 "gpr_or_int10_operand")]))
+   (clobber (match_operand:SI 0 "register_operand"))]
+  ""
+  { if (frv_emit_scc (operands)) DONE; else FAIL; })
 
 (define_insn "*scc_int"
   [(set (match_operand:SI 0 "integer_register_operand" "=d")
index 2e7b72f..4a0b647 100644 (file)
@@ -44,7 +44,8 @@ extern const char *output_logical_op (enum machine_mode, rtx *);
 extern unsigned int compute_logical_op_length (enum machine_mode,
                                               rtx *);
 extern int compute_logical_op_cc (enum machine_mode, rtx *);
-extern void h8300_expand_branch (enum rtx_code, rtx);
+extern void h8300_expand_branch (rtx[]);
+extern void h8300_expand_store (rtx[]);
 extern bool expand_a_shift (enum machine_mode, int, rtx[]);
 extern int h8300_shift_needs_scratch_p (int, enum machine_mode);
 extern int expand_a_rotate (rtx[]);
index 34d1f82..9946d28 100644 (file)
@@ -1226,6 +1226,11 @@ h8300_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
       *total = 20;
       return true;
 
+    case COMPARE:
+      if (XEXP (x, 1) == const0_rtx)
+       *total = 0;
+      return false;
+
     case AND:
       if (!h8300_dst_operand (XEXP (x, 0), VOIDmode)
          || !h8300_src_operand (XEXP (x, 1), VOIDmode))
@@ -3503,16 +3508,42 @@ compute_logical_op_cc (enum machine_mode mode, rtx *operands)
 /* Expand a conditional branch.  */
 
 void
-h8300_expand_branch (enum rtx_code code, rtx label)
+h8300_expand_branch (rtx operands[])
 {
+  enum rtx_code code = GET_CODE (operands[0]);
+  rtx op0 = operands[1];
+  rtx op1 = operands[2];
+  rtx label = operands[3];
   rtx tmp;
 
+  tmp = gen_rtx_COMPARE (VOIDmode, op0, op1);
+  emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, tmp));
+
   tmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
                              gen_rtx_LABEL_REF (VOIDmode, label),
                              pc_rtx);
   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
 }
+
+
+/* Expand a conditional store.  */
+
+void
+h8300_expand_store (rtx operands[])
+{
+  rtx dest = operands[0];
+  enum rtx_code code = GET_CODE (operands[1]);
+  rtx op0 = operands[2];
+  rtx op1 = operands[3];
+  rtx tmp;
+
+  tmp = gen_rtx_COMPARE (VOIDmode, op0, op1);
+  emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, tmp));
+
+  tmp = gen_rtx_fmt_ee (code, GET_MODE (dest), cc0_rtx, const0_rtx);
+  emit_insn (gen_rtx_SET (VOIDmode, dest, tmp));
+}
 \f
 /* Shifts.
 
index 61f876c..c05e8c6 100644 (file)
 ;; ----------------------------------------------------------------------
 
 (define_insn ""
-  [(set (cc0) (zero_extract:HI (match_operand:QI 0 "bit_memory_operand" "r,U")
-                              (const_int 1)
-                              (match_operand 1 "const_int_operand" "n,n")))]
+  [(set (cc0) (compare
+              (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "r,U")
+                               (const_int 1)
+                               (match_operand 1 "const_int_operand" "n,n"))
+              (const_int 0)))]
   "TARGET_H8300"
   "btst        %Z1,%Y0"
   [(set_attr "length" "2,4")
    (set_attr "cc" "set_zn,set_zn")])
 
 (define_insn ""
-  [(set (cc0) (zero_extract:HI (match_operand:HI 0 "register_operand" "r")
-                              (const_int 1)
-                              (match_operand 1 "const_int_operand" "n")))]
+  [(set (cc0) (compare
+              (zero_extract:HI (match_operand:HI 0 "register_operand" "r")
+                               (const_int 1)
+                               (match_operand 1 "const_int_operand" "n"))
+              (const_int 0)))]
   "TARGET_H8300"
   "btst        %Z1,%Y0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_zn")])
 
 (define_insn_and_split "*tst_extzv_1_n"
-  [(set (cc0)
-       (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
-                        (const_int 1)
-                        (match_operand 1 "const_int_operand" "n,n,n")))
+  [(set (cc0) (compare
+              (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
+                               (const_int 1)
+                               (match_operand 1 "const_int_operand" "n,n,n"))
+              (const_int 0)))
    (clobber (match_scratch:QI 2 "=X,X,&r"))]
   "(TARGET_H8300H || TARGET_H8300S)"
   "@
    && !OK_FOR_U (operands[0])"
   [(set (match_dup 2)
        (match_dup 0))
-   (parallel [(set (cc0) (zero_extract:SI (match_dup 2)
-                                         (const_int 1)
-                                         (match_dup 1)))
+   (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
+                                                  (const_int 1)
+                                                  (match_dup 1))
+                                 (const_int 0)))
              (clobber (scratch:QI))])]
   ""
   [(set_attr "length" "2,8,10")
    (set_attr "cc" "set_zn,set_zn,set_zn")])
 
 (define_insn ""
-  [(set (cc0) (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
-                              (const_int 1)
-                              (match_operand 1 "const_int_operand" "n")))]
+  [(set (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+                                       (const_int 1)
+                                       (match_operand 1 "const_int_operand" "n"))
+                      (const_int 0)))]
   "(TARGET_H8300H || TARGET_H8300S)
    && INTVAL (operands[1]) <= 15"
   "btst        %Z1,%Y0"
    (set_attr "cc" "set_zn")])
 
 (define_insn_and_split "*tstsi_upper_bit"
-  [(set (cc0)
-       (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
-                        (const_int 1)
-                        (match_operand 1 "const_int_operand" "n")))
+  [(set (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+                                       (const_int 1)
+                                       (match_operand 1 "const_int_operand" "n"))
+                      (const_int 0)))
    (clobber (match_scratch:SI 2 "=&r"))]
   "(TARGET_H8300H || TARGET_H8300S)
    && INTVAL (operands[1]) >= 16"
                        (const_int -65536))
                (lshiftrt:SI (match_dup 0)
                             (const_int 16))))
-   (set (cc0)
-       (zero_extract:SI (match_dup 2)
-                        (const_int 1)
-                        (match_dup 3)))]
+   (set (cc0) (compare (zero_extract:SI (match_dup 2)
+                                       (const_int 1)
+                                       (match_dup 3))
+                      (const_int 0)))]
   "operands[3] = GEN_INT (INTVAL (operands[1]) - 16);")
 
 (define_insn "*tstsi_variable_bit"
-  [(set (cc0)
-       (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
-                        (const_int 1)
-                        (and:SI (match_operand:SI 1 "register_operand" "r")
-                                (const_int 7))))]
+  [(set (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+                                       (const_int 1)
+                                       (and:SI (match_operand:SI 1 "register_operand" "r")
+                                               (const_int 7)))
+                      (const_int 0)))]
   "TARGET_H8300H || TARGET_H8300S"
   "btst        %w1,%w0"
   [(set_attr "length" "2")
 
 (define_insn_and_split "*tstsi_variable_bit_qi"
   [(set (cc0)
-       (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
-                        (const_int 1)
-                        (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
-                                (const_int 7))))
+       (compare
+        (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
+                         (const_int 1)
+                         (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
+                                 (const_int 7)))
+         (const_int 0)))
    (clobber (match_scratch:QI 2 "=X,X,&r"))]
   "(TARGET_H8300H || TARGET_H8300S)"
   "@
    && !OK_FOR_U (operands[0])"
   [(set (match_dup 2)
        (match_dup 0))
-   (parallel [(set (cc0) (zero_extract:SI (zero_extend:SI (match_dup 2))
-                                         (const_int 1)
-                                         (and:SI (match_dup 1)
-                                                 (const_int 7))))
+   (parallel [(set (cc0) (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
+                                                  (const_int 1)
+                                                  (and:SI (match_dup 1)
+                                                          (const_int 7)))
+                                 (const_int 0)))
              (clobber (scratch:QI))])]
   ""
   [(set_attr "length" "2,8,10")
    (set_attr "cc" "set_zn,set_zn,set_zn")])
 
-(define_insn "tstqi"
-  [(set (cc0) (match_operand:QI 0 "register_operand" "r"))]
+(define_insn "*tstqi"
+  [(set (cc0) (compare (match_operand:QI 0 "register_operand" "r")
+                      (const_int 0)))]
   ""
   "mov.b       %X0,%X0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
-(define_insn "tsthi"
-  [(set (cc0) (match_operand:HI 0 "register_operand" "r"))]
+(define_insn "*tsthi"
+  [(set (cc0) (compare (match_operand:HI 0 "register_operand" "r")
+                      (const_int 0)))]
   ""
   "mov.w       %T0,%T0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
 (define_insn "*tsthi_upper"
-  [(set (cc0)
-       (and:HI (match_operand:HI 0 "register_operand" "r")
-               (const_int -256)))]
+  [(set (cc0) (compare (and:HI (match_operand:HI 0 "register_operand" "r")
+                              (const_int -256))
+                      (const_int 0)))]
   ""
   "mov.b       %t0,%t0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
-(define_insn "tstsi"
-  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
+(define_insn "*tstsi"
+  [(set (cc0) (compare (match_operand:SI 0 "register_operand" "r")
+                      (const_int 0)))]
   "TARGET_H8300H || TARGET_H8300S"
   "mov.l       %S0,%S0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
 (define_insn "*tstsi_upper"
-  [(set (cc0)
-       (and:SI (match_operand:SI 0 "register_operand" "r")
-               (const_int -65536)))]
+  [(set (cc0) (compare (and:SI (match_operand:SI 0 "register_operand" "r")
+                              (const_int -65536))
+                      (const_int 0)))]
   ""
   "mov.w       %e0,%e0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
-(define_insn "cmpqi"
+(define_insn "*cmpqi"
   [(set (cc0)
        (compare (match_operand:QI 0 "h8300_dst_operand" "rQ")
                 (match_operand:QI 1 "h8300_src_operand" "rQi")))]
   [(set_attr "length_table" "addb")
    (set_attr "cc" "compare")])
 
-(define_expand "cmphi"
-  [(set (cc0)
-       (compare (match_operand:HI 0 "h8300_dst_operand" "")
-                (match_operand:HI 1 "h8300_src_operand" "")))]
-  ""
-  "
-{
-  /* Force operand1 into a register if we're compiling
-     for the H8/300.  */
-  if (GET_CODE (operands[1]) != REG && TARGET_H8300)
-    operands[1] = force_reg (HImode, operands[1]);
-}")
-
 (define_insn "*cmphi_h8300_znvc"
   [(set (cc0)
        (compare (match_operand:HI 0 "register_operand" "r")
 
 ;; Conditional jump instructions
 
-(define_expand "ble"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (LE, operands[0]); DONE;")
-
-(define_expand "bleu"
-  [(match_operand 0 "" "")]
+(define_expand "cbranchqi4"
+  [(use (match_operator 0 "ordered_comparison_operator"
+         [(match_operand:QI 1 "h8300_dst_operand" "")
+          (match_operand:QI 2 "h8300_src_operand" "")]))
+   (use (match_operand 3 ""))]
   ""
-  "h8300_expand_branch (LEU, operands[0]); DONE;")
+  "h8300_expand_branch (operands); DONE;")
 
-(define_expand "bge"
-  [(match_operand 0 "" "")]
+(define_expand "cbranchhi4"
+  [(use (match_operator 0 "ordered_comparison_operator"
+         [(match_operand:HI 1 "h8300_dst_operand" "")
+          (match_operand:HI 2 "h8300_src_operand" "")]))
+   (use (match_operand 3 ""))]
   ""
-  "h8300_expand_branch (GE, operands[0]); DONE;")
-
-(define_expand "bgeu"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (GEU, operands[0]); DONE;")
-
-(define_expand "blt"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (LT, operands[0]); DONE;")
-
-(define_expand "bltu"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (LTU, operands[0]); DONE;")
-
-(define_expand "bgt"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (GT, operands[0]); DONE;")
-
-(define_expand "bgtu"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (GTU, operands[0]); DONE;")
-
-(define_expand "beq"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (EQ, operands[0]); DONE;")
+  "
+{
+  /* Force operand1 into a register if we're compiling
+     for the H8/300.  */
+  if ((GET_CODE (operands[2]) != REG && operands[2] != const0_rtx)
+      && TARGET_H8300)
+    operands[2] = force_reg (HImode, operands[2]);
+  h8300_expand_branch (operands); DONE;
+}")
 
-(define_expand "bne"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (NE, operands[0]); DONE;")
+(define_expand "cbranchsi4"
+  [(use (match_operator 0 "ordered_comparison_operator"
+         [(match_operand:SI 1 "h8300_dst_operand" "")
+          (match_operand:SI 2 "h8300_src_operand" "")]))
+   (use (match_operand 3 ""))]
+  "TARGET_H8300H || TARGET_H8300S"
+  "h8300_expand_branch (operands); DONE;")
 
 (define_insn "branch_true"
   [(set (pc)
    (clobber (match_operand:QI 3 "register_operand" ""))]
   "epilogue_completed
    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
-  [(set (cc0)
-       (match_dup 1))
+  [(set (cc0) (compare (match_dup 1)
+                      (const_int 0)))
    (set (pc)
         (if_then_else (le (cc0) (const_int 0))
                      (label_ref (match_dup 5))
       (clobber (scratch:QI))])
    (set (match_dup 1)
        (plus:QI (match_dup 1) (const_int -1)))
-   (set (cc0)
-       (match_dup 1))
+   (set (cc0) (compare (match_dup 1)
+                      (const_int 0)))
    (set (pc)
         (if_then_else (ne (cc0) (const_int 0))
                      (label_ref (match_dup 4))
    && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
   [(set (match_dup 3)
        (match_dup 1))
-   (set (cc0)
-       (match_dup 3))
+   (set (cc0) (compare (match_dup 3)
+                      (const_int 0)))
    (set (pc)
         (if_then_else (le (cc0) (const_int 0))
                      (label_ref (match_dup 5))
       (clobber (scratch:QI))])
    (set (match_dup 3)
        (plus:QI (match_dup 3) (const_int -1)))
-   (set (cc0)
-       (match_dup 3))
+   (set (cc0) (compare (match_dup 3)
+                      (const_int 0)))
    (set (pc)
         (if_then_else (ne (cc0) (const_int 0))
                      (label_ref (match_dup 4))
   [(set_attr "cc" "none_0hit")
    (set_attr "length_table" "bitfield")])
 
-(define_expand "seq"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (eq:HI (cc0) (const_int 0)))]
+(define_expand "cstoreqi4"
+  [(use (match_operator 1 "eqne_operator"
+         [(match_operand:QI 2 "h8300_dst_operand" "")
+          (match_operand:QI 3 "h8300_src_operand" "")]))
+   (clobber (match_operand:HI 0 "register_operand"))]
   "TARGET_H8300SX"
-  "")
+  "h8300_expand_store (operands); DONE;")
 
-(define_expand "sne"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (ne:HI (cc0) (const_int 0)))]
+(define_expand "cstorehi4"
+  [(use (match_operator 1 "eqne_operator"
+         [(match_operand:HI 2 "h8300_dst_operand" "")
+          (match_operand:HI 3 "h8300_src_operand" "")]))
+   (clobber (match_operand:HI 0 "register_operand"))]
   "TARGET_H8300SX"
-  "")
+  "h8300_expand_store (operands); DONE;")
+
+(define_expand "cstoresi4"
+  [(use (match_operator 1 "eqne_operator"
+         [(match_operand:SI 2 "h8300_dst_operand" "")
+          (match_operand:SI 3 "h8300_src_operand" "")]))
+   (clobber (match_operand:HI 0 "register_operand"))]
+  "TARGET_H8300SX"
+  "h8300_expand_store (operands); DONE;")
 
 (define_insn "*bstzhireg"
   [(set (match_operand:HI 0 "register_operand" "=r")
   [(set (cc0) (match_dup 5))
    (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
        (match_op_dup:QI 2 [(cc0) (const_int 0)]))]
-  "
-{
-  if (operands[4] == const0_rtx && GET_CODE (operands[3]) == REG)
-    operands[5] = operands[3];
-  else
-    operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
-}"
+  "operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);"
   [(set_attr "cc" "set_znv,compare")])
    
 (define_insn "*bstz"
        (if_then_else:QI
         (match_op_dup 1 [(cc0) (const_int 0)])
         (ior:QI (match_dup 4) (match_dup 5)) (match_dup 4)))]
-  "
-{
-  if (operands[3] == const0_rtx && GET_CODE (operands[2]) == REG)
-    operands[6] = operands[2];
-  else
-    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-}"
+  "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
   [(set_attr "cc" "set_znv,compare")])
    
 (define_insn "*condbset"
        (if_then_else:QI
         (match_op_dup 1 [(cc0) (const_int 0)])
         (and:QI (match_dup 4) (match_dup 5)) (match_dup 4)))]
-  "
-{
-  if (operands[3] == const0_rtx && GET_CODE (operands[2]) == REG)
-    operands[6] = operands[2];
-  else
-    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-}"
+  "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
   [(set_attr "cc" "set_znv,compare")])
    
 (define_insn "*condbclr"
                 (ashift:QI (const_int 1)
                            (match_operand:QI 5 "register_operand" "r,r")))
         (match_dup 4)))]
-  "
-{
-  if (operands[3] == const0_rtx && GET_CODE (operands[2]) == REG)
-    operands[6] = operands[2];
-  else
-    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-}"
+  "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
   [(set_attr "cc" "set_znv,compare")])
    
 (define_insn "*condbsetreg"
                 (ashift:QI (const_int 1)
                            (match_operand:QI 5 "register_operand" "r,r")))
         (match_dup 4)))]
-  "
-{
-  if (operands[3] == const0_rtx && GET_CODE (operands[2]) == REG)
-    operands[6] = operands[2];
-  else
-    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-}"
+  "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
   [(set_attr "cc" "set_znv,compare")])
    
 (define_insn "*condbclrreg"
   "(TARGET_H8300H || TARGET_H8300S)"
   "#"
   "&& reload_completed"
-  [(set (cc0)
-       (zero_extract:SI (match_dup 1)
-                        (const_int 1)
-                        (const_int 0)))
+  [(set (cc0) (compare (zero_extract:SI (match_dup 1)
+                                       (const_int 1)
+                                       (const_int 0))
+                      (const_int 0)))
    (set (pc)
         (if_then_else (eq (cc0)
                          (const_int 0))
   "(TARGET_H8300H || TARGET_H8300S)"
   "#"
   "&& reload_completed"
-  [(set (cc0)
-       (zero_extract:SI (match_dup 1)
-                        (const_int 1)
-                        (const_int 0)))
+  [(set (cc0) (compare (zero_extract:SI (match_dup 1)
+                                       (const_int 1)
+                                       (const_int 0))
+                      (const_int 0)))
    (set (pc)
         (if_then_else (ne (cc0)
                          (const_int 0))
   ""
   "#"
   ""
-  [(set (cc0)
-       (match_dup 0))
+  [(set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (ge (cc0)
                          (const_int 0))
   ""
   "#"
   ""
-  [(set (cc0)
-       (match_dup 0))
+  [(set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (lt (cc0)
                          (const_int 0))
   [(set (match_operand:HI 0 "register_operand" "")
        (plus:HI (match_dup 0)
                 (match_operand 1 "incdec_operand" "")))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_operator 3 "eqne_operator"
                        [(cc0) (const_int 0)])
        (unspec:HI [(match_dup 0)
                    (match_dup 1)]
                   UNSPEC_INCDEC))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
   [(set (match_operand:SI 0 "register_operand" "")
        (plus:SI (match_dup 0)
                 (match_operand 1 "incdec_operand" "")))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_operator 3 "eqne_operator"
                        [(cc0) (const_int 0)])
        (unspec:SI [(match_dup 0)
                    (match_dup 1)]
                   UNSPEC_INCDEC))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
 
 (define_peephole2
   [(parallel [(set (cc0)
-                  (zero_extract:SI (match_operand:QI 0 "register_operand" "")
-                                   (const_int 1)
-                                   (const_int 7)))
+                  (compare (zero_extract:SI (match_operand:QI 0 "register_operand" "")
+                                            (const_int 1)
+                                            (const_int 7))
+                           (const_int 0)))
              (clobber (scratch:QI))])
    (set (pc)
        (if_then_else (match_operator 1 "eqne_operator"
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "(TARGET_H8300H || TARGET_H8300S)"
-  [(set (cc0)
-        (match_dup 0))
+  [(set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
   "operands[3] = gen_lowpart (HImode, operands[0]);
    operands[4] = gen_lowpart (HImode, operands[1]);")
 
+;; Convert a memory comparison to a move if there is a scratch register.
+
+(define_peephole2
+  [(match_scratch:QI 1 "r")
+   (set (cc0)
+       (compare (match_operand:QI 0 "memory_operand" "")
+                (const_int 0)))]
+  ""
+  [(set (match_dup 1)
+       (match_dup 0))
+   (set (cc0) (compare (match_dup 1)
+                      (const_int 0)))]
+  "")
+
+(define_peephole2
+  [(match_scratch:HI 1 "r")
+   (set (cc0)
+       (compare (match_operand:HI 0 "memory_operand" "")
+                (const_int 0)))]
+  "(TARGET_H8300H || TARGET_H8300S)"
+  [(set (match_dup 1)
+       (match_dup 0))
+   (set (cc0) (compare (match_dup 1)
+                      (const_int 0)))]
+  "")
+
+(define_peephole2
+  [(match_scratch:SI 1 "r")
+   (set (cc0)
+       (compare (match_operand:SI 0 "memory_operand" "")
+                (const_int 0)))]
+  "(TARGET_H8300H || TARGET_H8300S)"
+  [(set (match_dup 1)
+       (match_dup 0))
+   (set (cc0) (compare (match_dup 1)
+                      (const_int 0)))]
+  "")
+
+
 ;; (compare (reg:HI) (const_int)) takes 4 bytes, so we try to achieve
 ;; the equivalent with shorter sequences.  Here is the summary.  Cases
 ;; are grouped for each define_peephole2.
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "(TARGET_H8300H || TARGET_H8300S)
+   && INTVAL (operands[1]) != 0
    && peep2_reg_dead_p (1, operands[0])"
   [(set (match_dup 0)
        (unspec:HI [(match_dup 0)
                    (match_dup 4)]
                   UNSPEC_INCDEC))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
                   (ashiftrt:HI (match_dup 0)
                                (match_dup 4)))
              (clobber (scratch:QI))])
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 2)
                      (label_ref (match_dup 3))
                   (ashiftrt:HI (match_dup 0)
                                (match_dup 4)))
              (clobber (scratch:QI))])
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 5)
                      (label_ref (match_dup 3))
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "TARGET_H8300H || TARGET_H8300S"
-  [(set (cc0)
-       (and:HI (match_dup 0)
-               (const_int -256)))
+  [(set (cc0) (compare (and:HI (match_dup 0)
+                              (const_int -256))
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 1)
                      (label_ref (match_dup 2))
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "TARGET_H8300H || TARGET_H8300S"
-  [(set (cc0)
-       (and:HI (match_dup 0)
-               (const_int -256)))
+  [(set (cc0) (compare (and:HI (match_dup 0)
+                              (const_int -256))
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 3)
                      (label_ref (match_dup 2))
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "(TARGET_H8300H || TARGET_H8300S)
+   && INTVAL (operands[1]) != 0
    && peep2_reg_dead_p (1, operands[0])"
   [(set (match_dup 0)
        (unspec:SI [(match_dup 0)
                    (match_dup 4)]
                   UNSPEC_INCDEC))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
   [(set (match_dup 0)
        (plus:SI (match_dup 0)
                 (match_dup 4)))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
    && ((INTVAL (operands[1]) & 0x00ff) == INTVAL (operands[1])
        || (INTVAL (operands[1]) & 0xff00) == INTVAL (operands[1])
        || INTVAL (operands[1]) == 0x0000ffff)
+   && INTVAL (operands[1]) != 0
    && INTVAL (operands[1]) != 1
    && INTVAL (operands[1]) != 2"
   [(set (match_dup 0)
        (xor:SI (match_dup 0)
                (match_dup 1)))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
                (match_dup 4)))
    (set (match_dup 0)
        (not:SI (match_dup 0)))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
        (unspec:SI [(match_dup 0)
                    (const_int -1)]
                   UNSPEC_INCDEC))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
                   (ashiftrt:SI (match_dup 4)
                                (match_dup 5)))
              (clobber (scratch:QI))])
-   (set (cc0)
-       (match_dup 4))
+   (set (cc0) (compare (match_dup 4)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 2)
                      (label_ref (match_dup 3))
                   (ashiftrt:SI (match_dup 4)
                                (match_dup 5)))
              (clobber (scratch:QI))])
-   (set (cc0)
-       (match_dup 4))
+   (set (cc0) (compare (match_dup 4)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 6)
                      (label_ref (match_dup 3))
                   (ashiftrt:SI (match_dup 0)
                                (match_dup 4)))
              (clobber (scratch:QI))])
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 2)
                      (label_ref (match_dup 3))
                   (ashiftrt:SI (match_dup 0)
                                (match_dup 4)))
              (clobber (scratch:QI))])
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 5)
                      (label_ref (match_dup 3))
   [(set (match_dup 0)
        (and:SI (match_dup 0)
                (match_dup 4)))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 2)
                      (label_ref (match_dup 3))
   [(set (match_dup 0)
        (and:SI (match_dup 0)
                (match_dup 4)))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 5)
                      (label_ref (match_dup 3))
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "TARGET_H8300H || TARGET_H8300S"
-  [(set (cc0)
-       (and:SI (match_dup 0)
-               (const_int -65536)))
+  [(set (cc0) (compare (and:SI (match_dup 0)
+                              (const_int -65536))
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 1)
                      (label_ref (match_dup 2))
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "TARGET_H8300H || TARGET_H8300S"
-  [(set (cc0)
-       (and:SI (match_dup 0)
-               (const_int -65536)))
+  [(set (cc0) (compare (and:SI (match_dup 0)
+                              (const_int -65536))
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 3)
                      (label_ref (match_dup 2))
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "(TARGET_H8300H || TARGET_H8300S)
+   && INTVAL (operands[1]) != 0
    && !peep2_reg_dead_p (1, operands[0])
    && !same_cmp_following_p (insn)"
   [(set (match_dup 4)
        (unspec:SI [(match_dup 4)
                    (match_dup 5)]
                   UNSPEC_INCDEC))
-   (set (cc0)
-       (match_dup 4))
+   (set (cc0) (compare (match_dup 4)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
   [(set (match_operand:HI 0 "register_operand" "")
        (and:HI (match_dup 0)
                (match_operand:HI 1 "const_int_qi_operand" "")))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_operator 3 "eqne_operator"
                        [(cc0) (const_int 0)])
   [(set (match_dup 4)
        (and:QI (match_dup 4)
                (match_dup 5)))
-   (set (cc0)
-       (match_dup 4))
+   (set (cc0) (compare (match_dup 4)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
   [(set (match_operand:SI 0 "register_operand" "")
        (and:SI (match_dup 0)
                (match_operand:SI 1 "const_int_qi_operand" "")))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_operator 3 "eqne_operator"
                        [(cc0) (const_int 0)])
   [(set (match_dup 4)
        (and:QI (match_dup 4)
                (match_dup 5)))
-   (set (cc0)
-       (match_dup 4))
+   (set (cc0) (compare (match_dup 4)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
   [(set (match_operand:SI 0 "register_operand" "")
        (and:SI (match_dup 0)
                (match_operand:SI 1 "const_int_hi_operand" "")))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_operator 3 "eqne_operator"
                        [(cc0) (const_int 0)])
   [(set (match_dup 4)
        (and:HI (match_dup 4)
                (match_dup 5)))
-   (set (cc0)
-       (match_dup 4))
+   (set (cc0) (compare (match_dup 4)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
    (set (match_dup 0)
        (xor:SI (match_dup 0)
                (match_operand:SI 2 "const_int_qi_operand" "")))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_operator 4 "eqne_operator"
                        [(cc0) (const_int 0)])
    (set (match_dup 5)
        (xor:QI (match_dup 5)
                (match_dup 7)))
-   (set (cc0)
-       (match_dup 5))
+   (set (cc0) (compare (match_dup 5)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 4 [(cc0) (const_int 0)])
                      (label_ref (match_dup 3))
                 (match_operand 2 "h8300_src_operand" "")))]
   "TARGET_H8300SX
    && peep2_reg_dead_p (2, operands[0])
-   && !reg_overlap_mentioned_p (operands[0], operands[2])"
+   && !reg_overlap_mentioned_p (operands[0], operands[2])
+   && operands[2] != const0_rtx"
   [(set (cc0)
        (compare (match_dup 1)
                 (match_dup 2)))])
index 803a9da..9452d2a 100644 (file)
@@ -106,7 +106,7 @@ extern int ix86_match_ccmode (rtx, enum machine_mode);
 extern rtx ix86_expand_compare (enum rtx_code, rtx *, rtx *);
 extern int ix86_use_fcomi_compare (enum rtx_code);
 extern void ix86_expand_branch (enum rtx_code, rtx);
-extern int ix86_expand_setcc (enum rtx_code, rtx);
+extern void ix86_expand_setcc (enum rtx_code, rtx);
 extern int ix86_expand_int_movcc (rtx[]);
 extern int ix86_expand_fp_movcc (rtx[]);
 extern bool ix86_expand_fp_vcond (rtx[]);
index aefb891..bb013a1 100644 (file)
@@ -14947,15 +14947,12 @@ ix86_split_fp_branch (enum rtx_code code, rtx op1, rtx op2,
     emit_label (label);
 }
 
-int
+void
 ix86_expand_setcc (enum rtx_code code, rtx dest)
 {
   rtx ret, tmp, tmpreg, equiv;
   rtx second_test, bypass_test;
 
-  if (GET_MODE (ix86_compare_op0) == (TARGET_64BIT ? TImode : DImode))
-    return 0; /* FAIL */
-
   gcc_assert (GET_MODE (dest) == QImode);
 
   ret = ix86_expand_compare (code, &second_test, &bypass_test);
@@ -14994,8 +14991,6 @@ ix86_expand_setcc (enum rtx_code code, rtx dest)
                                       ix86_compare_op0, ix86_compare_op1);
       set_unique_reg_note (get_last_insn (), REG_EQUAL, equiv);
     }
-
-  return 1; /* DONE */
 }
 
 /* Expand comparison setting or clearing carry flag.  Return true when
@@ -15143,6 +15138,8 @@ ix86_expand_int_movcc (rtx operands[])
   bool sign_bit_compare_p = false;;
 
   start_sequence ();
+  ix86_compare_op0 = XEXP (operands[1], 0);
+  ix86_compare_op1 = XEXP (operands[1], 1);
   compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
   compare_seq = get_insns ();
   end_sequence ();
@@ -15860,6 +15857,8 @@ ix86_expand_fp_movcc (rtx operands[])
   enum rtx_code code = GET_CODE (operands[1]);
   rtx tmp, compare_op, second_test, bypass_test;
 
+  ix86_compare_op0 = XEXP (operands[1], 0);
+  ix86_compare_op1 = XEXP (operands[1], 1);
   if (TARGET_SSE_MATH && SSE_FLOAT_MODE_P (mode))
     {
       enum machine_mode cmode;
@@ -16387,6 +16386,8 @@ ix86_expand_int_addcc (rtx operands[])
   bool fpcmp = false;
   enum machine_mode mode = GET_MODE (operands[0]);
 
+  ix86_compare_op0 = XEXP (operands[1], 0);
+  ix86_compare_op1 = XEXP (operands[1], 1);
   if (operands[3] != const1_rtx
       && operands[3] != constm1_rtx)
     return 0;
@@ -28870,13 +28871,14 @@ void ix86_emit_i387_log1p (rtx op0, rtx op1)
 
   rtx tmp = gen_reg_rtx (XFmode);
   rtx tmp2 = gen_reg_rtx (XFmode);
+  rtx test;
 
   emit_insn (gen_absxf2 (tmp, op1));
-  emit_insn (gen_cmpxf (tmp,
+  test = gen_rtx_GE (VOIDmode, tmp,
     CONST_DOUBLE_FROM_REAL_VALUE (
        REAL_VALUE_ATOF ("0.29289321881345247561810596348408353", XFmode),
-       XFmode)));
-  emit_jump_insn (gen_bge (label1));
+       XFmode));
+  emit_jump_insn (gen_cbranchxf4 (test, XEXP (test, 0), XEXP (test, 1), label1));
 
   emit_move_insn (tmp2, standard_80387_constant_rtx (4)); /* fldln2 */
   emit_insn (gen_fyl2xp1xf3_i387 (op0, op1, tmp2));
index 1bb96fd..198b59d 100644 (file)
 (include "constraints.md")
 
 \f
-;; Compare instructions.
+;; Compare and branch/compare and store instructions.
 
-;; All compare insns have expanders that save the operands away without
-;; actually generating RTL.  The bCOND or sCOND (emitted immediately
-;; after the cmp) will actually emit the cmpM.
+(define_expand "cbranchti4"
+  [(set (reg:CC FLAGS_REG)
+       (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
+                   (match_operand:TI 2 "x86_64_general_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+  "TARGET_64BIT"
+{
+  if (MEM_P (operands[1]) && MEM_P (operands[2]))
+    operands[1] = force_reg (TImode, operands[1]);
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+  DONE;
+})
 
-(define_expand "cmpti"
+(define_expand "cbranchdi4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
-                   (match_operand:TI 1 "x86_64_general_operand" "")))]
+       (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
+                   (match_operand:DI 2 "x86_64_general_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+  ""
+{
+  if (MEM_P (operands[1]) && MEM_P (operands[2]))
+    operands[1] = force_reg (DImode, operands[1]);
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+  DONE;
+})
+
+(define_expand "cstoredi4"
+  [(set (reg:CC FLAGS_REG)
+       (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
+                   (match_operand:DI 3 "x86_64_general_operand" "")))
+   (set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)]))]
   "TARGET_64BIT"
 {
-  if (MEM_P (operands[0]) && MEM_P (operands[1]))
-    operands[0] = force_reg (TImode, operands[0]);
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  if (MEM_P (operands[2]) && MEM_P (operands[3]))
+    operands[2] = force_reg (DImode, operands[2]);
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
   DONE;
 })
 
-(define_expand "cmpdi"
+(define_expand "cbranchsi4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
-                   (match_operand:DI 1 "x86_64_general_operand" "")))]
+       (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
+                   (match_operand:SI 2 "general_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
   ""
 {
-  if (MEM_P (operands[0]) && MEM_P (operands[1]))
-    operands[0] = force_reg (DImode, operands[0]);
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  if (MEM_P (operands[1]) && MEM_P (operands[2]))
+    operands[1] = force_reg (SImode, operands[1]);
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
   DONE;
 })
 
-(define_expand "cmpsi"
+(define_expand "cstoresi4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
-                   (match_operand:SI 1 "general_operand" "")))]
+       (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
+                   (match_operand:SI 3 "general_operand" "")))
+   (set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)]))]
   ""
 {
-  if (MEM_P (operands[0]) && MEM_P (operands[1]))
-    operands[0] = force_reg (SImode, operands[0]);
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  if (MEM_P (operands[2]) && MEM_P (operands[3]))
+    operands[2] = force_reg (SImode, operands[2]);
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
   DONE;
 })
 
-(define_expand "cmphi"
+(define_expand "cbranchhi4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
-                   (match_operand:HI 1 "general_operand" "")))]
+       (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
+                   (match_operand:HI 2 "general_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
   ""
 {
-  if (MEM_P (operands[0]) && MEM_P (operands[1]))
-    operands[0] = force_reg (HImode, operands[0]);
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  if (MEM_P (operands[1]) && MEM_P (operands[2]))
+    operands[1] = force_reg (HImode, operands[1]);
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
   DONE;
 })
 
-(define_expand "cmpqi"
+(define_expand "cstorehi4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
-                   (match_operand:QI 1 "general_operand" "")))]
-  "TARGET_QIMODE_MATH"
+       (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
+                   (match_operand:HI 3 "general_operand" "")))
+   (set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)]))]
+  ""
 {
-  if (MEM_P (operands[0]) && MEM_P (operands[1]))
-    operands[0] = force_reg (QImode, operands[0]);
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  if (MEM_P (operands[2]) && MEM_P (operands[3]))
+    operands[2] = force_reg (HImode, operands[2]);
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+  DONE;
+})
+
+
+(define_expand "cbranchqi4"
+  [(set (reg:CC FLAGS_REG)
+       (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
+                   (match_operand:QI 2 "general_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+  ""
+{
+  if (MEM_P (operands[1]) && MEM_P (operands[2]))
+    operands[1] = force_reg (QImode, operands[1]);
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+  DONE;
+})
+
+
+(define_expand "cstoreqi4"
+  [(set (reg:CC FLAGS_REG)
+       (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
+                   (match_operand:QI 3 "general_operand" "")))
+   (set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)]))]
+  ""
+{
+  if (MEM_P (operands[2]) && MEM_P (operands[3]))
+    operands[2] = force_reg (QImode, operands[2]);
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
   DONE;
 })
 
+
 (define_insn "cmpdi_ccno_1_rex64"
   [(set (reg FLAGS_REG)
        (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
 ;; which would allow mix and match FP modes on the compares.  Which is what
 ;; the old patterns did, but with many more of them.
 
-(define_expand "cmpxf"
+(define_expand "cbranchxf4"
+  [(set (reg:CC FLAGS_REG)
+       (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
+                   (match_operand:XF 2 "nonmemory_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+  "TARGET_80387"
+{
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+  DONE;
+})
+
+(define_expand "cstorexf4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
-                   (match_operand:XF 1 "nonmemory_operand" "")))]
+       (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
+                   (match_operand:XF 3 "nonmemory_operand" "")))
+   (set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)]))]
   "TARGET_80387"
 {
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
   DONE;
 })
 
-(define_expand "cmp<mode>"
+(define_expand "cbranch<mode>4"
   [(set (reg:CC FLAGS_REG)
-       (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
-                   (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
+       (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
+                   (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
+   (set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
 {
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
   DONE;
 })
 
-(define_expand "cmpcc"
+(define_expand "cstore<mode>4"
   [(set (reg:CC FLAGS_REG)
-        (compare:CC (match_operand 0 "flags_reg_operand" "")
-                    (match_operand 1 "general_operand" "")))]
+       (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
+                   (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
+   (set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "comparison_operator"
+               [(reg:CC FLAGS_REG)
+                (const_int 0)]))]
+  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
+{
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+  DONE;
+})
+
+(define_expand "cbranchcc4"
+  [(set (pc) (if_then_else
+              (match_operator 0 "comparison_operator"
+               [(match_operand 1 "flags_reg_operand" "")
+                (match_operand 2 "const0_operand" "")])
+              (label_ref (match_operand 3 "" ""))
+              (pc)))]
+  ""
+{
+  ix86_compare_op0 = operands[1];
+  ix86_compare_op1 = operands[2];
+  ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+  DONE;
+})
+
+(define_expand "cstorecc4"
+  [(set (match_operand:QI 0 "register_operand" "")
+              (match_operator 1 "comparison_operator"
+               [(match_operand 2 "flags_reg_operand" "")
+                (match_operand 3 "const0_operand" "")]))]
   ""
 {
-  ix86_compare_op0 = operands[0];
-  ix86_compare_op1 = operands[1];
+  ix86_compare_op0 = operands[2];
+  ix86_compare_op1 = operands[3];
+  ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
   DONE;
 })
 
+
 ;; FP compares, step 1:
 ;; Set the FP condition codes.
 ;;
 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
 ;; way, which can later delete the movzx if only QImode is needed.
 
-(define_expand "s<code>"
-  [(set (match_operand:QI 0 "register_operand" "")
-        (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
-  ""
-  "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
-
-(define_expand "s<code>"
-  [(set (match_operand:QI 0 "register_operand" "")
-        (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
-  "TARGET_80387 || TARGET_SSE"
-  "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
-
 (define_insn "*setcc_1"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
        (match_operator:QI 1 "ix86_comparison_operator"
 ;; Basic conditional jump instructions.
 ;; We ignore the overflow flag for signed branch instructions.
 
-;; For all bCOND expanders, also expand the compare or test insn that
-;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
-
-(define_expand "b<code>"
-  [(set (pc)
-       (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
-                                  (const_int 0))
-                     (label_ref (match_operand 0 ""))
-                     (pc)))]
-  ""
-  "ix86_expand_branch (<CODE>, operands[0]); DONE;")
-
-(define_expand "b<code>"
-  [(set (pc)
-       (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
-                                 (const_int 0))
-                     (label_ref (match_operand 0 ""))
-                     (pc)))]
-  "TARGET_80387 || TARGET_SSE_MATH"
-  "ix86_expand_branch (<CODE>, operands[0]); DONE;")
-
 (define_insn "*jcc_1"
   [(set (pc)
        (if_then_else (match_operator 1 "ix86_comparison_operator"
     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
 #endif
 
-  ix86_compare_op0 = flags;
-  ix86_compare_op1 = const0_rtx;
-  emit_jump_insn (gen_beq (operands[2]));
+  emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
+                                 flags, const0_rtx, operands[2]));
   DONE;
 })
 
index e3b7864..0859c7f 100644 (file)
@@ -18,13 +18,6 @@ You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-/* Variables defined in ia64.c.  */
-
-#ifdef RTX_CODE
-extern GTY(()) rtx ia64_compare_op0;
-extern GTY(()) rtx ia64_compare_op1;
-#endif
-
 /* Functions defined in ia64.c */
 
 extern int bundling_p;
@@ -43,7 +36,7 @@ extern void ia64_emit_cond_move (rtx, rtx, rtx);
 extern int ia64_depz_field_mask (rtx, rtx);
 extern void ia64_split_tmode_move (rtx[]);
 extern bool ia64_expand_movxf_movrf (enum machine_mode, rtx[]);
-extern rtx ia64_expand_compare (enum rtx_code, enum machine_mode);
+extern void ia64_expand_compare (rtx *, rtx *, rtx *);
 extern void ia64_expand_vecint_cmov (rtx[]);
 extern bool ia64_expand_vecint_minmax (enum rtx_code, enum machine_mode, rtx[]);
 extern void ia64_expand_widen_sum (rtx[], bool);
index acf73c5..1f433a6 100644 (file)
@@ -63,11 +63,6 @@ along with GCC; see the file COPYING3.  If not see
    ASM_OUTPUT_LABELREF.  */
 int ia64_asm_output_label = 0;
 
-/* Define the information needed to generate branch and scc insns.  This is
-   stored from the compare operation.  */
-struct rtx_def * ia64_compare_op0;
-struct rtx_def * ia64_compare_op1;
-
 /* Register names for ia64_expand_prologue.  */
 static const char * const ia64_reg_numbers[96] =
 { "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
@@ -1493,28 +1488,28 @@ ia64_expand_movxf_movrf (enum machine_mode mode, rtx operands[])
   return false;
 }
 
-/* Emit comparison instruction if necessary, returning the expression
-   that holds the compare result in the proper mode.  */
+/* Emit comparison instruction if necessary, replacing *EXPR, *OP0, *OP1
+   with the expression that holds the compare result (in VOIDmode).  */
 
 static GTY(()) rtx cmptf_libfunc;
 
-rtx
-ia64_expand_compare (enum rtx_code code, enum machine_mode mode)
+void
+ia64_expand_compare (rtx *expr, rtx *op0, rtx *op1)
 {
-  rtx op0 = ia64_compare_op0, op1 = ia64_compare_op1;
+  enum rtx_code code = GET_CODE (*expr);
   rtx cmp;
 
   /* If we have a BImode input, then we already have a compare result, and
      do not need to emit another comparison.  */
-  if (GET_MODE (op0) == BImode)
+  if (GET_MODE (*op0) == BImode)
     {
-      gcc_assert ((code == NE || code == EQ) && op1 == const0_rtx);
-      cmp = op0;
+      gcc_assert ((code == NE || code == EQ) && *op1 == const0_rtx);
+      cmp = *op0;
     }
   /* HPUX TFmode compare requires a library call to _U_Qfcmp, which takes a
      magic number as its third argument, that indicates what to do.
      The return value is an integer to be compared against zero.  */
-  else if (TARGET_HPUX && GET_MODE (op0) == TFmode)
+  else if (TARGET_HPUX && GET_MODE (*op0) == TFmode)
     {
       enum qfcmp_magic {
        QCMP_INV = 1,   /* Raise FP_INVALID on SNaN as a side effect.  */
@@ -1527,7 +1522,7 @@ ia64_expand_compare (enum rtx_code code, enum machine_mode mode)
       enum rtx_code ncode;
       rtx ret, insns;
       
-      gcc_assert (cmptf_libfunc && GET_MODE (op1) == TFmode);
+      gcc_assert (cmptf_libfunc && GET_MODE (*op1) == TFmode);
       switch (code)
        {
          /* 1 = equal, 0 = not equal.  Equality operators do
@@ -1552,7 +1547,7 @@ ia64_expand_compare (enum rtx_code code, enum machine_mode mode)
       start_sequence ();
 
       ret = emit_library_call_value (cmptf_libfunc, 0, LCT_CONST, DImode, 3,
-                                    op0, TFmode, op1, TFmode,
+                                    *op0, TFmode, *op1, TFmode,
                                     GEN_INT (magic), DImode);
       cmp = gen_reg_rtx (BImode);
       emit_insn (gen_rtx_SET (VOIDmode, cmp,
@@ -1563,18 +1558,20 @@ ia64_expand_compare (enum rtx_code code, enum machine_mode mode)
       end_sequence ();
 
       emit_libcall_block (insns, cmp, cmp,
-                         gen_rtx_fmt_ee (code, BImode, op0, op1));
+                         gen_rtx_fmt_ee (code, BImode, *op0, *op1));
       code = NE;
     }
   else
     {
       cmp = gen_reg_rtx (BImode);
       emit_insn (gen_rtx_SET (VOIDmode, cmp,
-                             gen_rtx_fmt_ee (code, BImode, op0, op1)));
+                             gen_rtx_fmt_ee (code, BImode, *op0, *op1)));
       code = NE;
     }
 
-  return gen_rtx_fmt_ee (code, mode, cmp, const0_rtx);
+  *expr = gen_rtx_fmt_ee (code, VOIDmode, cmp, const0_rtx);
+  *op0 = cmp;
+  *op1 = const0_rtx;
 }
 
 /* Generate an integral vector comparison.  Return true if the condition has
index 26e71f8..e5a6d81 100644 (file)
    (set_attr "speculable2"   "no,  no,  no,  no,   yes,no,no,  no,  no,   yes,no, no,  no,  no,    no,    no,    no,    no,  no")])
 
 (define_mode_iterator MODE [BI QI HI SI DI SF DF XF TI])
+(define_mode_iterator MODE_FOR_CMP [BI SI DI SF DF XF (TF "TARGET_HPUX")])
 (define_mode_iterator MODE_FOR_EXTEND [QI HI SI])
 
 (define_mode_attr output_a [
 ;; ::
 ;; ::::::::::::::::::::
 
-(define_expand "cmpbi"
-  [(set (cc0)
-        (compare (match_operand:BI 0 "register_operand" "")
-                (match_operand:BI 1 "const_int_operand" "")))]
+(define_expand "cbranchbi4"
+  [(set (pc)
+       (if_then_else (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:BI 1 "register_operand" "")
+                       (match_operand:BI 2 "const_int_operand" "")])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))]
   ""
-{
-  ia64_compare_op0 = operands[0];
-  ia64_compare_op1 = operands[1];
-  DONE;
-})
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
 
-(define_expand "cmpsi"
-  [(set (cc0)
-        (compare (match_operand:SI 0 "gr_register_operand" "")
-                (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
+(define_expand "cbranchsi4"
+  [(set (pc)
+       (if_then_else (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:SI 1 "gr_register_operand" "")
+                       (match_operand:SI 2 "gr_reg_or_8bit_and_adjusted_operand" "")])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))]
   ""
-{
-  ia64_compare_op0 = operands[0];
-  ia64_compare_op1 = operands[1];
-  DONE;
-})
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
 
-(define_expand "cmpdi"
-  [(set (cc0)
-        (compare (match_operand:DI 0 "gr_register_operand" "")
-                (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
+(define_expand "cbranchdi4"
+  [(set (pc)
+       (if_then_else (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:DI 1 "gr_register_operand" "")
+                       (match_operand:DI 2 "gr_reg_or_8bit_and_adjusted_operand" "")])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))]
   ""
-{
-  ia64_compare_op0 = operands[0];
-  ia64_compare_op1 = operands[1];
-  DONE;
-})
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
 
-(define_expand "cmpsf"
-  [(set (cc0)
-        (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
-                (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
+(define_expand "cbranchsf4"
+  [(set (pc)
+       (if_then_else (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:SF 1 "fr_reg_or_fp01_operand" "")
+                       (match_operand:SF 2 "fr_reg_or_fp01_operand" "")])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))]
   ""
-{
-  ia64_compare_op0 = operands[0];
-  ia64_compare_op1 = operands[1];
-  DONE;
-})
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
 
-(define_expand "cmpdf"
-  [(set (cc0)
-        (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
-                (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
+(define_expand "cbranchdf4"
+  [(set (pc)
+       (if_then_else (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:DF 1 "fr_reg_or_fp01_operand" "")
+                       (match_operand:DF 2 "fr_reg_or_fp01_operand" "")])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))]
   ""
-{
-  ia64_compare_op0 = operands[0];
-  ia64_compare_op1 = operands[1];
-  DONE;
-})
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
 
-(define_expand "cmpxf"
-  [(set (cc0)
-        (compare (match_operand:XF 0 "xfreg_or_fp01_operand" "")
-                (match_operand:XF 1 "xfreg_or_fp01_operand" "")))]
+(define_expand "cbranchxf4"
+  [(set (pc)
+       (if_then_else (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:XF 1 "xfreg_or_fp01_operand" "")
+                       (match_operand:XF 2 "xfreg_or_fp01_operand" "")])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))]
   ""
-{
-  ia64_compare_op0 = operands[0];
-  ia64_compare_op1 = operands[1];
-  DONE;
-})
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
 
-(define_expand "cmptf"
-  [(set (cc0)
-        (compare (match_operand:TF 0 "gr_register_operand" "")
-                (match_operand:TF 1 "gr_register_operand" "")))]
+(define_expand "cbranchtf4"
+  [(set (pc)
+       (if_then_else (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:TF 1 "gr_register_operand" "")
+                       (match_operand:TF 2 "gr_register_operand" "")])
+                     (label_ref (match_operand 3 "" ""))
+                     (pc)))]
   "TARGET_HPUX"
-{
-  ia64_compare_op0 = operands[0];
-  ia64_compare_op1 = operands[1];
-  DONE;
-})
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
 
 (define_insn "*cmpsi_normal"
   [(set (match_operand:BI 0 "register_operand" "=c")
 ;; ::
 ;; ::::::::::::::::::::
 
-(define_expand "beq"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "operands[1] = ia64_expand_compare (EQ, VOIDmode);")
-
-(define_expand "bne"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "operands[1] = ia64_expand_compare (NE, VOIDmode);")
-
-(define_expand "blt"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "operands[1] = ia64_expand_compare (LT, VOIDmode);")
-
-(define_expand "ble"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "operands[1] = ia64_expand_compare (LE, VOIDmode);")
-
-(define_expand "bgt"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "operands[1] = ia64_expand_compare (GT, VOIDmode);")
-
-(define_expand "bge"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "operands[1] = ia64_expand_compare (GE, VOIDmode);")
-
-(define_expand "bltu"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "operands[1] = ia64_expand_compare (LTU, VOIDmode);")
-
-(define_expand "bleu"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "operands[1] = ia64_expand_compare (LEU, VOIDmode);")
-
-(define_expand "bgtu"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "operands[1] = ia64_expand_compare (GTU, VOIDmode);")
-
-(define_expand "bgeu"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "operands[1] = ia64_expand_compare (GEU, VOIDmode);")
-
-(define_expand "bunordered"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);")
-
-(define_expand "bordered"
-  [(set (pc)
-       (if_then_else (match_dup 1)
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);")
-
 (define_insn "*br_true"
   [(set (pc)
        (if_then_else (match_operator 0 "predicate_operator"
 ;; ::
 ;; ::::::::::::::::::::
 
-(define_expand "seq"
-  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
+(define_expand "cstorebi4"
+  [(set (match_operand:DI 0 "gr_register_operand" "") 
+       (match_operator:DI 1 "ia64_cbranch_operator"
+                      [(match_operand:BI 2 "register_operand" "")
+                       (match_operand:BI 3 "const_int_operand" "")]))]
   ""
-  "operands[1] = ia64_expand_compare (EQ, DImode);")
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
 
-(define_expand "sne"
-  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
+(define_expand "cstoresi4"
+  [(set (match_operand:DI 0 "gr_register_operand" "") 
+       (match_operator:DI 1 "ia64_cbranch_operator"
+                      [(match_operand:SI 2 "gr_register_operand" "")
+                       (match_operand:SI 3 "gr_reg_or_8bit_and_adjusted_operand" "")]))]
   ""
-  "operands[1] = ia64_expand_compare (NE, DImode);")
+  "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
 
-(define_expand "slt"
-  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
+(define_expand "cstoredi4"
+  [(set (match_operand:DI 0 "gr_register_operand" "") 
+       (match_operator:DI 1 "ia64_cbranch_operator"
+                      [(match_operand:DI 2 "gr_register_operand" "")
+                       (match_operand:DI 3 "gr_reg_or_8bit_and_adjusted_operand" "")]))]
   ""
-  "operands[1] = ia64_expand_compare (LT, DImode);")
+  "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
 
-(define_expand "sle"
-  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
+(define_expand "cstoresf4"
+  [(set (match_operand:DI 0 "gr_register_operand" "") 
+       (match_operator:DI 1 "ia64_cbranch_operator"
+                      [(match_operand:SF 2 "fr_reg_or_fp01_operand" "")
+                       (match_operand:SF 3 "fr_reg_or_fp01_operand" "")]))]
   ""
-  "operands[1] = ia64_expand_compare (LE, DImode);")
+  "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
 
-(define_expand "sgt"
-  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
+(define_expand "cstoredf4"
+  [(set (match_operand:DI 0 "gr_register_operand" "") 
+       (match_operator:DI 1 "ia64_cbranch_operator"
+                      [(match_operand:DF 2 "fr_reg_or_fp01_operand" "")
+                       (match_operand:DF 3 "fr_reg_or_fp01_operand" "")]))]
   ""
-  "operands[1] = ia64_expand_compare (GT, DImode);")
+  "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
 
-(define_expand "sge"
-  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
+(define_expand "cstorexf4"
+  [(set (match_operand:DI 0 "gr_register_operand" "") 
+       (match_operator:DI 1 "ia64_cbranch_operator"
+                      [(match_operand:XF 2 "xfreg_or_fp01_operand" "")
+                       (match_operand:XF 3 "xfreg_or_fp01_operand" "")]))]
   ""
-  "operands[1] = ia64_expand_compare (GE, DImode);")
+  "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
 
-(define_expand "sltu"
-  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
-  ""
-  "operands[1] = ia64_expand_compare (LTU, DImode);")
-
-(define_expand "sleu"
-  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
-  ""
-  "operands[1] = ia64_expand_compare (LEU, DImode);")
-
-(define_expand "sgtu"
-  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
-  ""
-  "operands[1] = ia64_expand_compare (GTU, DImode);")
-
-(define_expand "sgeu"
-  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
-  ""
-  "operands[1] = ia64_expand_compare (GEU, DImode);")
-
-(define_expand "sunordered"
-  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
-  ""
-  "operands[1] = ia64_expand_compare (UNORDERED, DImode);")
-
-(define_expand "sordered"
-  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
-  ""
-  "operands[1] = ia64_expand_compare (ORDERED, DImode);")
+(define_expand "cstoretf4"
+  [(set (match_operand:DI 0 "gr_register_operand" "") 
+       (match_operator:DI 1 "ia64_cbranch_operator"
+                      [(match_operand:TF 2 "gr_register_operand" "")
+                       (match_operand:TF 3 "gr_register_operand" "")]))]
+  "TARGET_HPUX"
+  "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
 
 ;; Don't allow memory as destination here, because cmov/cmov/st is more
 ;; efficient than mov/mov/cst/cst.
   "break %0"
   [(set_attr "itanium_class" "chk_s_i")])
 
-(define_expand "conditional_trap"
-  [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
+(define_expand "ctrapbi4"
+  [(trap_if (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:BI 1 "register_operand" "")
+                       (match_operand:BI 2 "const_int_operand" "")])
+                     (match_operand 3 "" ""))]
   ""
-{
-  operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
-})
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
+(define_expand "ctrapsi4"
+  [(trap_if (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:SI 1 "gr_register_operand" "")
+                       (match_operand:SI 2 "gr_reg_or_8bit_and_adjusted_operand" "")])
+                      (match_operand 3 "" ""))]
+  ""
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
+(define_expand "ctrapdi4"
+  [(trap_if (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:DI 1 "gr_register_operand" "")
+                       (match_operand:DI 2 "gr_reg_or_8bit_and_adjusted_operand" "")])
+                      (match_operand 3 "" ""))]
+  ""
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
+(define_expand "ctrapsf4"
+  [(trap_if (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:SF 1 "fr_reg_or_fp01_operand" "")
+                       (match_operand:SF 2 "fr_reg_or_fp01_operand" "")])
+                      (match_operand 3 "" ""))]
+  ""
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
+(define_expand "ctrapdf4"
+  [(trap_if (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:DF 1 "fr_reg_or_fp01_operand" "")
+                       (match_operand:DF 2 "fr_reg_or_fp01_operand" "")])
+                      (match_operand 3 "" ""))]
+  ""
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
+(define_expand "ctrapxf4"
+  [(trap_if (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:XF 1 "xfreg_or_fp01_operand" "")
+                       (match_operand:XF 2 "xfreg_or_fp01_operand" "")])
+                      (match_operand 3 "" ""))]
+  ""
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
+(define_expand "ctraptf4"
+  [(trap_if (match_operator 0 "ia64_cbranch_operator"
+                      [(match_operand:TF 1 "gr_register_operand" "")
+                       (match_operand:TF 2 "gr_register_operand" "")])
+                      (match_operand 3 "" ""))]
+  "TARGET_HPUX"
+  "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
 
 (define_insn "*conditional_trap"
   [(trap_if (match_operator 0 "predicate_operator"
index 5a95749..1503a05 100644 (file)
        (and (match_code "const_double,const_vector")
            (match_test "op == CONST0_RTX (GET_MODE (op))"))))
 
+;; Return 1 if OP is a valid comparison operator for "cbranch" instructions.
+(define_predicate "ia64_cbranch_operator"
+  (ior (match_operand 0 "ordered_comparison_operator")
+       (match_code "ordered,unordered")))
+
 ;; True if this is a comparison operator, which accepts a normal 8-bit
 ;; signed immediate operand.
 (define_predicate "normal_comparison_operator"
index 094bcbf..a927452 100644 (file)
@@ -41,7 +41,7 @@ extern void             print_operand (FILE *, rtx, int);
 
 #ifdef RTX_CODE
 extern rtx              gen_int_relational (enum rtx_code, rtx, rtx, rtx, int *);
-extern void             gen_conditional_branch (rtx *, enum rtx_code);
+extern void             gen_conditional_branch (rtx *, enum machine_mode);
 #endif
 
 #ifdef TREE_CODE
index 3b9e116..28bb7a8 100644 (file)
@@ -118,13 +118,6 @@ enum processor_type iq2000_tune;
 /* Which instruction set architecture to use.  */
 int iq2000_isa;
 
-/* Cached operands, and operator to compare for use in set/branch/trap
-   on condition codes.  */
-rtx branch_cmp[2];
-
-/* What type of branch to use.  */
-enum cmp_type branch_type;
-
 /* Local variables.  */
 
 /* The next branch instruction is a branch likely, not branch normal.  */
@@ -1010,60 +1003,31 @@ gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
    The comparison operands are saved away by cmp{si,di,sf,df}.  */
 
 void
-gen_conditional_branch (rtx operands[], enum rtx_code test_code)
+gen_conditional_branch (rtx operands[], enum machine_mode mode)
 {
-  enum cmp_type type = branch_type;
-  rtx cmp0 = branch_cmp[0];
-  rtx cmp1 = branch_cmp[1];
-  enum machine_mode mode;
+  enum rtx_code test_code = GET_CODE (operands[0]);
+  rtx cmp0 = operands[1];
+  rtx cmp1 = operands[2];
   rtx reg;
   int invert;
   rtx label1, label2;
 
-  switch (type)
-    {
-    case CMP_SI:
-    case CMP_DI:
-      mode = type == CMP_SI ? SImode : DImode;
-      invert = 0;
-      reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
-
-      if (reg)
-       {
-         cmp0 = reg;
-         cmp1 = const0_rtx;
-         test_code = NE;
-       }
-      else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
-       /* We don't want to build a comparison against a nonzero
-          constant.  */
-       cmp1 = force_reg (mode, cmp1);
-
-      break;
-
-    case CMP_SF:
-    case CMP_DF:
-      reg = gen_reg_rtx (CCmode);
+  invert = 0;
+  reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
 
-      /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0.  */
-      emit_insn (gen_rtx_SET (VOIDmode, reg,
-                             gen_rtx_fmt_ee (test_code == NE ? EQ : test_code,
-                                             CCmode, cmp0, cmp1)));
-
-      test_code = test_code == NE ? EQ : NE;
-      mode = CCmode;
+  if (reg)
+    {
       cmp0 = reg;
       cmp1 = const0_rtx;
-      invert = 0;
-      break;
-
-    default:
-      abort_with_insn (gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1),
-                      "bad test");
+      test_code = NE;
     }
+  else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
+    /* We don't want to build a comparison against a nonzero
+       constant.  */
+    cmp1 = force_reg (mode, cmp1);
 
   /* Generate the branch.  */
-  label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
+  label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
   label2 = pc_rtx;
 
   if (invert)
index 30642b2..0664f51 100644 (file)
@@ -1001,13 +1001,6 @@ extern enum processor_type iq2000_tune;
 /* Which instruction set architecture to use.  */
 extern int iq2000_isa;
 
-/* Cached operands, and operator to compare for use in set/branch/trap
-   on condition codes.  */
-extern rtx branch_cmp[2];
-
-/* What type of branch to use.  */
-extern enum cmp_type branch_type;
-
 enum iq2000_builtins
 {
   IQ2000_BUILTIN_ADO16,
index 919f6a2..61275f2 100644 (file)
 ;;
 ;;  ....................
 ;;
-;;     COMPARISONS
+;;     CONDITIONAL BRANCHES
 ;;
 ;;  ....................
 
-;; Flow here is rather complex:
-;;
-;;  1) The cmp{si,di,sf,df} routine is called.  It deposits the
-;;     arguments into the branch_cmp array, and the type into
-;;     branch_type.  No RTL is generated.
-;;
-;;  2) The appropriate branch define_expand is called, which then
-;;     creates the appropriate RTL for the comparison and branch.
-;;     Different CC modes are used, based on what type of branch is
-;;     done, so that we can constrain things appropriately.  There
-;;     are assumptions in the rest of GCC that break if we fold the
-;;     operands into the branches for integer operations, and use cc0
-;;     for floating point, so we use the fp status register instead.
-;;     If needed, an appropriate temporary is created to hold the
-;;     of the integer compare.
-
-(define_expand "cmpsi"
-  [(set (cc0)
-       (compare:CC (match_operand:SI 0 "register_operand" "")
-                   (match_operand:SI 1 "arith_operand" "")))]
+(define_expand "cbranchsi4"
+  [(set (pc)
+        (if_then_else
+         (match_operator:SI 0 "ordered_comparison_operator"
+                            [(match_operand:SI 1 "register_operand")
+                             (match_operand:SI 2 "reg_or_const_operand")])
+        (label_ref (match_operand:SI 3 ""))
+        (pc)))]
   ""
   "
 {
-  if (operands[0])             /* avoid unused code message */
-    {
-      branch_cmp[0] = operands[0];
-      branch_cmp[1] = operands[1];
-      branch_type = CMP_SI;
-      DONE;
-    }
+  gen_conditional_branch (operands, SImode);
+  DONE;
 }")
 
-(define_expand "tstsi"
-  [(set (cc0)
-       (match_operand:SI 0 "register_operand" ""))]
-  ""
-  "
-{
-  if (operands[0])             /* avoid unused code message */
-    {
-      branch_cmp[0] = operands[0];
-      branch_cmp[1] = const0_rtx;
-      branch_type = CMP_SI;
-      DONE;
-    }
-}")
-\f
-;;
-;;  ....................
-;;
-;;     CONDITIONAL BRANCHES
-;;
-;;  ....................
 
 ;; Conditional branches on comparisons with zero.
 
   [(set_attr "type"    "branch")
    (set_attr "mode"    "none")])
 
-(define_expand "beq"
-  [(set (pc)
-       (if_then_else (eq:CC (cc0)
-                            (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  if (operands[0])             /* avoid unused code warning */
-    {
-      gen_conditional_branch (operands, EQ);
-      DONE;
-    }
-}")
-
-(define_expand "bne"
-  [(set (pc)
-       (if_then_else (ne:CC (cc0)
-                            (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  if (operands[0])             /* avoid unused code warning */
-    {
-      gen_conditional_branch (operands, NE);
-      DONE;
-    }
-}")
-
-(define_expand "bgt"
-  [(set (pc)
-       (if_then_else (gt:CC (cc0)
-                            (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  if (operands[0])             /* avoid unused code warning */
-    {
-      gen_conditional_branch (operands, GT);
-      DONE;
-    }
-}")
-
-(define_expand "bge"
-  [(set (pc)
-       (if_then_else (ge:CC (cc0)
-                            (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  if (operands[0])             /* avoid unused code warning */
-    {
-      gen_conditional_branch (operands, GE);
-      DONE;
-    }
-}")
-
-(define_expand "blt"
-  [(set (pc)
-       (if_then_else (lt:CC (cc0)
-                            (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  if (operands[0])             /* avoid unused code warning */
-    {
-      gen_conditional_branch (operands, LT);
-      DONE;
-    }
-}")
-
-(define_expand "ble"
-  [(set (pc)
-       (if_then_else (le:CC (cc0)
-                            (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  if (operands[0])             /* avoid unused code warning */
-    {
-      gen_conditional_branch (operands, LE);
-      DONE;
-    }
-}")
-
-(define_expand "bgtu"
-  [(set (pc)
-       (if_then_else (gtu:CC (cc0)
-                             (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  if (operands[0])             /* avoid unused code warning */
-    {
-      gen_conditional_branch (operands, GTU);
-      DONE;
-    }
-}")
-
-(define_expand "bgeu"
-  [(set (pc)
-       (if_then_else (geu:CC (cc0)
-                             (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  if (operands[0])             /* avoid unused code warning */
-    {
-      gen_conditional_branch (operands, GEU);
-      DONE;
-    }
-}")
-
-
-(define_expand "bltu"
-  [(set (pc)
-       (if_then_else (ltu:CC (cc0)
-                             (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  if (operands[0])             /* avoid unused code warning */
-    {
-      gen_conditional_branch (operands, LTU);
-      DONE;
-    }
-}")
-
-(define_expand "bleu"
-  [(set (pc)
-       (if_then_else (leu:CC (cc0)
-                             (const_int 0))
-                     (label_ref (match_operand 0 "" ""))
-                     (pc)))]
-  ""
-  "
-{
-  if (operands[0])             /* avoid unused code warning */
-    {
-      gen_conditional_branch (operands, LEU);
-      DONE;
-    }
-}")
 
 ;; Recognize bbi and bbin instructions.  These use two unusual template
 ;; patterns, %Ax and %Px.  %Ax outputs an 'i' if operand `x' is a LABEL_REF
 ;;
 ;;  ....................
 
-(define_expand "seq"
+(define_expand "cstoresi4"
   [(set (match_operand:SI 0 "register_operand" "=d")
-       (eq:SI (match_dup 1)
-              (match_dup 2)))]
+       (match_operator:SI 1 "ordered_comparison_operator"
+        [(match_operand:SI 2 "register_operand")
+         (match_operand:SI 3 "reg_or_const_operand")]))]
   ""
   "
 {
-  if (branch_type != CMP_SI && (branch_type != CMP_DI))
-    FAIL;
-
-  /* Set up operands from compare.  */
-  operands[1] = branch_cmp[0];
-  operands[2] = branch_cmp[1];
-
-  gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
+  gen_int_relational (GET_CODE (operands[1]), operands[0],
+                     operands[2], operands[3], (int *)0);
   DONE;
 }")
 
-
 (define_insn "seq_si_zero"
   [(set (match_operand:SI 0 "register_operand" "=d")
        (eq:SI (match_operand:SI 1 "register_operand" "d")
   [(set_attr "type"    "arith")
    (set_attr "mode"    "SI")])
 
-(define_expand "sne"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-       (ne:SI (match_dup 1)
-              (match_dup 2)))]
-  ""
-  "
-{
-  if (branch_type != CMP_SI && (branch_type != CMP_DI))
-    FAIL;
-
-  /* Set up operands from compare.  */
-  operands[1] = branch_cmp[0];
-  operands[2] = branch_cmp[1];
-
-  gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
-  DONE;
-}")
-
 (define_insn "sne_si_zero"
   [(set (match_operand:SI 0 "register_operand" "=d")
        (ne:SI (match_operand:SI 1 "register_operand" "d")
   [(set_attr "type"    "arith")
    (set_attr "mode"    "SI")])
 
-(define_expand "sgt"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-       (gt:SI (match_dup 1)
-              (match_dup 2)))]
-  ""
-  "
-{
-  if (branch_type != CMP_SI && (branch_type != CMP_DI))
-    FAIL;
-
-  /* Set up operands from compare.  */
-  operands[1] = branch_cmp[0];
-  operands[2] = branch_cmp[1];
-
-  gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
-  DONE;
-}")
-
 (define_insn "sgt_si"
   [(set (match_operand:SI 0 "register_operand" "=d,=d")
        (gt:SI (match_operand:SI 1 "register_operand" "d,d")
   [(set_attr "type"    "arith,arith")
    (set_attr "mode"    "SI,SI")])
 
-(define_expand "sge"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-       (ge:SI (match_dup 1)
-              (match_dup 2)))]
-  ""
-  "
-{
-  if (branch_type != CMP_SI && (branch_type != CMP_DI))
-    FAIL;
-
-  /* Set up operands from compare.  */
-  operands[1] = branch_cmp[0];
-  operands[2] = branch_cmp[1];
-
-  gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
-  DONE;
-}")
-
-(define_expand "slt"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-       (lt:SI (match_dup 1)
-              (match_dup 2)))]
-  ""
-  "
-{
-  if (branch_type != CMP_SI && (branch_type != CMP_DI))
-    FAIL;
-
-  /* Set up operands from compare.  */
-  operands[1] = branch_cmp[0];
-  operands[2] = branch_cmp[1];
-
-  gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
-  DONE;
-}")
-
 (define_insn "slt_si"
   [(set (match_operand:SI 0 "register_operand" "=d,=d")
        (lt:SI (match_operand:SI 1 "register_operand" "d,d")
   [(set_attr "type"    "arith,arith")
    (set_attr "mode"    "SI,SI")])
 
-(define_expand "sle"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-       (le:SI (match_dup 1)
-              (match_dup 2)))]
-  ""
-  "
-{
-  if (branch_type != CMP_SI && (branch_type != CMP_DI))
-    FAIL;
-
-  /* Set up operands from compare.  */
-  operands[1] = branch_cmp[0];
-  operands[2] = branch_cmp[1];
-
-  gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
-  DONE;
-}")
-
 (define_insn "sle_si_const"
   [(set (match_operand:SI 0 "register_operand" "=d")
        (le:SI (match_operand:SI 1 "register_operand" "d")
   [(set_attr "type"    "arith")
    (set_attr "mode"    "SI")])
 
-(define_expand "sgtu"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-       (gtu:SI (match_dup 1)
-               (match_dup 2)))]
-  ""
-  "
-{
-  if (branch_type != CMP_SI && (branch_type != CMP_DI))
-    FAIL;
-
-  /* Set up operands from compare.  */
-  operands[1] = branch_cmp[0];
-  operands[2] = branch_cmp[1];
-
-  gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
-  DONE;
-}")
-
 (define_insn "sgtu_si"
   [(set (match_operand:SI 0 "register_operand" "=d")
        (gtu:SI (match_operand:SI 1 "register_operand" "d")
   [(set_attr "type"    "arith")
    (set_attr "mode"    "SI")])
 
-(define_expand "sgeu"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-        (geu:SI (match_dup 1)
-                (match_dup 2)))]
-  ""
-  "
-{
-  if (branch_type != CMP_SI && (branch_type != CMP_DI))
-    FAIL;
-
-  /* Set up operands from compare.  */
-  operands[1] = branch_cmp[0];
-  operands[2] = branch_cmp[1];
-
-  gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
-  DONE;
-}")
-
-(define_expand "sltu"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-       (ltu:SI (match_dup 1)
-               (match_dup 2)))]
-  ""
-  "
-{
-  if (branch_type != CMP_SI && (branch_type != CMP_DI))
-    FAIL;
-
-  /* Set up operands from compare.  */
-  operands[1] = branch_cmp[0];
-  operands[2] = branch_cmp[1];
-
-  gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
-  DONE;
-}")
-
 (define_insn "sltu_si"
   [(set (match_operand:SI 0 "register_operand" "=d,=d")
        (ltu:SI (match_operand:SI 1 "register_operand" "d,d")
   [(set_attr "type"    "arith,arith")
    (set_attr "mode"    "SI,SI")])
 
-(define_expand "sleu"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-       (leu:SI (match_dup 1)
-               (match_dup 2)))]
-  ""
-  "
-{
-  if (branch_type != CMP_SI && (branch_type != CMP_DI))
-    FAIL;
-
-  /* Set up operands from compare.  */
-  operands[1] = branch_cmp[0];
-  operands[2] = branch_cmp[1];
-
-  gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
-  DONE;
-}")
-
 (define_insn "sleu_si_const"
   [(set (match_operand:SI 0 "register_operand" "=d")
        (leu:SI (match_operand:SI 1 "register_operand" "d")
index 53471e4..f275090 100644 (file)
   return register_operand (op, mode);
 })
 
+;; Return 1 if OP is a register or a constant.  gen_int_relational
+;; takes care of forcing out-of-range constants into a register.
+
+(define_predicate "reg_or_const_operand"
+  (ior (match_code "const_int")
+       (and (match_code "reg,subreg")
+            (match_operand 0 "register_operand"))))
+
 ;; Return 1 if OP is a integer which fits in 16 bits.
 
 (define_predicate "small_int"
index 60d83ee..c751070 100644 (file)
   [(set (reg:CC FLG_REGNO)
        (compare (match_dup 1)
                 (match_dup 2)))
-   (set (pc) (if_then_else (match_dup 4)
+   (set (pc) (if_then_else (match_op_dup 0 [(reg:CC FLG_REGNO) (const_int 0)])
                           (label_ref (match_dup 3))
                           (pc)))]
-  "operands[4] = m32c_cmp_flg_0 (operands[0]);"
+  ""
   )
 
+(define_insn "bcc_op"
+  [(set (pc)
+        (if_then_else (match_operator 0 "ordered_comparison_operator"
+                      [(reg:CC FLG_REGNO) (const_int 0)])
+                      (label_ref (match_operand 1 ""))
+                      (pc)))]
+  ""
+  "j%c0\t%l1"
+  [(set_attr "flags" "n")]
+)
+
 (define_insn "stzx_16"
   [(set (match_operand:QI 0 "mrai_operand" "=R0w,R0w,R0w")
        (if_then_else:QI (eq (reg:CC FLG_REGNO) (const_int 0))
   "* return m32c_output_compare(insn, operands); "
   [(set_attr "flags" "oszc")])
 
-(define_expand "cmp<mode>"
-  [(set (reg:CC FLG_REGNO)
-       (compare (match_operand:QHPSI 0 "mra_operand" "RraSd")
-                (match_operand:QHPSI 1 "mrai_operand" "RraSdi")))]
-  ""
-  "m32c_pend_compare (operands); DONE;")
-
-(define_insn "b<code>_op"
-  [(set (pc)
-        (if_then_else (any_cond (reg:CC FLG_REGNO)
-                               (const_int 0))
-                      (label_ref (match_operand 0 ""))
-                      (pc)))]
-  ""
-  "j<code>\t%l0"
-  [(set_attr "flags" "n")]
-)
-
-(define_expand "b<code>"
-  [(set (pc)
-        (if_then_else (any_cond (reg:CC FLG_REGNO)
-                               (const_int 0))
-                      (label_ref (match_operand 0 ""))
-                      (pc)))]
-  ""
-  "m32c_unpend_compare ();"
-)
-
 ;; m32c_conditional_register_usage changes the setcc_gen_code array to
 ;; point to the _24 variants if needed.
 
 
 ;; These are the post-split patterns for the conditional sets.
 
-(define_insn "s<code>_op"
+(define_insn "scc_op"
   [(set (match_operand:QI 0 "register_operand" "=Rqi")
-       (any_cond:QI (reg:CC FLG_REGNO) (const_int 0)))]
+       (match_operator:QI 1 "ordered_comparison_operator"
+        [(reg:CC FLG_REGNO) (const_int 0)]))]
   "TARGET_A16 && reload_completed"
-  "* return m32c_scc_pattern(operands, <CODE>);")
+  "* return m32c_scc_pattern(operands, GET_CODE (operands[1]));")
 
-(define_insn "s<code>_24_op"
+(define_insn "scc_24_op"
   [(set (match_operand:HI 0 "mra_operand" "=RhiSd")
-       (any_cond:HI (reg:CC FLG_REGNO) (const_int 0)))]
+       (match_operator:HI 1 "ordered_comparison_operator"
+        [(reg:CC FLG_REGNO) (const_int 0)]))]
   "TARGET_A24 && reload_completed"
-  "sc<code>\t%0"
+  "sc%c1\t%0"
   [(set_attr "flags" "n")]
 )
 
-;; These are the pre-split patterns for the conditional sets.  Yes,
-;; there are a lot of permutations.
+;; These are the pre-split patterns for the conditional sets.
 
-(define_insn_and_split "s<code>_<mode>"
+(define_insn_and_split "cstore<mode>4"
   [(set (match_operand:QI 0 "register_operand" "=Rqi")
-       (any_cond:QI (match_operand:QHPSI 1 "mra_operand" "RraSd")
-                    (match_operand:QHPSI 2 "mrai_operand" "RraSdi")))]
+       (match_operator:QI 1 "ordered_comparison_operator"
+        [(match_operand:QHPSI 2 "mra_operand" "RraSd")
+         (match_operand:QHPSI 3 "mrai_operand" "RraSdi")]))]
   "TARGET_A16"
   "#"
   "reload_completed"
   [(set (reg:CC FLG_REGNO)
-       (compare (match_dup 1)
-                (match_dup 2)))
+       (compare (match_dup 2)
+                (match_dup 3)))
    (set (match_dup 0)
-       (any_cond:QI (reg:CC FLG_REGNO) (const_int 0)))]
+       (match_op_dup 1 [(reg:CC FLG_REGNO) (const_int 0)]))]
   ""
   [(set_attr "flags" "x")]
 )
 
-(define_insn_and_split "s<code>_<mode>_24"
+(define_insn_and_split "cstore<mode>4_24"
   [(set (match_operand:HI 0 "mra_nopp_operand" "=RhiSd")
-       (any_cond:HI (match_operand:QHPSI 1 "mra_operand" "RraSd")
-                    (match_operand:QHPSI 2 "mrai_operand" "RraSdi")))]
+       (match_operator:HI 1 "ordered_comparison_operator"
+        [(match_operand:QHPSI 2 "mra_operand" "RraSd")
+         (match_operand:QHPSI 3 "mrai_operand" "RraSdi")]))]
   "TARGET_A24"
   "#"
   "reload_completed"
   [(set (reg:CC FLG_REGNO)
-       (compare (match_dup 1)
-                (match_dup 2)))
+       (compare (match_dup 2)
+                (match_dup 3)))
    (set (match_dup 0)
-       (any_cond:HI (reg:CC FLG_REGNO) (const_int 0)))]
+       (match_op_dup 1 [(reg:CC FLG_REGNO) (const_int 0)]))]
   ""
   [(set_attr "flags" "x")]
 )
   [(set_attr "flags" "x")]
   )
 
-;; And these are the expanders, which read the pending compare
-;; operands to build a combined insn.
-
-(define_expand "s<code>"
-  [(set (match_operand:QI 0 "register_operand" "=Rqi")
-       (any_cond:QI (reg:CC FLG_REGNO) (const_int 0)))]
-  "TARGET_A16"
-  "m32c_expand_scc (<CODE>, operands); DONE;")
-
-(define_expand "s<code>_24"
-  [(set (match_operand:HI 0 "mra_nopp_operand" "=RhiSd")
-       (any_cond:HI (reg:CC FLG_REGNO) (const_int 0)))]
-  "TARGET_A24"
-  "m32c_expand_scc (<CODE>, operands); DONE;")
-
+;; And these are the expanders.
 
 (define_expand "movqicc"
   [(set (match_operand:QI 0 "register_operand" "")