On Fri, Jul 17, 2015 at 7:49 PM, H.J. Lu <hongjiu...@intel.com> wrote:
> If we put static chain on the stack, we need to replicate it on the stack
> so that static chain can be reached via (argp - 2) slot.  This is needed
> for nested function with stack realignment.
>
> OK for trunk if there are no regressions?
>
> H.J.
> ---
> gcc/
>
>         PR target/66906
>         * config/i386/i386.c (ix86_expand_prologue): Replicate static
>         chain on the stack.
>
> gcc/testsuite/
>
>         PR target/66906
>         * gcc.target/i386/pr66906.c: New test.
> ---
>  gcc/config/i386/i386.c                  | 18 ++++++++++++-
>  gcc/testsuite/gcc.target/i386/pr66906.c | 45 
> +++++++++++++++++++++++++++++++++
>  2 files changed, 62 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr66906.c
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 0551a75..3803dde 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -11495,6 +11495,7 @@ ix86_expand_prologue (void)
>    HOST_WIDE_INT allocate;
>    bool int_registers_saved;
>    bool sse_registers_saved;
> +  rtx static_chain = NULL_RTX;
>
>    ix86_finalize_stack_realign_flags ();
>
> @@ -11593,7 +11594,8 @@ ix86_expand_prologue (void)
>       call.  This insn will be skipped by the trampoline.  */
>    else if (ix86_static_chain_on_stack)
>      {
> -      insn = emit_insn (gen_push (ix86_static_chain (cfun->decl, false)));
> +      static_chain = ix86_static_chain (cfun->decl, false);
> +      insn = emit_insn (gen_push (static_chain));
>        emit_insn (gen_blockage ());
>
>        /* We don't want to interpret this push insn as a register save,
> @@ -11645,6 +11647,20 @@ ix86_expand_prologue (void)
>          we've started over with a new frame.  */
>        m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
>        m->fs.realigned = true;
> +
> +      if (static_chain)
> +       {
> +         /* Replicate static chain on the stack so that static chain
> +            can be reached via (argp - 2) slot.  This is needed for
> +            nested function with stack realignment.  */
> +         t = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
> +         t = gen_rtx_SET (stack_pointer_rtx, t);
> +         insn = emit_insn (t);
> +         RTX_FRAME_RELATED_P (insn) = 1;
> +         emit_move_insn (gen_rtx_MEM (Pmode, stack_pointer_rtx),
> +                         static_chain);
> +         m->fs.sp_offset += UNITS_PER_WORD;

All above can be just:

 if (static_chain)
    {
      /* ... */
      insn = emit_insn (gen_push (static_chain));
      RTX_FRAME_RELATED_P (insn) = 1;
    }

Please check if the above code survives bootstrap and regression test on x86_32.

Uros.

Reply via email to