+2009-08-05 Uros Bizjak <ubizjak@gmail.com>
+ Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
+
+ PR target/40906
+ * config/i386/i386.c (ix86_split_long_move): Fix push of multi-part
+ source operand.
+
2009-08-05 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/40924
/* When emitting push, take care for source operands on the stack. */
if (push && MEM_P (operands[1])
&& reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
- for (i = 0; i < nparts - 1; i++)
- part[1][i] = change_address (part[1][i],
- GET_MODE (part[1][i]),
- XEXP (part[1][i + 1], 0));
+ {
+ rtx src_base = XEXP (part[1][nparts - 1], 0);
+
+ /* Compensate for the stack decrement by 4. */
+ if (!TARGET_64BIT && nparts == 3
+ && mode == XFmode && TARGET_128BIT_LONG_DOUBLE)
+ src_base = plus_constant (src_base, 4);
+
+ /* src_base refers to the stack pointer and is
+ automatically decreased by emitted push. */
+ for (i = 0; i < nparts; i++)
+ part[1][i] = change_address (part[1][i],
+ GET_MODE (part[1][i]), src_base);
+ }
/* We need to do copy in the right order in case an address register
of the source overlaps the destination. */
if (nparts == 3)
{
if (TARGET_128BIT_LONG_DOUBLE && mode == XFmode)
- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-4)));
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx, GEN_INT (-4)));
emit_move_insn (part[0][2], part[1][2]);
}
else if (nparts == 4)
+2009-08-05 Uros Bizjak <ubizjak@gmail.com>
+ Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
+
+ PR target/40906
+ * gcc.target/i386/pr40906-1.c: New test.
+ * gcc.target/i386/pr40906-2.c: Ditto.
+ * gcc.target/i386/pr40906-3.c: Ditto.
+
2009-08-05 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/40924