diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-15 04:56:06 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-05-15 04:56:06 +0000 |
commit | 8da637123e80be2156e84d0f2f1be564132996c1 (patch) | |
tree | 3ff18ff7fc94a7ca0a414c165e33d5a33108b3f3 /gcc/expmed.c | |
parent | 8eafe656d06910682748b4f19ea12cd8bbabd4ba (diff) | |
download | gcc-8da637123e80be2156e84d0f2f1be564132996c1.tar.gz |
2009-05-15 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r147550
2009-05-15 Basile Starynkevitch <basile@starynkevitch.net>
merged with trunk rev147539
* gcc/melt/warmelt-normal.melt (normexp_defcmatcher): use obj_hash
instead of hashcode!
* gcc/Makefile.in: TEXI_GCCINT_FILES has both plugins.texi & melt.texi
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@147552 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 122 |
1 files changed, 25 insertions, 97 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c index d0c1621cc5e..16f7415b549 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -5207,8 +5207,9 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1, enum insn_code icode; enum machine_mode compare_mode; enum machine_mode target_mode = GET_MODE (target); + enum mode_class mclass; rtx tem; - rtx last = get_last_insn (); + rtx last; rtx pattern, comparison; if (unsignedp) @@ -5342,117 +5343,41 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1, return op0; } - icode = setcc_gen_code[(int) code]; - - if (icode != CODE_FOR_nothing) - { - insn_operand_predicate_fn pred; - - /* We think we may be able to do this with a scc insn. Emit the - comparison and then the scc insn. */ - - do_pending_stack_adjust (); - last = get_last_insn (); - - comparison - = compare_from_rtx (op0, op1, code, unsignedp, mode, NULL_RTX); - if (CONSTANT_P (comparison)) - { - switch (GET_CODE (comparison)) - { - case CONST_INT: - if (comparison == const0_rtx) - return const0_rtx; - break; - -#ifdef FLOAT_STORE_FLAG_VALUE - case CONST_DOUBLE: - if (comparison == CONST0_RTX (GET_MODE (comparison))) - return const0_rtx; - break; -#endif - default: - gcc_unreachable (); - } - - if (normalizep == 1) - return const1_rtx; - if (normalizep == -1) - return constm1_rtx; - return const_true_rtx; - } - - /* The code of COMPARISON may not match CODE if compare_from_rtx - decided to swap its operands and reverse the original code. - - We know that compare_from_rtx returns either a CONST_INT or - a new comparison code, so it is safe to just extract the - code from COMPARISON. */ - code = GET_CODE (comparison); - - /* Get a reference to the target in the proper mode for this insn. */ - compare_mode = insn_data[(int) icode].operand[0].mode; - subtarget = target; - pred = insn_data[(int) icode].operand[0].predicate; - if (optimize || ! (*pred) (subtarget, compare_mode)) - subtarget = gen_reg_rtx (compare_mode); - - pattern = GEN_FCN (icode) (subtarget); - if (pattern) - { - emit_insn (pattern); - return emit_store_flag_1 (target, subtarget, compare_mode, - normalizep); - } - } - else + mclass = GET_MODE_CLASS (mode); + for (compare_mode = mode; compare_mode != VOIDmode; + compare_mode = GET_MODE_WIDER_MODE (compare_mode)) { - /* We don't have an scc insn, so try a cstore insn. */ - - for (compare_mode = mode; compare_mode != VOIDmode; - compare_mode = GET_MODE_WIDER_MODE (compare_mode)) - { - icode = optab_handler (cstore_optab, compare_mode)->insn_code; - if (icode != CODE_FOR_nothing) - break; - } - - if (icode != CODE_FOR_nothing) + enum machine_mode optab_mode = mclass == MODE_CC ? CCmode : compare_mode; + icode = optab_handler (cstore_optab, optab_mode)->insn_code; + if (icode != CODE_FOR_nothing) { + rtx x, y; enum machine_mode result_mode = insn_data[(int) icode].operand[0].mode; - rtx cstore_op0 = op0; - rtx cstore_op1 = op1; do_pending_stack_adjust (); last = get_last_insn (); - if (compare_mode != mode) + x = prepare_operand (icode, op0, 2, mode, compare_mode, unsignedp); + y = prepare_operand (icode, op1, 3, mode, compare_mode, unsignedp); + comparison = gen_rtx_fmt_ee (code, result_mode, x, y); + if (!x || !y + || !insn_data[icode].operand[2].predicate + (x, insn_data[icode].operand[2].mode) + || !insn_data[icode].operand[3].predicate + (y, insn_data[icode].operand[3].mode) + || !insn_data[icode].operand[1].predicate (comparison, VOIDmode)) { - cstore_op0 = convert_modes (compare_mode, mode, cstore_op0, - unsignedp); - cstore_op1 = convert_modes (compare_mode, mode, cstore_op1, - unsignedp); + delete_insns_since (last); + continue; } - - if (!insn_data[(int) icode].operand[2].predicate (cstore_op0, - compare_mode)) - cstore_op0 = copy_to_mode_reg (compare_mode, cstore_op0); - if (!insn_data[(int) icode].operand[3].predicate (cstore_op1, - compare_mode)) - cstore_op1 = copy_to_mode_reg (compare_mode, cstore_op1); - - comparison = gen_rtx_fmt_ee (code, result_mode, cstore_op0, - cstore_op1); subtarget = target; - if (optimize || !(insn_data[(int) icode].operand[0].predicate (subtarget, result_mode))) subtarget = gen_reg_rtx (result_mode); - pattern = GEN_FCN (icode) (subtarget, comparison, cstore_op0, - cstore_op1); + pattern = GEN_FCN (icode) (subtarget, comparison, x, y); if (pattern) { @@ -5460,10 +5385,13 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1, return emit_store_flag_1 (target, subtarget, result_mode, normalizep); } + + delete_insns_since (last); + break; } } - delete_insns_since (last); + last = get_last_insn (); /* If optimizing, use different pseudo registers for each insn, instead of reusing the same pseudo. This leads to better CSE, but slows |