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:
parent
3d35bcc213
commit
3c745866ed
@ -1518,7 +1518,6 @@ static void do_rti(DisasContext *dc)
|
|||||||
tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
|
tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
|
||||||
|
|
||||||
tcg_temp_free_i32(tmp);
|
tcg_temp_free_i32(tmp);
|
||||||
dc->tb_flags &= ~DRTI_FLAG;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_rtb(DisasContext *dc)
|
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_gen_or_i32(cpu_msr, cpu_msr, tmp);
|
||||||
|
|
||||||
tcg_temp_free_i32(tmp);
|
tcg_temp_free_i32(tmp);
|
||||||
dc->tb_flags &= ~DRTB_FLAG;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_rte(DisasContext *dc)
|
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_gen_or_i32(cpu_msr, cpu_msr, tmp);
|
||||||
|
|
||||||
tcg_temp_free_i32(tmp);
|
tcg_temp_free_i32(tmp);
|
||||||
dc->tb_flags &= ~DRTE_FLAG;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insns connected to FSL or AXI stream attached devices. */
|
/* 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.
|
* Finish any return-from branch.
|
||||||
* TODO: Diagnose rtXd in delay slot of rtYd earlier.
|
* TODO: Diagnose rtXd in delay slot of rtYd earlier.
|
||||||
*/
|
*/
|
||||||
if (dc->tb_flags & DRTI_FLAG) {
|
uint32_t rt_ibe = dc->tb_flags & (DRTI_FLAG | DRTB_FLAG | DRTE_FLAG);
|
||||||
do_rti(dc);
|
if (unlikely(rt_ibe != 0)) {
|
||||||
} else if (dc->tb_flags & DRTB_FLAG) {
|
dc->tb_flags &= ~(DRTI_FLAG | DRTB_FLAG | DRTE_FLAG);
|
||||||
do_rtb(dc);
|
if (rt_ibe & DRTI_FLAG) {
|
||||||
} else if (dc->tb_flags & DRTE_FLAG) {
|
do_rti(dc);
|
||||||
do_rte(dc);
|
} else if (rt_ibe & DRTB_FLAG) {
|
||||||
|
do_rtb(dc);
|
||||||
|
} else {
|
||||||
|
do_rte(dc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Complete the branch, ending the TB. */
|
/* Complete the branch, ending the TB. */
|
||||||
@ -1723,8 +1724,12 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
|
|||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
case DISAS_NEXT:
|
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;
|
break;
|
||||||
case DISAS_EXIT_NEXT:
|
case DISAS_EXIT_NEXT:
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user