* expr.c (emit_push_insn): New argument alignment_pad.
authorclm <clm@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 29 Oct 1999 15:23:41 +0000 (15:23 +0000)
committerclm <clm@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 29 Oct 1999 15:23:41 +0000 (15:23 +0000)
        Update all callers.  Adjust stack pointer based on alignment pad.
        * function.c (pad_to_arg_alignment):  New argument alignment_pad.
        Update all callers.  Track alignment_pad if boundary > PARM_BOUNDARY.
        (locate_and_pad_parm): New argument alignment_pad.  Update all
        callers.
        * expr.h (emit_push_insn): Update prototype.
        (locate_and_pad_parm): Update prototype.
        * calls.c (arg_data):  Add new field alignment_pad.
        (initialize_argument_information): Initialize alignment_pad.

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

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

index 3680ac3..68090e2 100644 (file)
@@ -1,3 +1,16 @@
+Fri Oct 29 08:03:57 1999  Catherine Moore  <clm@cygnus.com>
+
+       * expr.c (emit_push_insn): New argument alignment_pad.
+       Update all callers.  Adjust stack pointer based on alignment pad.
+       * function.c (pad_to_arg_alignment):  New argument alignment_pad.
+       Update all callers.  Track alignment_pad if boundary > PARM_BOUNDARY.
+       (locate_and_pad_parm): New argument alignment_pad.  Update all
+       callers.
+       * expr.h (emit_push_insn): Update prototype.
+       (locate_and_pad_parm): Update prototype.
+       * calls.c (arg_data):  Add new field alignment_pad.
+       (initialize_argument_information): Initialize alignment_pad.
+
 Fri Oct 29 02:51:35 1999  Mark Mitchell  <mark@codesourcery.com>
 
        * except.c (free_eh_nesting_info): Free the info itself.
index 3b4b1b2..b17d197 100644 (file)
@@ -106,6 +106,9 @@ struct arg_data
      word-sized pseudos we made.  */
   rtx *aligned_regs;
   int n_aligned_regs;
+  /* The amount that the stack pointer needs to be adjusted to
+     force alignment for the next argument.  */
+  struct args_size alignment_pad;
 };
 
 #ifdef ACCUMULATE_OUTGOING_ARGS
@@ -898,6 +901,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
   /* Count arg position in order args appear.  */
   int argpos;
 
+  struct args_size alignment_pad;
   int i;
   tree p;
   
@@ -1093,12 +1097,14 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
                             args[i].reg != 0,
 #endif
                             fndecl, args_size, &args[i].offset,
-                            &args[i].size);
+                            &args[i].size, &alignment_pad);
 
 #ifndef ARGS_GROW_DOWNWARD
       args[i].slot_offset = *args_size;
 #endif
 
+      args[i].alignment_pad = alignment_pad;
+
       /* If a part of the arg was put into registers,
         don't include that part in the amount pushed.  */
       if (reg_parm_stack_space == 0 && ! args[i].pass_on_stack)
@@ -2688,7 +2694,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode,
       locate_and_pad_parm (mode, NULL_TREE,
                           argvec[count].reg && argvec[count].partial == 0,
                           NULL_TREE, &args_size, &argvec[count].offset,
-                          &argvec[count].size);
+                          &argvec[count].size, &alignment_pad);
 
       if (argvec[count].size.var)
        abort ();
@@ -2917,7 +2923,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode,
 #endif
          emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0,
                          argblock, GEN_INT (argvec[argnum].offset.constant),
-                         reg_parm_stack_space);
+                         reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
 
 #ifdef ACCUMULATE_OUTGOING_ARGS
          /* Now mark the segment we just used.  */
@@ -3072,6 +3078,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
   rtx fun;
   int inc;
   int count;
+  struct args_size alignment_pad;
   rtx argblock = 0;
   CUMULATIVE_ARGS args_so_far;
   struct arg { rtx value; enum machine_mode mode; rtx reg; int partial;
@@ -3192,7 +3199,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
       locate_and_pad_parm (Pmode, NULL_TREE,
                           argvec[count].reg && argvec[count].partial == 0,
                           NULL_TREE, &args_size, &argvec[count].offset,
-                          &argvec[count].size);
+                          &argvec[count].size, &alignment_pad);
 
 
       if (argvec[count].reg == 0 || argvec[count].partial != 0
@@ -3258,7 +3265,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
       locate_and_pad_parm (mode, NULL_TREE,
                           argvec[count].reg && argvec[count].partial == 0,
                           NULL_TREE, &args_size, &argvec[count].offset,
-                          &argvec[count].size);
+                          &argvec[count].size, &alignment_pad);
 
       if (argvec[count].size.var)
        abort ();
