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 <[email protected]>
Date: Thu, 23 Aug 2018 08:14:13 +0300
Subject: [PATCH] Add blockage in epilogue before SP restore.
Signed-off-by: Dimitar Dimitrov <[email protected]>
---
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