aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-12-27 09:31:54 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2007-12-27 09:31:54 +0100
commit22ccaaeea70de15c24476b4a6828bfbcff6bfea9 (patch)
tree6266007d280b8018d3b7a82c90f432b944d112df
parente2925ff2109fb38c43030bc610f47e6ab7115486 (diff)
downloadgcc-22ccaaeea70de15c24476b4a6828bfbcff6bfea9.zip
gcc-22ccaaeea70de15c24476b4a6828bfbcff6bfea9.tar.gz
gcc-22ccaaeea70de15c24476b4a6828bfbcff6bfea9.tar.bz2
re PR target/34281 (ARM: varargs broken with 64bit parameters.)
PR target/34281 * config/arm/arm.c (arm_setup_incoming_varargs): If last named argument needs double word alignment and cum->nregs is odd, account for the inserted padding. * gcc.c-torture/execute/20071213-1.c: New test. From-SVN: r131196
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/arm/arm.c14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20071213-1.c53
4 files changed, 73 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c3dc952..996e715 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2007-12-27 Jakub Jelinek <jakub@redhat.com>
+ PR target/34281
+ * config/arm/arm.c (arm_setup_incoming_varargs): If last named
+ argument needs double word alignment and cum->nregs is odd, account
+ for the inserted padding.
+
PR debug/34535
* tree-mudflap.c (mf_make_builtin): Make decl artificial
and don't emit debug info for it.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 5b3b703..ea9719a 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -17765,14 +17765,20 @@ arm_output_load_gr (rtx *operands)
static void
arm_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- tree type ATTRIBUTE_UNUSED,
+ enum machine_mode mode,
+ tree type,
int *pretend_size,
int second_time ATTRIBUTE_UNUSED)
{
+ int nregs = cum->nregs;
+ if (nregs & 1
+ && ARM_DOUBLEWORD_ALIGN
+ && arm_needs_doubleword_align (mode, type))
+ nregs++;
+
cfun->machine->uses_anonymous_args = 1;
- if (cum->nregs < NUM_ARG_REGS)
- *pretend_size = (NUM_ARG_REGS - cum->nregs) * UNITS_PER_WORD;
+ if (nregs < NUM_ARG_REGS)
+ *pretend_size = (NUM_ARG_REGS - nregs) * UNITS_PER_WORD;
}
/* Return nonzero if the CONSUMER instruction (a store) does not need
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2374f35..6f3fc35 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-12-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/34281
+ * gcc.c-torture/execute/20071213-1.c: New test.
+
2007-12-25 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libfortran/34560
diff --git a/gcc/testsuite/gcc.c-torture/execute/20071213-1.c b/gcc/testsuite/gcc.c-torture/execute/20071213-1.c
new file mode 100644
index 0000000..cbdfaa5
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20071213-1.c
@@ -0,0 +1,53 @@
+/* PR target/34281 */
+
+#include <stdarg.h>
+
+extern void abort (void);
+
+void
+h (int x, va_list ap)
+{
+ switch (x)
+ {
+ case 1:
+ if (va_arg (ap, int) != 3 || va_arg (ap, int) != 4)
+ abort ();
+ return;
+ case 5:
+ if (va_arg (ap, int) != 9 || va_arg (ap, int) != 10)
+ abort ();
+ return;
+ default:
+ abort ();
+ }
+}
+
+void
+f1 (int i, long long int j, ...)
+{
+ va_list ap;
+ va_start (ap, j);
+ h (i, ap);
+ if (i != 1 || j != 2)
+ abort ();
+ va_end (ap);
+}
+
+void
+f2 (int i, int j, int k, long long int l, ...)
+{
+ va_list ap;
+ va_start (ap, l);
+ h (i, ap);
+ if (i != 5 || j != 6 || k != 7 || l != 8)
+ abort ();
+ va_end (ap);
+}
+
+int
+main ()
+{
+ f1 (1, 2, 3, 4);
+ f2 (5, 6, 7, 8, 9, 10);
+ return 0;
+}