(movqi): Handle copying an address register to or
from memory when the address uses the address register. From-SVN: r4668
This commit is contained in:
parent
09d6547996
commit
9e69dd9f3a
@ -932,6 +932,44 @@
|
||||
/* Use d0 as an intermediate, but don't clobber its contents. */
|
||||
if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM)
|
||||
{
|
||||
/* ??? For 2.5, don't allow this choice and use secondary reloads
|
||||
instead.
|
||||
|
||||
See if the address register is used in the address. If it
|
||||
is, we have to generate a more complex sequence than those below. */
|
||||
if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
|
||||
operands[1], NULL_RTX))
|
||||
{
|
||||
/* See if the stack pointer is used in the address. If it isn't,
|
||||
we can push d0 or d1 (the insn can't use both of them) on
|
||||
the stack, perform our move into d0/d1, copy the byte from d0/1,
|
||||
and pop d0/1. */
|
||||
if (! reg_mentioned_p (stack_pointer_rtx, operands[1]))
|
||||
{
|
||||
if (refers_to_regno_p (0, 1, operands[1], NULL_RTX))
|
||||
return \"move%.l %/d0,%-\;move%.b %1,%/d0\;move%.l %/d0,%0\;move%.l %+,%/d0\";
|
||||
else
|
||||
return \"move%.l %/d1,%-\;move%.b %1,%/d1\;move%.l %/d1,%0\;move%.l %+,%/d1\";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, we know that d0 cannot be used in the address
|
||||
(since sp and one address register is). Assume that sp is
|
||||
being used as a base register and replace the address
|
||||
register that is our operand[0] with d0. */
|
||||
rtx reg_map[FIRST_PSEUDO_REGISTER];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
reg_map[i] = 0;
|
||||
|
||||
reg_map[REGNO (operands[0])] = gen_rtx (REG, Pmode, 0);
|
||||
operands[1] = copy_rtx (operands[1]);
|
||||
replace_regs (operands[1], reg_map, FIRST_PSEUDO_REGISTER, 0);
|
||||
return \"exg %/d0,%0\;move%.b %1,%/d0\;exg %/d0,%0\";
|
||||
}
|
||||
}
|
||||
|
||||
/* If the address of operand 1 uses d0, choose d1 as intermediate. */
|
||||
if (refers_to_regno_p (0, 1, operands[1], NULL_RTX))
|
||||
return \"exg %/d1,%0\;move%.b %1,%/d1\;exg %/d1,%0\";
|
||||
@ -944,6 +982,44 @@
|
||||
/* Likewise for moving from an address reg. */
|
||||
if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM)
|
||||
{
|
||||
/* ??? For 2.5, don't allow this choice and use secondary reloads
|
||||
instead.
|
||||
|
||||
See if the address register is used in the address. If it
|
||||
is, we have to generate a more complex sequence than those below. */
|
||||
if (refers_to_regno_p (REGNO (operands[1]), REGNO (operands[1]) + 1,
|
||||
operands[0], NULL_RTX))
|
||||
{
|
||||
/* See if the stack pointer is used in the address. If it isn't,
|
||||
we can push d0 or d1 (the insn can't use both of them) on
|
||||
the stack, copy the byte to d0/1, perform our move from d0/d1,
|
||||
and pop d0/1. */
|
||||
if (! reg_mentioned_p (stack_pointer_rtx, operands[0]))
|
||||
{
|
||||
if (refers_to_regno_p (0, 1, operands[0], NULL_RTX))
|
||||
return \"move%.l %/d0,%-\;move%.l %1,%/d0\;move%.b %/d0,%0\;move%.l %+,%/d0\";
|
||||
else
|
||||
return \"move%.l %/d1,%-\;move%.l %1,%/d1\;move%.b %/d1,%0\;move%.l %+,%/d1\";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, we know that d0 cannot be used in the address
|
||||
(since sp and one address register is). Assume that sp is
|
||||
being used as a base register and replace the address
|
||||
register that is our operand[1] with d0. */
|
||||
rtx reg_map[FIRST_PSEUDO_REGISTER];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
reg_map[i] = 0;
|
||||
|
||||
reg_map[REGNO (operands[1])] = gen_rtx (REG, Pmode, 0);
|
||||
operands[0] = copy_rtx (operands[0]);
|
||||
replace_regs (operands[0], reg_map, FIRST_PSEUDO_REGISTER, 0);
|
||||
return \"exg %/d0,%1\;move%.b %/d0,%0\;exg %/d0,%1\";
|
||||
}
|
||||
}
|
||||
|
||||
if (refers_to_regno_p (0, 1, operands[0], NULL_RTX))
|
||||
return \"exg %/d1,%1\;move%.b %/d1,%0\;exg %/d1,%1\";
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user