aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@casey.cygnus.com>2000-03-02 23:50:11 +0000
committerJason Merrill <jason@gcc.gnu.org>2000-03-02 18:50:11 -0500
commitc2732da3bbdf6c723f562783fe383649f3f133e9 (patch)
treef69a6f6136385e1d2c8f5c79cf8274209b73b798
parent16214ee327ce67a984cb98816fb1230ccca232ac (diff)
downloadgcc-c2732da3bbdf6c723f562783fe383649f3f133e9.zip
gcc-c2732da3bbdf6c723f562783fe383649f3f133e9.tar.gz
gcc-c2732da3bbdf6c723f562783fe383649f3f133e9.tar.bz2
function.h (struct expr_status): Add x_arg_space_so_far.
* 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. From-SVN: r32296
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/calls.c21
-rw-r--r--gcc/expr.c1
-rw-r--r--gcc/function.h5
4 files changed, 33 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 04824c6..d8b64b4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+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
diff --git a/gcc/calls.c b/gcc/calls.c
index 3d78c8b..4ff988a 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -352,9 +352,10 @@ prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen)
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.
@@ -502,6 +503,10 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
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)
@@ -1219,10 +1224,12 @@ compute_argument_block_size (reg_parm_stack_space, args_size,
#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
@@ -2285,6 +2292,7 @@ expand_call (exp, target, ignore)
{
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;
@@ -2292,6 +2300,11 @@ expand_call (exp, target, ignore)
}
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
@@ -4061,6 +4074,7 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
ARGS_SIZE_RTX (arg->alignment_pad));
+ arg_space_so_far += used;
}
else
{
@@ -4088,6 +4102,7 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
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,
diff --git a/gcc/expr.c b/gcc/expr.c
index 4d777f9..b0d1e07 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -288,6 +288,7 @@ init_expr ()
pending_chain = 0;
pending_stack_adjust = 0;
+ arg_space_so_far = 0;
inhibit_defer_pop = 0;
saveregs_value = 0;
apply_args_value = 0;
diff --git a/gcc/function.h b/gcc/function.h
index fb3ef49..9ede7a7 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -130,6 +130,10 @@ struct expr_status
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
@@ -163,6 +167,7 @@ struct expr_status
};
#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)