diff options
author | Eric Botcazou <ebotcazou@libertysurf.fr> | 2004-11-10 18:24:19 +0100 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2004-11-10 17:24:19 +0000 |
commit | 22d8d62798a3ce51a7e328805593bf675eddf60f (patch) | |
tree | 519d44fed7e51de0d70afcb9657d3224501a3194 /gcc | |
parent | d05f9c39a3a6e7d9a95de9c134d13c1a34f1c70d (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/union-2.c | 28 |
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; +} |