This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] expr.c: Fix the failure of gcc.dg/compat/scalar-by-value-4.
- From: Kazu Hirata <kazu at cs dot umass dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 22 Jun 2003 14:26:15 -0400 (EDT)
- Subject: [patch] expr.c: Fix the failure of gcc.dg/compat/scalar-by-value-4.
Hi,
Attached is a patch to fix the failure of
gcc.dg/compat/scalar-by-value-4 and struct-by-value-11 on h8300 port.
The failure is due to a mismatch of stack locations that the caller
and the callee use to store/retrieve an object of CQImode in the
stack. Specifically, the caller pushes four bytes like so
sp + 3 : padding
sp + 2 : padding
sp + 1 : imaginary part of CQImode object
sp + 0 : real part of CQImode object
But the callee expects
sp + 3 : imaginary part of CQImode object
sp + 2 : real part of CQImode object
sp + 1 : padding
sp + 0 : padding
Since h8300 port uses the default FUNCTION_ARG_PADDING, which
evaluates to downward in this case, and the stack grows downward on
h8300, the padding is supposed to appear at the very frontier of the
stack. That is, the caller is wrong.
Since h8300 port does not have any special pattern for pushing
CQImode, emit_single_push_insn computes the stack location and asks
emit_move_insn to do the actual move. However, the stack location
that emit_single_push_insn computes is equivalent to "sp + 0" above.
Not knowing that padding is needed afterwards, emit_move_insn honestly
places the CQI object at the wrong place.
The patch fixes this problem by telling emit_single_push_insn to first
subtract PUSH_ROUNDed size from the stack pointer and then ask
emit_move_insn to copy the object to *(sp + offset).
Tested on h8300 port. OK to apply?
Kazu Hirata
2003-06-22 Kazu Hirata <kazu@cs.umass.edu>
* expr.c (emit_single_push_insn): If padding is needed
afterwards, adjust the stack pointer first, and then store the
data into the stack location using an offset.
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.553
diff -u -r1.553 expr.c
--- expr.c 19 Jun 2003 17:29:29 -0000 1.553
+++ expr.c 22 Jun 2003 15:03:04 -0000
@@ -3783,6 +3783,12 @@
tree type;
{
rtx dest_addr;
+ enum direction stack_direction
+#ifdef STACK_GROWS_DOWNWARD
+ = downward;
+#else
+ = upward;
+#endif
unsigned rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
rtx dest;
enum insn_code icode;
@@ -3802,6 +3808,28 @@
}
if (GET_MODE_SIZE (mode) == rounded_size)
dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
+ /* If we are to pad after the pushed object, adjust the stack
+ pointer now and store X into the stack location using an offset.
+ This is because emit_move_insn does not know how to pad; it does
+ not have access to type. */
+ else if (FUNCTION_ARG_PADDING (mode, type) == stack_direction)
+ {
+ unsigned padding_size = rounded_size - GET_MODE_SIZE (mode);
+#ifdef STACK_GROWS_DOWNWARD
+ HOST_WIDE_INT stack_growth_sign = -1;
+#else
+ HOST_WIDE_INT stack_growth_sign = 1;
+#endif
+
+ emit_move_insn (stack_pointer_rtx,
+ expand_binop (Pmode, add_optab, stack_pointer_rtx,
+ GEN_INT (stack_growth_sign
+ * (HOST_WIDE_INT) rounded_size),
+ NULL_RTX, 0, OPTAB_LIB_WIDEN));
+ dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+ GEN_INT (-stack_growth_sign
+ * (HOST_WIDE_INT) padding_size));
+ }
else
{
#ifdef STACK_GROWS_DOWNWARD