+2000-03-02 Jason Merrill <jason@casey.cygnus.com>
+
+ * function.h (struct expr_status): Add x_arg_space_so_far.
+ (arg_space_so_far): New macro.
+ * expr.c (init_expr): Initialize it.
+ * calls.c (emit_call_1): Reset it.
+ (compute_argument_block_size, expand_call): Use it.
+ (expand_call, store_one_arg): Increment it.
+
Thu Mar 2 17:27:13 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* varasm.c (output_constant): Strip off a CONVERT_EXPR to
says that the pointer to this aggregate is to be popped by the callee.
STACK_SIZE is the number of bytes of arguments on the stack,
- rounded up to PREFERRED_STACK_BOUNDARY; zero if the size is variable.
- This is both to put into the call insn and
- to generate explicit popping code if necessary.
+ ROUNDED_STACK_SIZE is that number rounded up to
+ PREFERRED_STACK_BOUNDARY; zero if the size is variable. This is
+ both to put into the call insn and to generate explicit popping
+ code if necessary.
STRUCT_VALUE_SIZE is the number of bytes wanted in a structure value.
It is zero if this call doesn't want a structure value.
If returning from the subroutine does pop the args, indicate that the
stack pointer will be changed. */
+ /* The space for the args is no longer waiting for the call; either it
+ was popped by the call, or it'll be popped below. */
+ arg_space_so_far -= rounded_stack_size;
+
if (n_popped > 0)
{
if (!already_popped)
#ifdef PREFERRED_STACK_BOUNDARY
preferred_stack_boundary /= BITS_PER_UNIT;
args_size->constant = (((args_size->constant
+ + arg_space_so_far
+ pending_stack_adjust
+ preferred_stack_boundary - 1)
/ preferred_stack_boundary
* preferred_stack_boundary)
+ - arg_space_so_far
- pending_stack_adjust);
#endif
{
args_size.constant = (unadjusted_args_size
+ ((pending_stack_adjust + args_size.constant
+ + arg_space_so_far
- unadjusted_args_size)
% (preferred_stack_boundary / BITS_PER_UNIT)));
pending_stack_adjust -= args_size.constant - unadjusted_args_size;
}
else if (argblock == 0)
anti_adjust_stack (GEN_INT (args_size.constant - unadjusted_args_size));
+ arg_space_so_far += args_size.constant - unadjusted_args_size;
+
+ /* Now that the stack is properly aligned, pops can't safely
+ be deferred during the evaluation of the arguments. */
+ NO_DEFER_POP;
}
#endif
#endif
ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
ARGS_SIZE_RTX (arg->alignment_pad));
+ arg_space_so_far += used;
}
else
{
excess = (arg->size.constant - int_size_in_bytes (TREE_TYPE (pval))
+ partial * UNITS_PER_WORD);
size_rtx = expr_size (pval);
+ arg_space_so_far += excess + INTVAL (size_rtx);
}
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
These are the arguments to function calls that have already returned. */
int x_pending_stack_adjust;
+ /* Number of units that we should eventually pop off the stack.
+ These are the arguments to function calls that have not happened yet. */
+ int x_arg_space_so_far;
+
/* Under some ABIs, it is the caller's responsibility to pop arguments
pushed for function calls. A naive implementation would simply pop
the arguments immediately after each call. However, if several
};
#define pending_stack_adjust (cfun->expr->x_pending_stack_adjust)
+#define arg_space_so_far (cfun->expr->x_arg_space_so_far)
#define inhibit_defer_pop (cfun->expr->x_inhibit_defer_pop)
#define saveregs_value (cfun->expr->x_saveregs_value)
#define apply_args_value (cfun->expr->x_apply_args_value)