@@ -3486,7 +3493,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
 #endif
          emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0,
                          argblock, GEN_INT (argvec[argnum].offset.constant),
-                         reg_parm_stack_space);
+                         reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
 
 #ifdef ACCUMULATE_OUTGOING_ARGS
          /* Now mark the segment we just used.  */
@@ -3636,6 +3643,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
   highest_outgoing_arg_in_use = initial_highest_arg_in_use;
   stack_usage_map = initial_stack_usage_map;
 #endif
+  struct args_size alignment_pad;
 
   return value;
 }
@@ -3899,7 +3907,9 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
         This can either be done with push or copy insns.  */
       emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX, 0,
                      partial, reg, used - size, argblock,
-                     ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space);
+                     ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
+                     ARGS_SIZE_RTX (arg->alignment_pad));
+
     }
   else
     {
@@ -3932,7 +3942,8 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
       emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
                      TYPE_ALIGN (TREE_TYPE (pval)) / BITS_PER_UNIT, partial,
                      reg, excess, argblock, ARGS_SIZE_RTX (arg->offset),
-                     reg_parm_stack_space);
+                     reg_parm_stack_space,
+                     ARGS_SIZE_RTX (arg->alignment_pad));
     }
 
 
index e509ca4..3655960 100644 (file)
@@ -2870,7 +2870,8 @@ get_push_address (size)
 
 void
 emit_push_insn (x, mode, type, size, align, partial, reg, extra,
-               args_addr, args_so_far, reg_parm_stack_space)
+               args_addr, args_so_far, reg_parm_stack_space,
+                alignment_pad)
      register rtx x;
      enum machine_mode mode;
      tree type;
@@ -2882,6 +2883,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
      rtx args_addr;
      rtx args_so_far;
      int reg_parm_stack_space;
