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:
Joseph Myers 2007-02-09 01:11:18 +00:00 committed by Joseph Myers
parent 687e00ee8a
commit 46bd2beed4
3 changed files with 38 additions and 3 deletions

View file

@ -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

View file

@ -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));

View file

@ -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