diff options
author | Richard Henderson | 2020-08-31 19:35:15 +0200 |
---|---|---|
committer | Richard Henderson | 2020-09-07 21:58:08 +0200 |
commit | 3c745866ed8169638accecd81e61dcfafa3cb3fb (patch) | |
tree | e3bfc4fa62a949c3dc86bc42654cd0afb7ef27d0 /target/microblaze | |
parent | target/microblaze: Handle DISAS_EXIT_NEXT in delay slot (diff) | |
download | qemu-3c745866ed8169638accecd81e61dcfafa3cb3fb.tar.gz qemu-3c745866ed8169638accecd81e61dcfafa3cb3fb.tar.xz qemu-3c745866ed8169638accecd81e61dcfafa3cb3fb.zip |
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>
Diffstat (limited to 'target/microblaze')
-rw-r--r-- | target/microblaze/translate.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c index 608d413c83..da84fdb20b 100644 --- a/target/microblaze/translate.c +++ b/target/microblaze/translate.c @@ -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: /* |