re PR target/15783 (ICE with union assignment in 64-bit mode)
PR target/15783 * config/sparc/sparc.c (function_arg_union_value): Add 'mode' parameter. Enumerate the registers inside the PARALLEL. (function_arg): Adjust call to function_arg_union_value. (function_value): Likewise. From-SVN: r82722
This commit is contained in:
parent
67057c537b
commit
85bbb21f8f
4 changed files with 59 additions and 23 deletions
|
@ -1,3 +1,13 @@
|
|||
2004-06-07 Eric Botcazou <ebotcazou@libertysurf.fr>
|
||||
|
||||
PR target/15783
|
||||
* config/sparc/sparc.c (function_arg_union_value): Add 'mode'
|
||||
parameter. Enumerate the registers inside the PARALLEL.
|
||||
(function_arg): Adjust call to function_arg_union_value.
|
||||
(function_value): Likewise.
|
||||
|
||||
* config/sparc/sparc.c (sparc_function_epilogue): Properly format.
|
||||
|
||||
2004-06-07 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* real.c (real_copysign): New function to implement libm's copysign.
|
||||
|
|
|
@ -4514,12 +4514,12 @@ sparc_function_epilogue (FILE *file,
|
|||
This insn is used in the 32-bit ABI when calling a function that returns
|
||||
a non zero-sized structure. The 64-bit ABI doesn't have it. Be careful
|
||||
to have this test be the same as that used on the call. */
|
||||
sparc_skip_caller_unimp =
|
||||
! TARGET_ARCH64
|
||||
&& current_function_returns_struct
|
||||
&& (TREE_CODE (DECL_SIZE (DECL_RESULT (current_function_decl)))
|
||||
== INTEGER_CST)
|
||||
&& ! integer_zerop (DECL_SIZE (DECL_RESULT (current_function_decl)));
|
||||
sparc_skip_caller_unimp
|
||||
= ! TARGET_ARCH64
|
||||
&& current_function_returns_struct
|
||||
&& (TREE_CODE (DECL_SIZE (DECL_RESULT (current_function_decl)))
|
||||
== INTEGER_CST)
|
||||
&& ! integer_zerop (DECL_SIZE (DECL_RESULT (current_function_decl)));
|
||||
|
||||
if (current_function_epilogue_delay_list == 0)
|
||||
{
|
||||
|
@ -5129,7 +5129,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, int);
|
||||
static rtx function_arg_union_value (int, enum machine_mode, int);
|
||||
|
||||
/* A subroutine of function_arg_record_value. Traverse the structure
|
||||
recursively and determine how many registers will be required. */
|
||||
|
@ -5471,26 +5471,25 @@ function_arg_record_value (tree type, enum machine_mode mode,
|
|||
FUNCTION_ARG and FUNCTION_VALUE.
|
||||
|
||||
SIZE is the size in bytes of the union.
|
||||
MODE is the argument's machine mode.
|
||||
REGNO is the hard register the union will be passed in. */
|
||||
|
||||
static rtx
|
||||
function_arg_union_value (int size, int regno)
|
||||
function_arg_union_value (int size, enum machine_mode mode, int regno)
|
||||
{
|
||||
enum machine_mode mode;
|
||||
rtx reg;
|
||||
|
||||
if (size <= UNITS_PER_WORD)
|
||||
mode = word_mode;
|
||||
else
|
||||
mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
|
||||
|
||||
reg = gen_rtx_REG (mode, regno);
|
||||
int nwords = ROUND_ADVANCE (size), i;
|
||||
rtx regs;
|
||||
|
||||
/* Unions are passed left-justified. */
|
||||
return gen_rtx_PARALLEL (mode,
|
||||
gen_rtvec (1, gen_rtx_EXPR_LIST (VOIDmode,
|
||||
reg,
|
||||
const0_rtx)));
|
||||
regs = gen_rtx_PARALLEL (mode, rtvec_alloc (nwords));
|
||||
|
||||
for (i = 0; i < nwords; i++)
|
||||
XVECEXP (regs, 0, i)
|
||||
= gen_rtx_EXPR_LIST (VOIDmode,
|
||||
gen_rtx_REG (word_mode, regno + i),
|
||||
GEN_INT (UNITS_PER_WORD * i));
|
||||
|
||||
return regs;
|
||||
}
|
||||
|
||||
/* Handle the FUNCTION_ARG macro.
|
||||
|
@ -5547,7 +5546,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, regno);
|
||||
return function_arg_union_value (size, mode, regno);
|
||||
}
|
||||
/* v9 fp args in reg slots beyond the int reg slots get passed in regs
|
||||
but also have the slot allocated for them.
|
||||
|
@ -5872,7 +5871,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, regbase);
|
||||
return function_arg_union_value (size, mode, regbase);
|
||||
}
|
||||
else if (AGGREGATE_TYPE_P (type))
|
||||
{
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2004-06-07 Eric Botcazou <ebotcazou@libertysurf.fr>
|
||||
|
||||
* gcc.dg/union-1.c: New test.
|
||||
|
||||
2004-06-07 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* gcc.dg/builtins-41.c: New test case.
|
||||
|
@ -22718,3 +22722,4 @@ rlsruhe.de>
|
|||
correspond to c-torture 1.11.
|
||||
|
||||
* New file.
|
||||
|
||||
|
|
22
gcc/testsuite/gcc.dg/union-1.c
Normal file
22
gcc/testsuite/gcc.dg/union-1.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* PR target/15783 */
|
||||
/* Origin: Paul Pluzhnikov <ppluzhnikov@charter.net> */
|
||||
|
||||
/* This used to ICE on SPARC 64-bit because the back-end was
|
||||
returning an invalid construct for the return value of fu2. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
union u2 {
|
||||
struct
|
||||
{
|
||||
int u2s_a, u2s_b, u2s_c, u2s_d, u2s_e;
|
||||
} u2_s;
|
||||
double u2_d;
|
||||
} u2a;
|
||||
|
||||
union u2 fu2();
|
||||
|
||||
void unions()
|
||||
{
|
||||
u2a = fu2();
|
||||
}
|
Loading…
Add table
Reference in a new issue