+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-04 Uros Bizjak <ubizjak@gmail.com>
Backport from mainline:
if (push && MEM_P (operands[1])
&& reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
{
- if (nparts == 3)
- part[1][1] = change_address (part[1][1], GET_MODE (part[1][1]),
- XEXP (part[1][2], 0));
- part[1][0] = change_address (part[1][0], GET_MODE (part[1][0]),
- XEXP (part[1][1], 0));
+ rtx src_base = XEXP (part[1][nparts - 1], 0);
+ int i;
+
+ /* 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
+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-04 Dodji Seketeli <dodji@redhat.com>
PR debug/39706
--- /dev/null
+/* { dg-do run } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -fomit-frame-pointer -mpush-args -mno-accumulate-outgoing-args" } */
+
+void abort (void);
+
+void __attribute__((noinline))
+f (long double a)
+{
+ if (a != 1.23L)
+ abort ();
+}
+
+int __attribute__((noinline))
+g (long double b)
+{
+ f (b);
+ return 0;
+}
+
+int
+main (void)
+{
+ g (1.23L);
+ return 0;
+}
--- /dev/null
+/* { dg-do run } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -fomit-frame-pointer -mpush-args -mno-accumulate-outgoing-args -m128bit-long-double" } */
+
+void abort (void);
+
+void __attribute__((noinline))
+f (long double a)
+{
+ if (a != 1.23L)
+ abort ();
+}
+
+int __attribute__((noinline))
+g (long double b)
+{
+ f (b);
+ return 0;
+}
+
+int
+main (void)
+{
+ g (1.23L);
+ return 0;
+}
--- /dev/null
+/* { dg-do run { target *-*-linux* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -fomit-frame-pointer -msse2 -mpush-args -mno-accumulate-outgoing-args" } */
+
+#include "sse2-check.h"
+
+void __attribute__((noinline))
+f (__float128 a)
+{
+ if (a != 1.23L)
+ abort ();
+}
+
+int __attribute__((noinline))
+g (__float128 b)
+{
+ f (b);
+ return 0;
+}
+
+static void
+sse2_test (void)
+{
+ g (1.23L);
+}