@@ -1394,7 +1394,7 @@ static void handle_sync(DisasContext *s, uint32_t insn,
* any pending interrupts immediately.
*/
gen_a64_set_pc_im(s->pc);
- s->is_jmp = DISAS_UPDATE;
+ s->is_jmp = DISAS_JUMP;
return;
default:
unallocated_encoding(s);
@@ -1203,6 +1203,15 @@ static inline void gen_lookup_tb(DisasContext *s)
s->is_jmp = DISAS_UPDATE;
}
+/* End the current block and force a TB lookup. We may chain to the
+ * next TB but exit_req will be immediately checked so we will exit to
+ * the main loop if we need to */
+static inline void gen_jump_tb(DisasContext *s)
+{
+ tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
+ s->is_jmp = DISAS_JUMP;
+}
+
static inline void gen_hlt(DisasContext *s, int imm)
{
/* HLT. This has two purposes.
@@ -8171,7 +8180,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
* self-modifying code correctly and also to take
* any pending interrupts immediately.
*/
- gen_lookup_tb(s);
+ gen_jump_tb(s);
return;
default:
goto illegal_op;
@@ -10564,7 +10573,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
* and also to take any pending interrupts
* immediately.
*/
- gen_lookup_tb(s);
+ gen_jump_tb(s);
break;
default:
goto illegal_op;
While an ISB will ensure any raised IRQs happen on the next instruction it doesn't cause any to get raised by itself. We can therefor use DISAS_JUMP for ISB instructions and rely on the exit_request check at the top of each TB to deal with exiting if needed. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> --- target/arm/translate-a64.c | 2 +- target/arm/translate.c | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) -- 2.13.0