target/microblaze: Force rtid, rted, rtbd to exit

These return-from-exception type instructions have modified
MSR to re-enable various forms of interrupt.  Force a return
to the main loop.

Consolidate the cleanup of tb_flags into mb_tr_translate_insn.

Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2020-08-31 10:35:15 -07:00
parent 3d35bcc213
commit 3c745866ed
1 changed files with 16 additions and 11 deletions

View File

@ -1518,7 +1518,6 @@ static void do_rti(DisasContext *dc)
tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
tcg_temp_free_i32(tmp);
dc->tb_flags &= ~DRTI_FLAG;
}
static void do_rtb(DisasContext *dc)
@ -1531,7 +1530,6 @@ static void do_rtb(DisasContext *dc)
tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
tcg_temp_free_i32(tmp);
dc->tb_flags &= ~DRTB_FLAG;
}
static void do_rte(DisasContext *dc)
@ -1545,7 +1543,6 @@ static void do_rte(DisasContext *dc)
tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
tcg_temp_free_i32(tmp);
dc->tb_flags &= ~DRTE_FLAG;
}
/* Insns connected to FSL or AXI stream attached devices. */
@ -1700,12 +1697,16 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
* Finish any return-from branch.
* TODO: Diagnose rtXd in delay slot of rtYd earlier.
*/
if (dc->tb_flags & DRTI_FLAG) {
do_rti(dc);
} else if (dc->tb_flags & DRTB_FLAG) {
do_rtb(dc);
} else if (dc->tb_flags & DRTE_FLAG) {
do_rte(dc);
uint32_t rt_ibe = dc->tb_flags & (DRTI_FLAG | DRTB_FLAG | DRTE_FLAG);
if (unlikely(rt_ibe != 0)) {
dc->tb_flags &= ~(DRTI_FLAG | DRTB_FLAG | DRTE_FLAG);
if (rt_ibe & DRTI_FLAG) {
do_rti(dc);
} else if (rt_ibe & DRTB_FLAG) {
do_rtb(dc);
} else {
do_rte(dc);
}
}
/* Complete the branch, ending the TB. */
@ -1723,8 +1724,12 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
*/
break;
case DISAS_NEXT:
/* Normal insn a delay slot. */
dc->base.is_jmp = DISAS_JUMP;
/*
* Normal insn a delay slot.
* However, the return-from-exception type insns should
* return to the main loop, as they have adjusted MSR.
*/
dc->base.is_jmp = (rt_ibe ? DISAS_EXIT_JUMP : DISAS_JUMP);
break;
case DISAS_EXIT_NEXT:
/*