From bfbf933af83d1520667a3f05e7c6e0521645c06b Mon Sep 17 00:00:00 2001 From: Richard Stallman Date: Tue, 2 Jun 1992 01:41:11 +0000 Subject: [PATCH] *** empty log message *** From-SVN: r1135 --- gcc/calls.c | 89 ++++++++++++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/gcc/calls.c b/gcc/calls.c index 02f60ca867c..310bc4a5585 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1208,22 +1208,11 @@ expand_call (exp, target, ignore) highest_outgoing_arg_in_use - initial_highest_arg_in_use); needed = 0; - /* The only way the stack pointer can change here is if some arguments - which are passed in memory are constructed in place in the outgoing - argument area. All objects which are constructed in place have - pass_on_stack == 1 (see store_one_arg ()). - - The test for arguments being constructed on the stack is just an - optimization: it would be correct but suboptimal to call - copy_addr_to_reg () unconditionally. */ + /* The address of the outgoing argument list must not be copied to a + register here, because argblock would be left pointing to the + wrong place after the call to allocate_dynamic_stack_space below. */ argblock = virtual_outgoing_args_rtx; - for (i = 0; i < num_actuals; i++) - if (args[i].pass_on_stack) - { - argblock = copy_addr_to_reg (argblock); - break; - } #else /* not ACCUMULATE_OUTGOING_ARGS */ if (inhibit_defer_pop == 0) @@ -1258,6 +1247,47 @@ expand_call (exp, target, ignore) #endif /* not ACCUMULATE_OUTGOING_ARGS */ } + +#ifdef ACCUMULATE_OUTGOING_ARGS + /* The save/restore code in store_one_arg handles all cases except one: + a constructor call (including a C function returning a BLKmode struct) + to initialize an argument. */ + if (stack_arg_under_construction) + { +#if defined(REG_PARM_STACK_SPACE) && ! defined(OUTGOING_REG_PARM_STACK_SPACE) + rtx push_size = gen_rtx (CONST_INT, VOIDmode, + reg_parm_stack_space + args_size.constant); +#else + rtx push_size = gen_rtx (CONST_INT, VOIDmode, args_size.constant); +#endif + if (old_stack_level == 0) + { + emit_stack_save (SAVE_BLOCK, &old_stack_level, 0); + old_pending_adj = pending_stack_adjust; + pending_stack_adjust = 0; + /* stack_arg_under_construction says whether a stack arg is + being constructed at the old stack level. Pushing the stack + gets a clean outgoing argument block. */ + old_stack_arg_under_construction = stack_arg_under_construction; + stack_arg_under_construction = 0; + /* Make a new map for the new argument list. */ + stack_usage_map = (char *)alloca (highest_outgoing_arg_in_use); + bzero (stack_usage_map, highest_outgoing_arg_in_use); + highest_outgoing_arg_in_use = 0; + } + allocate_dynamic_stack_space (push_size, 0, BITS_PER_UNIT); + } + /* If argument evaluation might modify the stack pointer, copy the + address of the argument list to a register. */ + for (i = 0; i < num_actuals; i++) + if (args[i].pass_on_stack) + { + argblock = copy_addr_to_reg (argblock); + break; + } +#endif + + /* If we preallocated stack space, compute the address of each argument. We need not ensure it is a valid memory address here; it will be validized when it is used. */ @@ -1310,37 +1340,6 @@ expand_call (exp, target, ignore) #endif #endif -#ifdef ACCUMULATE_OUTGOING_ARGS - /* The save/restore code in store_one_arg handles all cases except one: - a constructor call (including a C function returning a BLKmode struct) - to initialize an argument. */ - if (stack_arg_under_construction) - { -#if defined(REG_PARM_STACK_SPACE) && ! defined(OUTGOING_REG_PARM_STACK_SPACE) - rtx push_size = gen_rtx (CONST_INT, VOIDmode, - reg_parm_stack_space + args_size.constant); -#else - rtx push_size = gen_rtx (CONST_INT, VOIDmode, args_size.constant); -#endif - if (old_stack_level == 0) - { - emit_stack_save (SAVE_BLOCK, &old_stack_level, 0); - old_pending_adj = pending_stack_adjust; - pending_stack_adjust = 0; - /* stack_arg_under_construction says whether a stack arg is - being constructed at the old stack level. Pushing the stack - gets a clean outgoing argument block. */ - old_stack_arg_under_construction = stack_arg_under_construction; - stack_arg_under_construction = 0; - /* Make a new map for the new argument list. */ - stack_usage_map = (char *)alloca (highest_outgoing_arg_in_use); - bzero (stack_usage_map, highest_outgoing_arg_in_use); - highest_outgoing_arg_in_use = 0; - } - allocate_dynamic_stack_space (push_size, 0, BITS_PER_UNIT); - } -#endif - /* Don't try to defer pops if preallocating, not even from the first arg, since ARGBLOCK probably refers to the SP. */ if (argblock) -- 2.30.2