This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]