On Thursday, 08/23/2018. 8:09:05 EEST Dimitar Dimitrov wrote:
> > > +/* Emit function epilogue.  */
> > > +void
> > > +pru_expand_epilogue (bool sibcall_p)
> > > +{
> > > +  rtx cfa_adj;
> > > +  int total_frame_size;
> > > +  int sp_adjust, save_offset;
> > > +  int regno_start;
> > > +
> > > +  if (!sibcall_p && pru_can_use_return_insn ())
> > > +    {
> > > +      emit_jump_insn (gen_return ());
> > > +      return;
> > > +    }
> > > +
> > > +  emit_insn (gen_blockage ());
> > > +
> > > +  total_frame_size = pru_compute_frame_layout ();
> > > +  if (frame_pointer_needed)
> > > +    {
> > > +      /* Recover the stack pointer.  */
> > > +      cfa_adj = plus_constant (Pmode, stack_pointer_rtx,
> > > +                              (total_frame_size
> > > +                               - cfun->machine->save_regs_offset));
> > > +      pru_add3_frame_adjust (stack_pointer_rtx,
> > > +                            hard_frame_pointer_rtx,
> > > +                            -cfun->machine->fp_save_offset,
> > > +                            REG_CFA_DEF_CFA,
> > > +                            cfa_adj);
> > > +
> > > +      save_offset = 0;
> > > +      sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
> > > +    }
> > > +  else if (!UBYTE_INT (total_frame_size))
> > > +    {
> > > +      pru_add_to_sp (cfun->machine->save_regs_offset,
> > > +                           REG_CFA_ADJUST_CFA);
> > > +      save_offset = 0;
> > > +      sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
> > > +    }
> > > +  else
> > > +    {
> > > +      save_offset = cfun->machine->save_regs_offset;
> > > +      sp_adjust = total_frame_size;
> > > +    }
> > > +
> > > +  regno_start = 0;
> > > +  do {
> > > +      regno_start = xbbo_next_reg_cluster (regno_start, &save_offset,
> > > false); +  } while (regno_start >= 0);
> > > +
> > > +  if (sp_adjust)
> > > +      pru_add_to_sp (sp_adjust, REG_CFA_ADJUST_CFA);
> > > +
> > > +  if (!sibcall_p)
> > > +    emit_jump_insn (gen_simple_return ());
> > 
> > Note you probably need a blockage before the restore of the stack
> > pointer to avoid some really nasty problems with the scheduler
> > reordering things such that the current frame gets deallocated before
> > register restores happen.  It usually doesn't cause a problem, but if an
> > interrupt occurs between the de-allocation and register restore, then
> > all bets are off.
> 
> Thank you. I will fix it.

I have attached a fixup patch for this particular blockage issue, in case you 
want to apply it on top of the v3 patch series. If that is not convenient, I 
will wait a few more days for comments, and then I will send v4.

Thanks,
Dimitar
>From 3feed8e7d19db555af0665dec24233a97d9a634c Mon Sep 17 00:00:00 2001
From: Dimitar Dimitrov <dimi...@dinux.eu>
Date: Thu, 23 Aug 2018 08:14:13 +0300
Subject: [PATCH] Add blockage in epilogue before SP restore.

Signed-off-by: Dimitar Dimitrov <dimi...@dinux.eu>
---
 gcc/config/pru/pru.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/gcc/config/pru/pru.c b/gcc/config/pru/pru.c
index de72d22278e..f1ce8bfeddd 100644
--- a/gcc/config/pru/pru.c
+++ b/gcc/config/pru/pru.c
@@ -389,6 +389,13 @@ pru_expand_epilogue (bool sibcall_p)
       regno_start = xbbo_next_reg_cluster (regno_start, &save_offset, false);
   } while (regno_start >= 0);
 
+  /* Emit a blockage insn here to keep these insns from being moved to
+     an earlier spot in the epilogue.
+
+     This is necessary as we must not cut the stack back before all the
+     restores are finished.  */
+  emit_insn (gen_blockage ());
+
   if (sp_adjust)
       pru_add_to_sp (sp_adjust, REG_CFA_ADJUST_CFA);
 
-- 
2.11.0

Reply via email to