/* 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\";
/* 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