diff options
Diffstat (limited to 'gcc/calls.c')
-rw-r--r-- | gcc/calls.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/gcc/calls.c b/gcc/calls.c index 0ca03f8..ab51d17 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1,6 +1,6 @@ /* Convert function calls to rtl insns, for GNU C compiler. Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GCC. @@ -4191,6 +4191,7 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags, else if (arg->mode != BLKmode) { int size; + unsigned int parm_align; /* Argument is a scalar, not entirely passed in registers. (If part is passed in registers, arg->partial says how much @@ -4218,10 +4219,22 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags, / (PARM_BOUNDARY / BITS_PER_UNIT)) * (PARM_BOUNDARY / BITS_PER_UNIT)); + /* Compute the alignment of the pushed argument. */ + parm_align = arg->locate.boundary; + if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward) + { + int pad = used - size; + if (pad) + { + unsigned int pad_align = (pad & -pad) * BITS_PER_UNIT; + parm_align = MIN (parm_align, pad_align); + } + } + /* This isn't already where we want it on the stack, so put it there. This can either be done with push or copy insns. */ emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX, - PARM_BOUNDARY, partial, reg, used - size, argblock, + parm_align, partial, reg, used - size, argblock, ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space, ARGS_SIZE_RTX (arg->locate.alignment_pad)); |