calls.c (store_one_arg): Rename default_align to parm_align; always adjust parm_align...
authorRichard Henderson <rth@redhat.com>
Thu, 19 Sep 2002 00:37:24 +0000 (17:37 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 19 Sep 2002 00:37:24 +0000 (17:37 -0700)
* calls.c (store_one_arg): Rename default_align to parm_align;
always adjust parm_align for downward padding.

From-SVN: r57292

gcc/ChangeLog
gcc/calls.c

index b88236f989a608ea6e43e34b44b0c895b6e2355f..3a4be4e6d2dc1b05c5500c9607d10acd0772ca66 100644 (file)
@@ -1,3 +1,8 @@
+2002-09-18  Richard Henderson  <rth@redhat.com>
+
+       * calls.c (store_one_arg): Rename default_align to parm_align;
+       always adjust parm_align for downward padding.
+
 2002-09-18  Richard Henderson  <rth@redhat.com>
 
        * toplev.c (backend_init): Move init_real_once invocation ...
index 578bd982b62512c924957450d9de880310904bce..97e7e045068b96dce2d8d7115c461d95849ae4e0 100644 (file)
@@ -4491,7 +4491,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
     {
       /* BLKmode, at least partly to be pushed.  */
 
-      unsigned int default_align = PARM_BOUNDARY;
+      unsigned int parm_align;
       int excess;
       rtx size_rtx;
 
@@ -4499,13 +4499,6 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
         If part is passed in registers, PARTIAL says how much
         and emit_push_insn will take care of putting it there.  */
 
-#ifdef ARGS_GROW_DOWNWARD
-      /* When an argument is padded down, the block is not aligned to
-        PARM_BOUNDARY.  */
-      if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
-       default_align = BITS_PER_UNIT;
-#endif
-
       /* Round its size up to a multiple
         of the allocation unit for arguments.  */
 
@@ -4524,6 +4517,23 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
                                  NULL_RTX, TYPE_MODE (sizetype), 0);
        }
 
+      /* Some types will require stricter alignment, which will be
+        provided for elsewhere in argument layout.  */
+      parm_align = MAX (PARM_BOUNDARY, TYPE_ALIGN (TREE_TYPE (pval)));
+
+      /* When an argument is padded down, the block is aligned to
+        PARM_BOUNDARY, but the actual argument isn't.  */
+      if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
+       {
+         if (arg->size.var)
+           parm_align = BITS_PER_UNIT;
+         else if (excess)
+           {
+             int excess_align = (excess & -excess) * BITS_PER_UNIT;
+             parm_align = MIN (parm_align, excess_align);
+           }
+       }
+
       if ((flags & ECF_SIBCALL) && GET_CODE (arg->value) == MEM)
        {
          /* emit_push_insn might not work properly if arg->value and
@@ -4581,8 +4591,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
           {
            rtx size_rtx1 = GEN_INT (reg_parm_stack_space - arg->offset.constant);
            emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx1,
-                           MAX (default_align, TYPE_ALIGN (TREE_TYPE (pval))),
-                           partial, reg, excess, argblock,
+                           parm_align, partial, reg, excess, argblock,
                            ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
                            ARGS_SIZE_RTX (arg->alignment_pad));
          }
@@ -4590,8 +4599,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
        
 
       emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
-                     MAX (default_align, TYPE_ALIGN (TREE_TYPE (pval))),
-                     partial, reg, excess, argblock,
+                     parm_align, partial, reg, excess, argblock,
                      ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
                      ARGS_SIZE_RTX (arg->alignment_pad));