summaryrefslogtreecommitdiff
path: root/gcc/config/i860/i860.c
diff options
context:
space:
mode:
authorrms <rms@138bc75d-0d04-0410-961f-82ee72b054a4>1993-07-11 22:52:46 +0000
committerrms <rms@138bc75d-0d04-0410-961f-82ee72b054a4>1993-07-11 22:52:46 +0000
commitfc4dd30ec8b3d8870e2ca7b7988b560bb2d98456 (patch)
tree583607ecb889ed3f856a34dbb546e3e865069d20 /gcc/config/i860/i860.c
parent99a602cc9a8cf01777df5cd882d9a0ccd63ae3a2 (diff)
downloadgcc-fc4dd30ec8b3d8870e2ca7b7988b560bb2d98456.tar.gz
(output_move_double): Fix typos in Jun 28 change.
Only set highest_first if first reg of dest overlaps memory src address. Otherwise, if addreg1 set and is same as second reg of dest, suppress trailing decrement. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@4907 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/i860/i860.c')
-rw-r--r--gcc/config/i860/i860.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/gcc/config/i860/i860.c b/gcc/config/i860/i860.c
index da7d0ab91e9..7201f059d1a 100644
--- a/gcc/config/i860/i860.c
+++ b/gcc/config/i860/i860.c
@@ -573,6 +573,7 @@ output_move_double (operands)
rtx latehalf[2];
rtx addreg0 = 0, addreg1 = 0;
int highest_first = 0;
+ int no_addreg1_decrement = 0;
/* First classify both operands. */
@@ -681,22 +682,33 @@ output_move_double (operands)
else if (optype0 == REGOP && optype1 != REGOP
&& reg_overlap_mentioned_p (operands[0], operands[1]))
{
- 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 (operands[0]).
+ Then it works to load latehalf first. */
+ if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
+ && reg_mentioned_p (latehalf[0], XEXP (operands[1], 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;
+ xops[1] = operands[0];
output_asm_insn ("adds %1,%0,%1", xops);
- operands[1] = gen_rtx (MEM, DImode, op0);
+ operands[1] = gen_rtx (MEM, DImode, operands[0]);
latehalf[1] = adj_offsettable_operand (operands[1], 4);
addreg1 = 0;
+ highest_first = 1;
}
- /* Do the late half first. */
- highest_first = 1;
+ /* Only one register in the dest is used in the src memory address,
+ and this is the first register of the dest, so we want to do
+ the late half first here also. */
+ else if (! reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
+ highest_first = 1;
+ /* Only one register in the dest is used in the src memory address,
+ and this is the second register of the dest, so we want to do
+ the late half last. If addreg1 is set, and addreg1 is the same
+ register as latehalf, then we must suppress the trailing decrement,
+ because it would clobber the value just loaded. */
+ else if (addreg1 && reg_mentioned_p (addreg1, latehalf[0]))
+ no_addreg1_decrement = 1;
}
/* Normal case: do the two words, low-numbered first.
@@ -718,7 +730,7 @@ output_move_double (operands)
/* Undo the adds we just did. */
if (addreg0)
output_asm_insn ("adds -0x4,%0,%0", &addreg0);
- if (addreg1)
+ if (addreg1 && !no_addreg1_decrement)
output_asm_insn ("adds -0x4,%0,%0", &addreg1);
if (highest_first)