aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1993-06-28 18:21:17 +0000
committerRichard Stallman <rms@gnu.org>1993-06-28 18:21:17 +0000
commit5a167d9cee971f3125535b9b670c06bb9c78a9a1 (patch)
treec82b0faf76bc7fc9ca76a844c37792aaa0b85d8f /gcc
parent3b76513aee76adbfa5a19dd2d7a27fdae1e02940 (diff)
downloadgcc-5a167d9cee971f3125535b9b670c06bb9c78a9a1.zip
gcc-5a167d9cee971f3125535b9b670c06bb9c78a9a1.tar.gz
gcc-5a167d9cee971f3125535b9b670c06bb9c78a9a1.tar.bz2
(output_move_double): Handle reg[n,n+1] = mem[reg[n] + reg[n+1]].
From-SVN: r4789
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/ns32k/ns32k.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/gcc/config/ns32k/ns32k.c b/gcc/config/ns32k/ns32k.c
index eb47d9c..6dd4a96 100644
--- a/gcc/config/ns32k/ns32k.c
+++ b/gcc/config/ns32k/ns32k.c
@@ -316,7 +316,42 @@ output_move_double (operands)
return singlemove_string (operands);
}
- /* Not autodecrementing. Do the two words, low-numbered first. */
+ /* If the first move would clobber the source of the second one,
+ do them in the other order. */
+
+ /* Overlapping registers. */
+ if (optype0 == REGOP && optype1 == REGOP
+ && REGNO (op0) == REGNO (latehalf[1]))
+ {
+ /* Do that word. */
+ output_asm_insn (singlemove_string (latehalf), latehalf);
+ /* Do low-numbered word. */
+ return singlemove_string (operands);
+ }
+ /* Loading into a register which overlaps a register used in the address. */
+ else if (optype0 == REGOP && optype1 != REGOP
+ && reg_overlap_mentioned_p (op0, op1))
+ {
+ if (reg_mentioned_p (op0, XEXP (op1, 0))
+ && reg_mentioned_p (latehalf[0], XEXP (op1, 0)))
+ {
+ /* If both halves of dest are used in the src memory address,
+ add the two regs and put them in the low reg (op0).
+ Then it works to load latehalf first. */
+ rtx xops[2];
+ xops[0] = latehalf[0];
+ xops[1] = op0;
+ output_asm_insn ("addd %0,%1", xops);
+ operands[1] = gen_rtx (MEM, DImode, op0);
+ latehalf[1] = adj_offsettable_operand (operands[1], 4);
+ }
+ /* Do the late half first. */
+ output_asm_insn (singlemove_string (latehalf), latehalf);
+ /* Then clobber. */
+ return singlemove_string (operands);
+ }
+
+ /* Normal case. Do the two words, low-numbered first. */
output_asm_insn (singlemove_string (operands), operands);