Commit 46bd2bee by Joseph Myers Committed by Joseph Myers

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
parent 687e00ee
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
......
/* 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));
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment