aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-09-18 17:37:24 -0700
committerRichard Henderson <rth@gcc.gnu.org>2002-09-18 17:37:24 -0700
commit1b1f20cab9ba8fea71e43cecfe985eb60e2f59e7 (patch)
tree1c0bdbce207c01a6f967dd988580a82b62456ac3 /gcc/calls.c
parent724838b9aa794141c9230c5d72316173752a9875 (diff)
downloadgcc-1b1f20cab9ba8fea71e43cecfe985eb60e2f59e7.zip
gcc-1b1f20cab9ba8fea71e43cecfe985eb60e2f59e7.tar.gz
gcc-1b1f20cab9ba8fea71e43cecfe985eb60e2f59e7.tar.bz2
calls.c (store_one_arg): Rename default_align to parm_align; always adjust parm_align for downward padding.
* calls.c (store_one_arg): Rename default_align to parm_align; always adjust parm_align for downward padding. From-SVN: r57292
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index 578bd98..97e7e04 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -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));