From 4d2a9850cf9af014fd058118ecc8eafa72456f30 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Tue, 1 Jul 2008 20:49:40 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 9 ++++++ gcc/function.c | 79 ++++++++++++++++++-------------------------------- 2 files changed, 37 insertions(+), 51 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1e258ac1739..01ed439fdcf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2008-07-01 Daniel Jacobowitz + + * 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 * c-typeck.c (convert_for_assignment): Use diff --git a/gcc/function.c b/gcc/function.c index 680b3604859..d8234da3877 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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. */ -- 2.30.2