The m32c-elf with -mcpu=m32c has a word-aligned stack and uses pushes
for arguments (i.e. not accumulate_outgoing_args).  In this test case,
one of the arguments is memcpy'd into place, and an assert fails:

typedef struct {
  int a, b, c, d, e, f, g, h;
} foo;
int x;
void
dj (int a, int b, foo c)
{
  dj2 (x, a, b, c);
}

      if (pass == 0)
        {
          . . .
        }
      else
        {
          normal_call_insns = insns;

          /* Verify that we've deallocated all the stack we used.  */
          gcc_assert ((flags & ECF_NORETURN)
                      || (old_stack_allocated
                          == stack_pointer_delta - pending_stack_adjust));
        }

After much debugging, it turns out that the argument that's memcpy'd
to stack doesn't adjust stack_pointer_delta the same way that the
other arguments do (i.e. push_block and push_args don't adjust it
consistently, or something like that.)

I came up with this patch:

Index: expr.c
===================================================================
--- expr.c      (revision 214599)
+++ expr.c      (working copy)
@@ -4234,12 +4234,16 @@ emit_push_insn (rtx x, enum machine_mode
          /* Get the address of the stack space.
             In this case, we do not deal with EXTRA separately.
             A single stack adjust will do.  */
          if (! args_addr)
            {
              temp = push_block (size, extra, where_pad == downward);
+#ifdef PUSH_ROUNDING
+             if (CONST_INT_P (size))
+               stack_pointer_delta += INTVAL (size) + extra;
+#endif
              extra = 0;
            }
          else if (CONST_INT_P (args_so_far))
            temp = memory_address (BLKmode,
                                   plus_constant (Pmode, args_addr,
                                                  skip + INTVAL (args_so_far)));


But builds of libstdc++v3 demonstrate that sometimes
stack_pointer_delta *is* adjusted consistently, thus there must be
some more complex logic for determining when the extra adjustment
(i.e. my patch) should be made, or it's in the wrong place.

So... could someone more familiar with this code enlighten me on the
actual rules for what stack_pointer_delta means and when it gets
adjusted, and where (in theory) a memcpy'd argument on a push_args
target should update it (if at all)?

Thanks!
DJ

Reply via email to