aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2005-07-06 11:16:53 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2005-07-06 11:16:53 +0200
commit5b667039e939f8f855fb06f617a6ade13e9b010d (patch)
treeb5e9eab605583ad47e9f746ca3871aa9749f131c /gcc
parentc456a94a49c9497da22209bb479c63487bb93c7c (diff)
downloadgcc-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/ChangeLog29
-rw-r--r--gcc/config/rs6000/darwin.h1
-rw-r--r--gcc/config/rs6000/rs6000.c114
-rw-r--r--gcc/config/rs6000/rs6000.h22
-rw-r--r--gcc/config/rs6000/sysv4.h7
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