Commit 85bbb21f by Eric Botcazou Committed by Eric Botcazou

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
parent 67057c53
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> 2004-06-07 Roger Sayle <roger@eyesopen.com>
* real.c (real_copysign): New function to implement libm's copysign. * real.c (real_copysign): New function to implement libm's copysign.
......
...@@ -4514,12 +4514,12 @@ sparc_function_epilogue (FILE *file, ...@@ -4514,12 +4514,12 @@ sparc_function_epilogue (FILE *file,
This insn is used in the 32-bit ABI when calling a function that returns 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 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. */ to have this test be the same as that used on the call. */
sparc_skip_caller_unimp = sparc_skip_caller_unimp
! TARGET_ARCH64 = ! TARGET_ARCH64
&& current_function_returns_struct && current_function_returns_struct
&& (TREE_CODE (DECL_SIZE (DECL_RESULT (current_function_decl))) && (TREE_CODE (DECL_SIZE (DECL_RESULT (current_function_decl)))
== INTEGER_CST) == INTEGER_CST)
&& ! integer_zerop (DECL_SIZE (DECL_RESULT (current_function_decl))); && ! integer_zerop (DECL_SIZE (DECL_RESULT (current_function_decl)));
if (current_function_epilogue_delay_list == 0) if (current_function_epilogue_delay_list == 0)
{ {
...@@ -5129,7 +5129,7 @@ static void function_arg_record_value_2 ...@@ -5129,7 +5129,7 @@ static void function_arg_record_value_2
static void function_arg_record_value_1 static void function_arg_record_value_1
(tree, HOST_WIDE_INT, struct function_arg_record_value_parms *, bool); (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_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 /* A subroutine of function_arg_record_value. Traverse the structure
recursively and determine how many registers will be required. */ recursively and determine how many registers will be required. */
...@@ -5471,26 +5471,25 @@ function_arg_record_value (tree type, enum machine_mode mode, ...@@ -5471,26 +5471,25 @@ function_arg_record_value (tree type, enum machine_mode mode,
FUNCTION_ARG and FUNCTION_VALUE. FUNCTION_ARG and FUNCTION_VALUE.
SIZE is the size in bytes of the union. 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. */ REGNO is the hard register the union will be passed in. */
static rtx 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; int nwords = ROUND_ADVANCE (size), i;
rtx reg; rtx regs;
if (size <= UNITS_PER_WORD) /* Unions are passed left-justified. */
mode = word_mode; regs = gen_rtx_PARALLEL (mode, rtvec_alloc (nwords));
else
mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
reg = gen_rtx_REG (mode, regno); 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));
/* Unions are passed left-justified. */ return regs;
return gen_rtx_PARALLEL (mode,
gen_rtvec (1, gen_rtx_EXPR_LIST (VOIDmode,
reg,
const0_rtx)));
} }
/* Handle the FUNCTION_ARG macro. /* Handle the FUNCTION_ARG macro.
...@@ -5547,7 +5546,7 @@ function_arg (const struct sparc_args *cum, enum machine_mode mode, ...@@ -5547,7 +5546,7 @@ function_arg (const struct sparc_args *cum, enum machine_mode mode,
if (size > 16) if (size > 16)
abort (); /* shouldn't get here */ 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 /* v9 fp args in reg slots beyond the int reg slots get passed in regs
but also have the slot allocated for them. but also have the slot allocated for them.
...@@ -5872,7 +5871,7 @@ function_value (tree type, enum machine_mode mode, int incoming_p) ...@@ -5872,7 +5871,7 @@ function_value (tree type, enum machine_mode mode, int incoming_p)
if (size > 32) if (size > 32)
abort (); /* shouldn't get here */ 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)) else if (AGGREGATE_TYPE_P (type))
{ {
......
2004-06-07 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.dg/union-1.c: New test.
2004-06-07 Roger Sayle <roger@eyesopen.com> 2004-06-07 Roger Sayle <roger@eyesopen.com>
* gcc.dg/builtins-41.c: New test case. * gcc.dg/builtins-41.c: New test case.
...@@ -22718,3 +22722,4 @@ rlsruhe.de> ...@@ -22718,3 +22722,4 @@ rlsruhe.de>
correspond to c-torture 1.11. correspond to c-torture 1.11.
* New file. * New file.
/* 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();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment