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
This commit is contained in:
Eric Botcazou 2004-11-10 18:24:19 +01:00 committed by Eric Botcazou
parent d05f9c39a3
commit 22d8d62798
4 changed files with 49 additions and 5 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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:

View File

@ -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;
}