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:
parent
d05f9c39a3
commit
22d8d62798
4 changed files with 49 additions and 5 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
28
gcc/testsuite/gcc.dg/union-2.c
Normal file
28
gcc/testsuite/gcc.dg/union-2.c
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue