|
@@ -1816,6 +1816,18 @@ static void decode_opc(DisasContext * ctx)
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_USER_ONLY
|
|
|
+/*
|
|
|
+ * Restart with the EXCLUSIVE bit set, within a TB run via
|
|
|
+ * cpu_exec_step_atomic holding the exclusive lock.
|
|
|
+ */
|
|
|
+static void gen_restart_exclusive(DisasContext *ctx)
|
|
|
+{
|
|
|
+ ctx->envflags |= TB_FLAG_GUSA_EXCLUSIVE;
|
|
|
+ gen_save_cpu_state(ctx, false);
|
|
|
+ gen_helper_exclusive(tcg_env);
|
|
|
+ ctx->base.is_jmp = DISAS_NORETURN;
|
|
|
+}
|
|
|
+
|
|
|
/* For uniprocessors, SH4 uses optimistic restartable atomic sequences.
|
|
|
Upon an interrupt, a real kernel would simply notice magic values in
|
|
|
the registers and reset the PC to the start of the sequence.
|
|
@@ -2149,12 +2161,7 @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
|
|
|
qemu_log_mask(LOG_UNIMP, "Unrecognized gUSA sequence %08x-%08x\n",
|
|
|
pc, pc_end);
|
|
|
|
|
|
- /* Restart with the EXCLUSIVE bit set, within a TB run via
|
|
|
- cpu_exec_step_atomic holding the exclusive lock. */
|
|
|
- ctx->envflags |= TB_FLAG_GUSA_EXCLUSIVE;
|
|
|
- gen_save_cpu_state(ctx, false);
|
|
|
- gen_helper_exclusive(tcg_env);
|
|
|
- ctx->base.is_jmp = DISAS_NORETURN;
|
|
|
+ gen_restart_exclusive(ctx);
|
|
|
|
|
|
/* We're not executing an instruction, but we must report one for the
|
|
|
purposes of accounting within the TB. We might as well report the
|
|
@@ -2242,12 +2249,22 @@ static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
|
|
|
#ifdef CONFIG_USER_ONLY
|
|
|
if (unlikely(ctx->envflags & TB_FLAG_GUSA_MASK)
|
|
|
&& !(ctx->envflags & TB_FLAG_GUSA_EXCLUSIVE)) {
|
|
|
- /* We're in an gUSA region, and we have not already fallen
|
|
|
- back on using an exclusive region. Attempt to parse the
|
|
|
- region into a single supported atomic operation. Failure
|
|
|
- is handled within the parser by raising an exception to
|
|
|
- retry using an exclusive region. */
|
|
|
- decode_gusa(ctx, env);
|
|
|
+ /*
|
|
|
+ * We're in an gUSA region, and we have not already fallen
|
|
|
+ * back on using an exclusive region. Attempt to parse the
|
|
|
+ * region into a single supported atomic operation. Failure
|
|
|
+ * is handled within the parser by raising an exception to
|
|
|
+ * retry using an exclusive region.
|
|
|
+ *
|
|
|
+ * Parsing the region in one block conflicts with plugins,
|
|
|
+ * so always use exclusive mode if plugins enabled.
|
|
|
+ */
|
|
|
+ if (ctx->base.plugin_enabled) {
|
|
|
+ gen_restart_exclusive(ctx);
|
|
|
+ ctx->base.pc_next += 2;
|
|
|
+ } else {
|
|
|
+ decode_gusa(ctx, env);
|
|
|
+ }
|
|
|
return;
|
|
|
}
|
|
|
#endif
|