aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@libertysurf.fr>2004-11-10 18:24:19 +0100
committerEric Botcazou <ebotcazou@gcc.gnu.org>2004-11-10 17:24:19 +0000
commit22d8d62798a3ce51a7e328805593bf675eddf60f (patch)
tree519d44fed7e51de0d70afcb9657d3224501a3194 /gcc
parentd05f9c39a3a6e7d9a95de9c134d13c1a34f1c70d (diff)
downloadgcc-22d8d62798a3ce51a7e328805593bf675eddf60f.zip
gcc-22d8d62798a3ce51a7e328805593bf675eddf60f.tar.gz
gcc-22d8d62798a3ce51a7e328805593bf675eddf60f.tar.bz2
sparc.c (function_arg_union_value): New 'slotno' argument.
* config/sparc/sparc.c (function_arg_union_value): New 'slotno' argument. When the union is passed in the 6th slot, build a PARALLEL with only one element. (function_arg): Adjust call to function_arg_union_value. (function_value): Likewise. From-SVN: r90396
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/sparc/sparc.c14
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/union-2.c28
4 files changed, 49 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7d84272..23d6473 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2004-11-10 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_union_value): New 'slotno'
+ argument. When the union is passed in the 6th slot, build a
+ PARALLEL with only one element.
+ (function_arg): Adjust call to function_arg_union_value.
+ (function_value): Likewise.
+
2004-11-10 Fariborz Jahanian <fjahanian@apple.com>
PR tree-optimization/17892
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 0f34884..87e30d4 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -5241,7 +5241,7 @@ static void function_arg_record_value_2
static void function_arg_record_value_1
(tree, HOST_WIDE_INT, struct function_arg_record_value_parms *, bool);
static rtx function_arg_record_value (tree, enum machine_mode, int, int, int);
-static rtx function_arg_union_value (int, enum machine_mode, int);
+static rtx function_arg_union_value (int, enum machine_mode, int, int);
/* A subroutine of function_arg_record_value. Traverse the structure
recursively and determine how many registers will be required. */
@@ -5608,7 +5608,8 @@ function_arg_record_value (tree type, enum machine_mode mode,
REGNO is the hard register the union will be passed in. */
static rtx
-function_arg_union_value (int size, enum machine_mode mode, int regno)
+function_arg_union_value (int size, enum machine_mode mode, int slotno,
+ int regno)
{
int nwords = ROUND_ADVANCE (size), i;
rtx regs;
@@ -5617,6 +5618,9 @@ function_arg_union_value (int size, enum machine_mode mode, int regno)
if (nwords == 0)
return gen_rtx_REG (mode, regno);
+ if (slotno == SPARC_INT_ARG_MAX - 1)
+ nwords = 1;
+
regs = gen_rtx_PARALLEL (mode, rtvec_alloc (nwords));
for (i = 0; i < nwords; i++)
@@ -5717,7 +5721,7 @@ function_arg (const struct sparc_args *cum, enum machine_mode mode,
if (size > 16)
abort (); /* shouldn't get here */
- return function_arg_union_value (size, mode, regno);
+ return function_arg_union_value (size, mode, slotno, regno);
}
else if (type && TREE_CODE (type) == VECTOR_TYPE)
{
@@ -6107,7 +6111,7 @@ function_value (tree type, enum machine_mode mode, int incoming_p)
if (size > 32)
abort (); /* shouldn't get here */
- return function_arg_union_value (size, mode, regbase);
+ return function_arg_union_value (size, mode, 0, regbase);
}
else if (AGGREGATE_TYPE_P (type))
{
@@ -6130,7 +6134,7 @@ function_value (tree type, enum machine_mode mode, int incoming_p)
try to be unduly clever, and simply follow the ABI
for unions in that case. */
if (mode == BLKmode)
- return function_arg_union_value (bytes, mode, regbase);
+ return function_arg_union_value (bytes, mode, 0, regbase);
else
mclass = MODE_INT;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b87577d..0893277 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2004-11-10 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * gcc.dg/union-2.c: New test.
+
2004-11-10 Fariborz Jahanian <fjahanian@apple.com>
* gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.c:
diff --git a/gcc/testsuite/gcc.dg/union-2.c b/gcc/testsuite/gcc.dg/union-2.c
new file mode 100644
index 0000000..edc8a7a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/union-2.c
@@ -0,0 +1,28 @@
+/* This used to segfault on SPARC 64-bit at runtime because
+ the stack pointer was clobbered by the function call. */
+
+/* { dg-do run } */
+
+#include <stdarg.h>
+
+union U
+{
+ long l1[2];
+};
+
+union U u;
+
+void foo (int z, ...)
+{
+ int i;
+ va_list ap;
+ va_start(ap,z);
+ i = va_arg(ap, int);
+ va_end(ap);
+}
+
+int main(void)
+{
+ foo (1, 1, 1, 1, 1, u);
+ return 0;
+}