diff options
author | Richard Stallman <rms@gnu.org> | 1993-03-04 20:37:02 +0000 |
---|---|---|
committer | Richard Stallman <rms@gnu.org> | 1993-03-04 20:37:02 +0000 |
commit | 54e7b5e6ef5f4dc87b64f5781e56aae248da857f (patch) | |
tree | d2dc58d8eabd78accc4928c18160187cdada96ac /gcc/optabs.c | |
parent | b6a10c9fe17597c7870f182aa505e7bf77aab429 (diff) | |
download | gcc-54e7b5e6ef5f4dc87b64f5781e56aae248da857f.tar.gz |
(emit_no_conflict_block): Don't move target to itself if that takes multiple insns.
(emit_no_conflict_block): Don't move target to itself
if that takes multiple insns.
(expand_binop): For complex mult and div, avoid fetching operand
components more than once from memory.
From-SVN: r3647
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index cc192be2e39..65a56cdca93 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -916,16 +916,21 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) if (imag0 && imag1) { - rtx temp = - expand_binop (submode, sub_optab, - expand_binop (submode, binoptab, real0, - real1, 0, unsignedp, methods), - expand_binop (submode, binoptab, imag0, - imag1, 0, unsignedp, methods), - realr, unsignedp, methods); + /* Don't fetch these from memory more than once. */ + real0 = force_reg (submode, real0); + real1 = force_reg (submode, real1); + imag0 = force_reg (submode, imag0); + imag1 = force_reg (submode, imag1); + + res = expand_binop (submode, sub_optab, + expand_binop (submode, binoptab, real0, + real1, 0, unsignedp, methods), + expand_binop (submode, binoptab, imag0, + imag1, 0, unsignedp, methods), + realr, unsignedp, methods); - if (temp != realr) - emit_move_insn (realr, temp); + if (res != realr) + emit_move_insn (realr, res); res = expand_binop (submode, add_optab, expand_binop (submode, binoptab, @@ -940,6 +945,10 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) } else { + /* Don't fetch these from memory more than once. */ + real0 = force_reg (submode, real0); + real1 = force_reg (submode, real1); + res = expand_binop (submode, binoptab, real0, real1, realr, unsignedp, methods); if (res != realr) @@ -961,6 +970,10 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) if (! imag1) { /* (a+ib) / (c+i0) = (a/c) + i(b/c) */ + + /* Don't fetch these from memory more than once. */ + real1 = force_reg (submode, real1); + /* Simply divide the real and imaginary parts by `c' */ res = expand_binop (submode, binoptab, real0, real1, realr, unsignedp, methods); @@ -981,6 +994,13 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) optab mulopt = unsignedp ? umul_widen_optab : smul_optab; + /* Don't fetch these from memory more than once. */ + real0 = force_reg (submode, real0); + real1 = force_reg (submode, real1); + if (imag0) + imag0 = force_reg (submode, imag0); + imag1 = force_reg (submode, imag1); + /* Divisor: c*c + d*d */ divisor = expand_binop (submode, add_optab, expand_binop (submode, mulopt, @@ -1984,9 +2004,16 @@ emit_no_conflict_block (insns, target, op0, op1, equiv) REG_NOTES (insn)); } - last = emit_move_insn (target, target); - if (equiv) - REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last)); + if (mov_optab->handlers[(int) GET_MODE (target)].insn_code + != CODE_FOR_nothing) + { + last = emit_move_insn (target, target); + if (equiv) + REG_NOTES (last) + = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last)); + } + else + last = get_last_insn (); if (prev == 0) first = get_insns (); |