aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1995-10-26 08:06:43 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1995-10-26 08:06:43 -0400
commite82ee4ccb6c344f5525e0c640e9f279d7d1013c0 (patch)
tree2cf38fbcf9cffd6d8a7d936931d80790cb067d9f
parentc7eee2df1d729c52112e5388f6d4146780ae77d5 (diff)
downloadgcc-e82ee4ccb6c344f5525e0c640e9f279d7d1013c0.zip
gcc-e82ee4ccb6c344f5525e0c640e9f279d7d1013c0.tar.gz
gcc-e82ee4ccb6c344f5525e0c640e9f279d7d1013c0.tar.bz2
(load_multiple insn): If address register is among regs...
(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
-rw-r--r--gcc/config/rs6000/rs6000.md56
1 files changed, 41 insertions, 15 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index f5ecb7e..ccea4dc 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -4706,29 +4706,55 @@
"*
{
/* 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")])
(define_expand "store_multiple"