calls.c (store_one_arg): Pass correct alignment to emit_push_insn for non-BLKmode values.
* calls.c (store_one_arg): Pass correct alignment to emit_push_insn for non-BLKmode values. * expr.c (emit_push_insn): If STRICT_ALIGNMENT, copy to an unaligned stack slot via a suitably aligned slot. From-SVN: r121736
This commit is contained in:
parent
687e00ee8a
commit
46bd2beed4
3 changed files with 38 additions and 3 deletions
|
@ -1,3 +1,10 @@
|
|||
2007-02-09 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* calls.c (store_one_arg): Pass correct alignment to
|
||||
emit_push_insn for non-BLKmode values.
|
||||
* expr.c (emit_push_insn): If STRICT_ALIGNMENT, copy to an
|
||||
unaligned stack slot via a suitably aligned slot.
|
||||
|
||||
2007-02-08 DJ Delorie <dj@redhat.com>
|
||||
|
||||
* config/m32c/m32c.c (m32c_unpend_compare): Add default to silence
|
||||
|
|
17
gcc/calls.c
17
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));
|
||||
|
||||
|
|
17
gcc/expr.c
17
gcc/expr.c
|
@ -3643,7 +3643,8 @@ emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size,
|
|||
|
||||
xinner = x;
|
||||
|
||||
if (mode == BLKmode)
|
||||
if (mode == BLKmode
|
||||
|| (STRICT_ALIGNMENT && align < GET_MODE_ALIGNMENT (mode)))
|
||||
{
|
||||
/* Copy a block into the stack, entirely or partially. */
|
||||
|
||||
|
@ -3655,6 +3656,20 @@ emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size,
|
|||
offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
|
||||
used = partial - offset;
|
||||
|
||||
if (mode != BLKmode)
|
||||
{
|
||||
/* A value is to be stored in an insufficiently aligned
|
||||
stack slot; copy via a suitably aligned slot if
|
||||
necessary. */
|
||||
size = GEN_INT (GET_MODE_SIZE (mode));
|
||||
if (!MEM_P (xinner))
|
||||
{
|
||||
temp = assign_temp (type, 0, 1, 1);
|
||||
emit_move_insn (temp, xinner);
|
||||
xinner = temp;
|
||||
}
|
||||
}
|
||||
|
||||
gcc_assert (size);
|
||||
|
||||
/* USED is now the # of bytes we need not copy to the stack
|
||||
|
|
Loading…
Add table
Reference in a new issue