function.c (assign_parm_remove_parallels): New.

* function.c (assign_parm_remove_parallels): New.
	(assign_parm_setup_block_p): Do not return true for non-BLKmode
	PARALLELs.
	(assign_parm_setup_block): Do not handle them.
	(assign_parm_setup_reg, assign_parm_setup_stack): Call
	assign_parm_remove_parallels.

From-SVN: r137326
This commit is contained in:
Daniel Jacobowitz 2008-07-01 20:49:40 +00:00 committed by Daniel Jacobowitz
parent f83c7f631f
commit 4d2a9850cf
2 changed files with 37 additions and 51 deletions

View file

@ -1,3 +1,12 @@
2008-07-01 Daniel Jacobowitz <dan@codesourcery.com>
* function.c (assign_parm_remove_parallels): New.
(assign_parm_setup_block_p): Do not return true for non-BLKmode
PARALLELs.
(assign_parm_setup_block): Do not handle them.
(assign_parm_setup_reg, assign_parm_setup_stack): Call
assign_parm_remove_parallels.
2008-07-01 Daniel Jacobowitz <dan@codesourcery.com>
* c-typeck.c (convert_for_assignment): Use

View file

@ -2352,6 +2352,30 @@ assign_parm_adjust_entry_rtl (struct assign_parm_data_one *data)
data->entry_parm = entry_parm;
}
/* A subroutine of assign_parms. Reconstitute any values which were
passed in multiple registers and would fit in a single register. */
static void
assign_parm_remove_parallels (struct assign_parm_data_one *data)
{
rtx entry_parm = data->entry_parm;
/* Convert the PARALLEL to a REG of the same mode as the parallel.
This can be done with register operations rather than on the
stack, even if we will store the reconstituted parameter on the
stack later. */
if (GET_CODE (entry_parm) == PARALLEL
&& data->passed_mode != BLKmode)
{
rtx parmreg = gen_reg_rtx (GET_MODE (entry_parm));
emit_group_store (parmreg, entry_parm, NULL_TREE,
GET_MODE_SIZE (GET_MODE (entry_parm)));
entry_parm = parmreg;
}
data->entry_parm = entry_parm;
}
/* A subroutine of assign_parms. Adjust DATA->STACK_RTL such that it's
always valid and properly aligned. */
@ -2397,8 +2421,6 @@ assign_parm_setup_block_p (struct assign_parm_data_one *data)
{
if (data->nominal_mode == BLKmode)
return true;
if (GET_CODE (data->entry_parm) == PARALLEL)
return true;
#ifdef BLOCK_REG_PADDING
/* Only assign_parm_setup_block knows how to deal with register arguments
@ -2424,59 +2446,10 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
rtx stack_parm = data->stack_parm;
HOST_WIDE_INT size;
HOST_WIDE_INT size_stored;
rtx orig_entry_parm = entry_parm;
if (GET_CODE (entry_parm) == PARALLEL)
entry_parm = emit_group_move_into_temps (entry_parm);
/* If we've a non-block object that's nevertheless passed in parts,
reconstitute it in register operations rather than on the stack. */
if (GET_CODE (entry_parm) == PARALLEL
&& data->nominal_mode != BLKmode)
{
rtx elt0 = XEXP (XVECEXP (orig_entry_parm, 0, 0), 0);
if ((XVECLEN (entry_parm, 0) > 1
|| hard_regno_nregs[REGNO (elt0)][GET_MODE (elt0)] > 1)
&& use_register_for_decl (parm))
{
rtx parmreg = gen_reg_rtx (data->nominal_mode);
push_to_sequence2 (all->first_conversion_insn,
all->last_conversion_insn);
/* For values returned in multiple registers, handle possible
incompatible calls to emit_group_store.
For example, the following would be invalid, and would have to
be fixed by the conditional below:
emit_group_store ((reg:SF), (parallel:DF))
emit_group_store ((reg:SI), (parallel:DI))
An example of this are doubles in e500 v2:
(parallel:DF (expr_list (reg:SI) (const_int 0))
(expr_list (reg:SI) (const_int 4))). */
if (data->nominal_mode != data->passed_mode)
{
rtx t = gen_reg_rtx (GET_MODE (entry_parm));
emit_group_store (t, entry_parm, NULL_TREE,
GET_MODE_SIZE (GET_MODE (entry_parm)));
convert_move (parmreg, t, 0);
}
else
emit_group_store (parmreg, entry_parm, data->nominal_type,
int_size_in_bytes (data->nominal_type));
all->first_conversion_insn = get_insns ();
all->last_conversion_insn = get_last_insn ();
end_sequence ();
SET_DECL_RTL (parm, parmreg);
return;
}
}
size = int_size_in_bytes (data->passed_type);
size_stored = CEIL_ROUND (size, UNITS_PER_WORD);
if (stack_parm == 0)
@ -2641,6 +2614,8 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
else
SET_DECL_RTL (parm, parmreg);
assign_parm_remove_parallels (data);
/* Copy the value into the register. */
if (data->nominal_mode != data->passed_mode
|| promoted_nominal_mode != data->promoted_mode)
@ -2803,6 +2778,8 @@ assign_parm_setup_stack (struct assign_parm_data_all *all, tree parm,
execution. */
bool to_conversion = false;
assign_parm_remove_parallels (data);
if (data->promoted_mode != data->nominal_mode)
{
/* Conversion is required. */