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