]> gcc.gnu.org Git - gcc.git/commitdiff
(movqi): Handle copying an address register to or
authorRichard Stallman <rms@gnu.org>
Sat, 12 Jun 1993 20:23:42 +0000 (20:23 +0000)
committerRichard Stallman <rms@gnu.org>
Sat, 12 Jun 1993 20:23:42 +0000 (20:23 +0000)
from memory when the address uses the address register.

From-SVN: r4668

gcc/config/m68k/m68k.md

index 456b99e6ee603ff47eef046436eed5dce243d762..ce6b42f8e9bd5cc7601bf6fca0c1e4ab661e3501 100644 (file)
   /* 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
This page took 0.068934 seconds and 5 git commands to generate.