From 9e69dd9f3a3e70cd53e5cf9717094030a1590e13 Mon Sep 17 00:00:00 2001 From: Richard Stallman Date: Sat, 12 Jun 1993 20:23:42 +0000 Subject: [PATCH] (movqi): Handle copying an address register to or from memory when the address uses the address register. From-SVN: r4668 --- gcc/config/m68k/m68k.md | 76 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index 456b99e6ee6..ce6b42f8e9b 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -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 -- 2.30.2