diff options
author | Jason Merrill <jason@casey.cygnus.com> | 2000-03-02 23:50:11 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2000-03-02 18:50:11 -0500 |
commit | c2732da3bbdf6c723f562783fe383649f3f133e9 (patch) | |
tree | f69a6f6136385e1d2c8f5c79cf8274209b73b798 | |
parent | 16214ee327ce67a984cb98816fb1230ccca232ac (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/calls.c | 21 | ||||
-rw-r--r-- | gcc/expr.c | 1 | ||||
-rw-r--r-- | gcc/function.h | 5 |
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, @@ -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) |