"*
{
/* 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"