OSDN Git Service

* function.h (struct expr_status): Add x_arg_space_so_far.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 2 Mar 2000 23:50:11 +0000 (23:50 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 2 Mar 2000 23:50:11 +0000 (23:50 +0000)
        (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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32296 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/calls.c
gcc/expr.c
gcc/function.h

index 04824c6..d8b64b4 100644 (file)
@@ -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
index 3d78c8b..4ff988a 100644 (file)
@@ -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,
index 4d777f9..b0d1e07 100644 (file)
@@ -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;
index fb3ef49..9ede7a7 100644 (file)
@@ -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)