(load_multiple insn): If address register is among regs...
authorRichard Kenner <kenner@gcc.gnu.org>
Thu, 26 Oct 1995 12:06:43 +0000 (08:06 -0400)
committerRichard Kenner <kenner@gcc.gnu.org>
Thu, 26 Oct 1995 12:06:43 +0000 (08:06 -0400)
(load_multiple insn): If address register is among regs, don't load it
with a lwsi instruction, which is undefined on PowerPC.

From-SVN: r10512

gcc/config/rs6000/rs6000.md

index f5ecb7ec25544a69f056eae1f882f7f58e7ce6e5..ccea4dc81e0f0c14860aeeb887f9f30cbf685441 100644 (file)
   "*
 {
   /* We have to handle the case where the pseudo used to contain the address
-     is assigned to one of the output registers.  In that case, do the
-     lsi, but then load the correct value.  This is a bit of a mess, but is
-     the best we can do.
-     We set the length attribute to the maximum possible size (8 bytes).  */
-  static char result[100];
-  char newload[40];
-  int i;
+     is assigned to one of the output registers.  */
+  int i, j;
+  int words = XVECLEN (operands[0], 0);
+  rtx xop[10];
+
+  if (XVECLEN (operands[0], 0) == 1)
+    return \"{l|lwz} %1,0(%2)\";
 
-  strcpy (result, \"{lsi|lswi} %1,%2,%N0\");
-  for (i = 0; i < XVECLEN (operands[0], 0); i++)
+  for (i = 0; i < words; i++)
     if (refers_to_regno_p (REGNO (operands[1]) + i,
                           REGNO (operands[1]) + i + 1, operands[2], 0))
       {
-       sprintf (newload, \"\;{l|lwz} %d,%d(%d)\",
-                REGNO (operands[1]) + i,
-                i * 4, REGNO (operands[2]));
-       strcat (result, newload);
+       if (i == words-1)
+         {
+           xop[0] = operands[1];
+           xop[1] = operands[2];
+           xop[2] = GEN_INT (4 * (words-1));
+           output_asm_insn (\"{lsi|lswi} %0,%1,%2\;lwz %1,%2(%1)\", xop);
+           return \"\";
+         }
+       else if (i == 0)
+         {
+           xop[0] = operands[1];
+           xop[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
+           xop[2] = GEN_INT (4 * (words-1));
+           output_asm_insn (\"{cal %0,4(%0)|addi %0,%0,4}\;{lsi|lswi} %1,%0,%2\;{l|lwz} %0,-4(%0)\", xop);
+           return \"\";
+         }
+       else
+         {
+           for (j = 0; j < words; j++)
+             if (j != i)
+               {
+                 xop[0] = gen_rtx (REG, SImode, REGNO (operands[1]) + j);
+                 xop[1] = operands[2];
+                 xop[2] = GEN_INT (j * 4);
+                 output_asm_insn (\"{l|lwz} %0,%2(%1)\", xop);
+               }
+           xop[0] = operands[2];
+           xop[1] = GEN_INT (i * 4);
+           output_asm_insn (\"{l|lwz} %0,%1(%0)\", xop);
+           return \"\";
+         }
       }
 
-  return result;
+  return \"{lsi|lswi} %1,%2,%N0\";
 }"
   [(set_attr "type" "load")
-   (set_attr "length" "8")])
+   (set_attr "length" "32")])
 \f
 
 (define_expand "store_multiple"