summaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1993-03-04 20:37:02 +0000
committerRichard Stallman <rms@gnu.org>1993-03-04 20:37:02 +0000
commit54e7b5e6ef5f4dc87b64f5781e56aae248da857f (patch)
treed2dc58d8eabd78accc4928c18160187cdada96ac /gcc/optabs.c
parentb6a10c9fe17597c7870f182aa505e7bf77aab429 (diff)
downloadgcc-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.c51
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 ();