diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-07-06 11:16:53 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-07-06 11:16:53 +0200 |
commit | 5b667039e939f8f855fb06f617a6ade13e9b010d (patch) | |
tree | b5e9eab605583ad47e9f746ca3871aa9749f131c /gcc | |
parent | c456a94a49c9497da22209bb479c63487bb93c7c (diff) | |
download | gcc-5b667039e939f8f855fb06f617a6ade13e9b010d.zip gcc-5b667039e939f8f855fb06f617a6ade13e9b010d.tar.gz gcc-5b667039e939f8f855fb06f617a6ade13e9b010d.tar.bz2 |
rs6000.h (RS6000_VARARGS_AREA, [...]): Remove.
* config/rs6000/rs6000.h (RS6000_VARARGS_AREA, RS6000_VARARGS_SIZE):
Remove.
(STARTING_FRAME_OFFSET): Don't add RS6000_VARARGS_AREA.
(machine_function): Move typedef to...
* config/rs6000/rs6000.c (machine_function): ... here. Add
varargs_save_offset field.
(rs6000_stack_t): Remove varargs_size field.
(setup_incoming_varargs): Allocate varargs save area using
assign_stack_local, try to make it as small as possible.
Save offset from virtual_stack_vars_rtx to the save area
in cfun->machine->varargs_save_offset. Use UNITS_PER_FP_WORD
instead of magic 8 when fp word byte size is used.
(rs6000_va_start): Use cfun->machine->varargs_save_offset
instead of -RS6000_VARARGS_SIZE.
(rs6000_stack_info, debug_stack_info,
rs6000_initial_elimination_offset): Remove all traces of
varargs_size.
* config/rs6000/sysv4.h (RS6000_VARARGS_AREA): Remove.
* config/rs6000/darwin.h (STARTING_FRAME_OFFSET): Don't add
RS6000_VARARGS_AREA.
From-SVN: r101655
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 29 | ||||
-rw-r--r-- | gcc/config/rs6000/darwin.h | 1 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 114 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 22 | ||||
-rw-r--r-- | gcc/config/rs6000/sysv4.h | 7 |
5 files changed, 118 insertions, 55 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a85f3d1..d25480b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2005-07-06 Jakub Jelinek <jakub@redhat.com> + + * config/rs6000/rs6000.h (RS6000_VARARGS_AREA, RS6000_VARARGS_SIZE): + Remove. + (STARTING_FRAME_OFFSET): Don't add RS6000_VARARGS_AREA. + (machine_function): Move typedef to... + * config/rs6000/rs6000.c (machine_function): ... here. Add + varargs_save_offset field. + (rs6000_stack_t): Remove varargs_size field. + (setup_incoming_varargs): Allocate varargs save area using + assign_stack_local, try to make it as small as possible. + Save offset from virtual_stack_vars_rtx to the save area + in cfun->machine->varargs_save_offset. Use UNITS_PER_FP_WORD + instead of magic 8 when fp word byte size is used. + (rs6000_va_start): Use cfun->machine->varargs_save_offset + instead of -RS6000_VARARGS_SIZE. + (rs6000_stack_info, debug_stack_info, + rs6000_initial_elimination_offset): Remove all traces of + varargs_size. + * config/rs6000/sysv4.h (RS6000_VARARGS_AREA): Remove. + * config/rs6000/darwin.h (STARTING_FRAME_OFFSET): Don't add + RS6000_VARARGS_AREA. + 2005-07-06 Zdenek Dvorak <dvorakz@suse.cz> PR tree-optimization/21963 @@ -467,9 +490,9 @@ 2005-07-02 Richard Henderson <rth@redhat.com> - * config/alpha/alpha.c (alpha_legitimize_address): Check for - TLS_MODEL_NONE. - (alpha_stdarg_optimize_hook): Use DECL_UID with va_list_vars. + * config/alpha/alpha.c (alpha_legitimize_address): Check for + TLS_MODEL_NONE. + (alpha_stdarg_optimize_hook): Use DECL_UID with va_list_vars. 2005-07-02 Andrew Pinski <pinskia@physics.uc.edu> diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h index 7edee27..72ec64b 100644 --- a/gcc/config/rs6000/darwin.h +++ b/gcc/config/rs6000/darwin.h @@ -164,7 +164,6 @@ do { \ (FRAME_GROWS_DOWNWARD \ ? 0 \ : (RS6000_ALIGN (current_function_outgoing_args_size, 16) \ - + RS6000_VARARGS_AREA \ + RS6000_SAVE_AREA)) #undef STACK_DYNAMIC_OFFSET diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 0472169..fb5f3ae 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -93,7 +93,6 @@ typedef struct rs6000_stack { int varargs_save_offset; /* offset to save the varargs registers */ int ehrd_offset; /* offset to EH return data */ int reg_size; /* register size (4 or 8) */ - int varargs_size; /* size to hold V.4 args passed in regs */ HOST_WIDE_INT vars_size; /* variable save area size */ int parm_size; /* outgoing parameter size */ int save_size; /* save area size */ @@ -113,6 +112,23 @@ typedef struct rs6000_stack { int spe_64bit_regs_used; } rs6000_stack_t; +/* A C structure for machine-specific, per-function data. + This is added to the cfun structure. */ +typedef struct machine_function GTY(()) +{ + /* Flags if __builtin_return_address (n) with n >= 1 was used. */ + int ra_needs_full_frame; + /* Some local-dynamic symbol. */ + const char *some_ld_name; + /* Whether the instruction chain has been scanned already. */ + int insn_chain_scanned_p; + /* Flags if __builtin_return_address (0) was used. */ + int ra_need_lr; + /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4 + varargs save area. */ + HOST_WIDE_INT varargs_save_offset; +} machine_function; + /* Target cpu type */ enum processor_type rs6000_cpu; @@ -5218,11 +5234,70 @@ setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, if (DEFAULT_ABI == ABI_V4) { + first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG; + if (! no_rtl) - save_area = plus_constant (virtual_stack_vars_rtx, - - RS6000_VARARGS_SIZE); + { + int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0; + HOST_WIDE_INT offset = 0; + + /* Try to optimize the size of the varargs save area. + The ABI requires that ap.reg_save_area is doubleword + aligned, but we don't need to allocate space for all + the bytes, only those to which we actually will save + anything. */ + if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG) + gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset; + if (TARGET_HARD_FLOAT && TARGET_FPRS + && next_cum.fregno <= FP_ARG_V4_MAX_REG + && cfun->va_list_fpr_size) + { + if (gpr_reg_num) + fpr_size = (next_cum.fregno - FP_ARG_MIN_REG) + * UNITS_PER_FP_WORD; + if (cfun->va_list_fpr_size + < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno) + fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD; + else + fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno) + * UNITS_PER_FP_WORD; + } + if (gpr_reg_num) + { + offset = -((first_reg_offset * reg_size) & ~7); + if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size) + { + gpr_reg_num = cfun->va_list_gpr_size; + if (reg_size == 4 && (first_reg_offset & 1)) + gpr_reg_num++; + } + gpr_size = (gpr_reg_num * reg_size + 7) & ~7; + } + else if (fpr_size) + offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG) + * UNITS_PER_FP_WORD + - (int) (GP_ARG_NUM_REG * reg_size); - first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG; + if (gpr_size + fpr_size) + { + rtx reg_save_area + = assign_stack_local (BLKmode, gpr_size + fpr_size, 64); + gcc_assert (GET_CODE (reg_save_area) == MEM); + reg_save_area = XEXP (reg_save_area, 0); + if (GET_CODE (reg_save_area) == PLUS) + { + gcc_assert (XEXP (reg_save_area, 0) + == virtual_stack_vars_rtx); + gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT); + offset += INTVAL (XEXP (reg_save_area, 1)); + } + else + gcc_assert (reg_save_area == virtual_stack_vars_rtx); + } + + cfun->machine->varargs_save_offset = offset; + save_area = plus_constant (virtual_stack_vars_rtx, offset); + } } else { @@ -5272,7 +5347,8 @@ setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, int fregno = next_cum.fregno, nregs; rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO); rtx lab = gen_label_rtx (); - int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8); + int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) + * UNITS_PER_FP_WORD); emit_jump_insn (gen_rtx_SET (VOIDmode, @@ -5285,7 +5361,7 @@ setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, for (nregs = 0; fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size; - fregno++, off += 8, nregs++) + fregno++, off += UNITS_PER_FP_WORD, nregs++) { mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off)); set_mem_alias_set (mem, set); @@ -5423,8 +5499,9 @@ rs6000_va_start (tree valist, rtx nextarg) /* Find the register save area. */ t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx); - t = build (PLUS_EXPR, TREE_TYPE (sav), t, - build_int_cst (NULL_TREE, -RS6000_VARARGS_SIZE)); + if (cfun->machine->varargs_save_offset) + t = build (PLUS_EXPR, TREE_TYPE (sav), t, + build_int_cst (NULL_TREE, cfun->machine->varargs_save_offset)); t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t); TREE_SIDE_EFFECTS (t) = 1; expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); @@ -12116,17 +12193,16 @@ rs6000_stack_info (void) /* Determine various sizes. */ info_ptr->reg_size = reg_size; info_ptr->fixed_size = RS6000_SAVE_AREA; - info_ptr->varargs_size = RS6000_VARARGS_AREA; info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8); info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size, TARGET_ALTIVEC ? 16 : 8); if (FRAME_GROWS_DOWNWARD) info_ptr->vars_size - += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->varargs_size - + info_ptr->vars_size + info_ptr->parm_size, + += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size + + info_ptr->parm_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT) - - (info_ptr->fixed_size + info_ptr->varargs_size - + info_ptr->vars_size + info_ptr->parm_size); + - (info_ptr->fixed_size + info_ptr->vars_size + + info_ptr->parm_size); if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0) info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save); @@ -12251,8 +12327,7 @@ rs6000_stack_info (void) non_fixed_size = (info_ptr->vars_size + info_ptr->parm_size - + info_ptr->save_size - + info_ptr->varargs_size); + + info_ptr->save_size); info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT); @@ -12452,9 +12527,6 @@ debug_stack_info (rs6000_stack_t *info) fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n", info->total_size); - if (info->varargs_size) - fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size); - if (info->vars_size) fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n", info->vars_size); @@ -18261,13 +18333,11 @@ rs6000_initial_elimination_offset (int from, int to) { offset = info->push_p ? 0 : -info->total_size; if (FRAME_GROWS_DOWNWARD) - offset += info->fixed_size + info->varargs_size - + info->vars_size + info->parm_size; + offset += info->fixed_size + info->vars_size + info->parm_size; } else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) offset = FRAME_GROWS_DOWNWARD - ? info->fixed_size + info->varargs_size - + info->vars_size + info->parm_size + ? info->fixed_size + info->vars_size + info->parm_size : 0; else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) offset = info->total_size; diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index f615c8d..269d5bb0 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1251,16 +1251,9 @@ extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */ plus_constant (stack_pointer_rtx, \ (TARGET_32BIT ? 20 : 40))) -/* Size of the V.4 varargs area if needed */ -#define RS6000_VARARGS_AREA 0 - /* Align an address */ #define RS6000_ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1)) -/* Size of V.4 varargs area in bytes */ -#define RS6000_VARARGS_SIZE \ - ((GP_ARG_NUM_REG * (TARGET_32BIT ? 4 : 8)) + (FP_ARG_NUM_REG * 8) + 8) - /* Offset within stack frame to start allocating local variables at. If FRAME_GROWS_DOWNWARD, this is the offset to the END of the first local allocated. Otherwise, it is the offset to the BEGINNING @@ -1275,7 +1268,6 @@ extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */ ? 0 \ : (RS6000_ALIGN (current_function_outgoing_args_size, \ TARGET_ALTIVEC ? 16 : 8) \ - + RS6000_VARARGS_AREA \ + RS6000_SAVE_AREA)) /* Offset from the stack pointer register to an item dynamically @@ -1413,20 +1405,6 @@ extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */ || ((unsigned) (N) - FP_ARG_MIN_REG < FP_ARG_NUM_REG \ && TARGET_HARD_FLOAT && TARGET_FPRS)) -/* A C structure for machine-specific, per-function data. - This is added to the cfun structure. */ -typedef struct machine_function GTY(()) -{ - /* Flags if __builtin_return_address (n) with n >= 1 was used. */ - int ra_needs_full_frame; - /* Some local-dynamic symbol. */ - const char *some_ld_name; - /* Whether the instruction chain has been scanned already. */ - int insn_chain_scanned_p; - /* Flags if __builtin_return_address (0) was used. */ - int ra_need_lr; -} machine_function; - /* Define a data type for recording info about an argument list during the scan of that argument list. This data type should hold all necessary information about the function itself diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h index c95c952..2d5b6e8 100644 --- a/gcc/config/rs6000/sysv4.h +++ b/gcc/config/rs6000/sysv4.h @@ -249,13 +249,6 @@ do { \ so it is not available to the normal user. */ #define FIXED_R13 1 -/* Size of the V.4 varargs area if needed. */ -/* Override rs6000.h definition. */ -#undef RS6000_VARARGS_AREA -#define RS6000_VARARGS_AREA \ - ((DEFAULT_ABI == ABI_V4 && current_function_stdarg) \ - ? RS6000_VARARGS_SIZE : 0) - /* Override default big endianism definitions in rs6000.h. */ #undef BYTES_BIG_ENDIAN #undef WORDS_BIG_ENDIAN |