+     rtx alignment_pad;
 {
   rtx xinner;
   enum direction stack_direction
@@ -3176,7 +3178,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
                          0, args_addr,
                          GEN_INT (args_offset + ((i - not_stack + skip)
                                                  * UNITS_PER_WORD)),
-                         reg_parm_stack_space);
+                         reg_parm_stack_space, alignment_pad);
     }
   else
     {
@@ -3248,6 +3250,9 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
 
   if (extra && args_addr == 0 && where_pad == stack_direction)
     anti_adjust_stack (GEN_INT (extra));
+  if (alignment_pad)
+    anti_adjust_stack (alignment_pad);
 }
 \f
 /* Expand an assignment that stores the value of FROM into TO.
index 667ba02..816b86d 100644 (file)
@@ -983,7 +983,7 @@ extern rtx gen_push_operand PROTO((void));
 #ifdef TREE_CODE
 /* Generate code to push something onto the stack, given its mode and type.  */
 extern void emit_push_insn PROTO((rtx, enum machine_mode, tree, rtx, int,
-                                 int, rtx, int, rtx, rtx, int));
+                                 int, rtx, int, rtx, rtx, int, rtx));
 
 /* Emit library call.  */
 extern void emit_library_call PVPROTO((rtx orgfun, int no_queue,
@@ -1075,7 +1075,7 @@ extern rtx expand_call PROTO((tree, rtx, int));
 
 extern rtx expand_shift PROTO((enum tree_code, enum machine_mode, rtx, tree, rtx, int));
 extern rtx expand_divmod PROTO((int, enum tree_code, enum machine_mode, rtx, rtx, rtx, int));
-extern void locate_and_pad_parm PROTO((enum machine_mode, tree, int, tree, struct args_size *, struct args_size *, struct args_size *));
+extern void locate_and_pad_parm PROTO((enum machine_mode, tree, int, tree, struct args_size *, struct args_size *, struct args_size *, struct args_size *));
 extern rtx expand_inline_function PROTO((tree, tree, rtx, int, tree, rtx));
 /* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary.  */
 extern rtx label_rtx PROTO((tree));
index d5cdc26..847dcdf 100644 (file)
@@ -252,7 +252,7 @@ static void instantiate_decls_1     PROTO((tree, int));
 static void instantiate_decl   PROTO((rtx, int, int));
 static int instantiate_virtual_regs_1 PROTO((rtx *, rtx, int));
 static void delete_handlers    PROTO((void));
-static void pad_to_arg_alignment PROTO((struct args_size *, int));
+static void pad_to_arg_alignment PROTO((struct args_size *, int, struct args_size *));
 #ifndef ARGS_GROW_DOWNWARD
 static void pad_below          PROTO((struct args_size *, enum  machine_mode,
                                       tree));
@@ -3957,6 +3957,7 @@ assign_parms (fndecl)
   int varargs_setup = 0;
 #endif
   rtx conversion_insns = 0;
+  struct args_size alignment_pad;
 
   /* Nonzero if the last arg is named `__builtin_va_alist',
      which is used on some machines for old-fashioned non-ANSI varargs.h;
@@ -4169,7 +4170,8 @@ assign_parms (fndecl)
                                         pretend_named) != 0,
 #endif
 #endif
-                          fndecl, &stack_args_size, &stack_offset, &arg_size);
+                          fndecl, &stack_args_size, &stack_offset, &arg_size,
+                           &alignment_pad);
 
       {
        rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);
@@ -4861,7 +4863,8 @@ promoted_input_arg (regno, pmode, punsignedp)
 
 void
 locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
-                    initial_offset_ptr, offset_ptr, arg_size_ptr)
+                    initial_offset_ptr, offset_ptr, arg_size_ptr,
+                     alignment_pad)
      enum machine_mode passed_mode;
      tree type;
      int in_regs;
@@ -4869,6 +4872,8 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
      struct args_size *initial_offset_ptr;
      struct args_size *offset_ptr;
      struct args_size *arg_size_ptr;
+     struct args_size *alignment_pad;
+
 {
   tree sizetree
     = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
@@ -4923,7 +4928,7 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
     sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
   SUB_PARM_SIZE (*offset_ptr, sizetree);
   if (where_pad != downward)
-    pad_to_arg_alignment (offset_ptr, boundary);
+    pad_to_arg_alignment (offset_ptr, boundary, alignment_pad);
   if (initial_offset_ptr->var)
     {
       arg_size_ptr->var = size_binop (MINUS_EXPR,
@@ -4938,7 +4943,7 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
                                - offset_ptr->constant); 
     }
 #else /* !ARGS_GROW_DOWNWARD */
-  pad_to_arg_alignment (initial_offset_ptr, boundary);
+  pad_to_arg_alignment (initial_offset_ptr, boundary, alignment_pad);
   *offset_ptr = *initial_offset_ptr;
 
 #ifdef PUSH_ROUNDING
@@ -4967,12 +4972,26 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
    BOUNDARY is measured in bits, but must be a multiple of a storage unit.  */
 
 static void
-pad_to_arg_alignment (offset_ptr, boundary)
+pad_to_arg_alignment (offset_ptr, boundary, alignment_pad)
      struct args_size *offset_ptr;
      int boundary;
+     struct args_size *alignment_pad;
 {
+  tree save_var;
+  HOST_WIDE_INT save_constant;
+
   int boundary_in_bytes = boundary / BITS_PER_UNIT;
   
+  if (boundary > PARM_BOUNDARY)
+    {
+      save_var = offset_ptr->var;
+      save_constant = offset_ptr->constant;
+    }
+
+  alignment_pad->var = NULL_TREE;
+  alignment_pad->constant = 0;
+  /* END CYGNUS LOCAL */
+
   if (boundary > BITS_PER_UNIT)
     {
       if (offset_ptr->var)
@@ -4986,6 +5005,8 @@ pad_to_arg_alignment (offset_ptr, boundary)
              (ARGS_SIZE_TREE (*offset_ptr),
               boundary / BITS_PER_UNIT);
          offset_ptr->constant = 0; /*?*/
+          if (boundary > PARM_BOUNDARY)
+            alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var, save_var);
        }
       else
        offset_ptr->constant =
@@ -4994,6 +5015,8 @@ pad_to_arg_alignment (offset_ptr, boundary)
 #else
          CEIL_ROUND (offset_ptr->constant, boundary_in_bytes);
 #endif
+        if (boundary > PARM_BOUNDARY)
+          alignment_pad->constant = offset_ptr->constant - save_constant;
     }
 }