(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. */
|
/* Use d0 as an intermediate, but don't clobber its contents. */
|
||||||
if (ADDRESS_REG_P (operands[0]) && GET_CODE (operands[1]) == MEM)
|
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 the address of operand 1 uses d0, choose d1 as intermediate. */
|
||||||
if (refers_to_regno_p (0, 1, operands[1], NULL_RTX))
|
if (refers_to_regno_p (0, 1, operands[1], NULL_RTX))
|
||||||
return \"exg %/d1,%0\;move%.b %1,%/d1\;exg %/d1,%0\";
|
return \"exg %/d1,%0\;move%.b %1,%/d1\;exg %/d1,%0\";
|
||||||
@ -944,6 +982,44 @@
|
|||||||
/* Likewise for moving from an address reg. */
|
/* Likewise for moving from an address reg. */
|
||||||
if (ADDRESS_REG_P (operands[1]) && GET_CODE (operands[0]) == MEM)
|
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))
|
if (refers_to_regno_p (0, 1, operands[0], NULL_RTX))
|
||||||
return \"exg %/d1,%1\;move%.b %/d1,%0\;exg %/d1,%1\";
|
return \"exg %/d1,%1\;move%.b %/d1,%0\;exg %/d1,%1\";
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user