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]

Re: [patch] expr.c: Fix the failure ofgcc.dg/compat/scalar-by-value-4.


Hi Jim,

> > +  else if (FUNCTION_ARG_PADDING (mode, type) == stack_direction)
> 
> I think this test is wrong.  If arg and stack padding are both
> upward, then we want to emit 2 bytes of operand followed by 2 bytes
> of padding.  There is no special offset needed here, since this is
> just a 2 byte store followed by a 4 byte increment.
> 
> I think the problem case is always when FUNCTION_ARG_PADDING is
> downward.  In that case, we are always writing into the middle of
> the new stack area.  Does this sound right to you?

Doh!  Thank you for spotting this.  Reflected in the new patch below.

After reading your comment, doing a complete job here seems to mean to
take care of four different cases:

 1)  STACK_GROWS_DOWNWARD, STACK_PUSH_CODE == PRE_DEC
 2)  STACK_GROWS_DOWNWARD, STACK_PUSH_CODE == POST_DEC
 3) !STACK_GROWS_DOWNWARD, STACK_PUSH_CODE == PRE_INC
 4) !STACK_GROWS_DOWNWARD, STACK_PUSH_CODE == POST_INC

To my surprise, h8300 is the only port that my patch has effects on.

h8300 is the only one that falls into 1).  i386 doesn't get to my code
because BYTES_BIG_ENDIAN == 0, which always forces
FUNCTION_ARG_PADDING to upward.  Some don't have PUSH_ROUNDING.
Others may have have PUSH_ROUNDING, but it may be the identity
function.

No port falls into 2).  avr port comes close, but its PUSH_ROUNDING is
the identity function, so the control flow does not get to my code.

c4x port comes close to 3), but its PUSH_ROUNDING is the identity
function.

Again, stormy16 comes close to 4), but it's a little endinan machine,
so FUNCTION_ARG_PADDING always evaluates to upward.

OK to apply after regression testing on h8300 port?

Kazu Hirata

2003-06-28  Kazu Hirata  <kazu@cs.umass.edu>

	* expr.c (emit_single_push_insn): If padding is needed
	downward, 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.556
diff -u -r1.556 expr.c
--- expr.c	27 Jun 2003 09:49:31 -0000	1.556
+++ expr.c	28 Jun 2003 08:56:49 -0000
@@ -3802,12 +3802,48 @@
     }
   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 downward, adjust the stack pointer first and
+     then 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) == downward)
+    {
+      unsigned padding_size = rounded_size - GET_MODE_SIZE (mode);
+      HOST_WIDE_INT offset;
+
+      emit_move_insn (stack_pointer_rtx,
+		      expand_binop (Pmode,
+#ifdef STACK_GROWS_DOWNWARD
+				    sub_optab,
+#else
+				    add_optab,
+#endif
+				    stack_pointer_rtx,
+				    GEN_INT (rounded_size),
+				    NULL_RTX, 0, OPTAB_LIB_WIDEN));
+
+      offset = (HOST_WIDE_INT) padding_size;
+#ifdef STACK_GROWS_DOWNWARD
+      if (STACK_PUSH_CODE == POST_DEC)
+	/* We have already decremented the stack pointer, so get the
+	   previous value.  */
+	offset += (HOST_WIDE_INT) rounded_size;
+#else
+      if (STACK_PUSH_CODE == POST_INC)
+	/* We have already incremented the stack pointer, so get the
+	   previous value.  */
+	offset -= (HOST_WIDE_INT) rounded_size;
+#endif
+      dest_addr = gen_rtx_PLUS (Pmode, GEN_INT (offset));
+    }
   else
     {
 #ifdef STACK_GROWS_DOWNWARD
+      /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC.  */
       dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
 				GEN_INT (-(HOST_WIDE_INT) rounded_size));
 #else
+      /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC.  */
       dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
 				GEN_INT (rounded_size));
 #endif


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