diff mbox series

[2/4] accel/tcg: Create io_recompile_replay_branch hook

Message ID 20210208233906.479571-3-richard.henderson@linaro.org
State New
Headers show
Series accel/tcg: Create io_recompile_replay_branch hook | expand

Commit Message

Richard Henderson Feb. 8, 2021, 11:39 p.m. UTC
Create a hook in which to split out the mips and
sh4 ifdefs from cpu_io_recompile.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 include/hw/core/tcg-cpu-ops.h | 10 ++++++++++
 accel/tcg/translate-all.c     | 17 +++++++++++++----
 2 files changed, 23 insertions(+), 4 deletions(-)

-- 
2.25.1

Comments

Peter Maydell Feb. 9, 2021, 5:05 p.m. UTC | #1
On Tue, 9 Feb 2021 at 00:29, Richard Henderson
<richard.henderson@linaro.org> wrote:
>

> Create a hook in which to split out the mips and

> sh4 ifdefs from cpu_io_recompile.

>

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

> ---

>  include/hw/core/tcg-cpu-ops.h | 10 ++++++++++

>  accel/tcg/translate-all.c     | 17 +++++++++++++----

>  2 files changed, 23 insertions(+), 4 deletions(-)

>

> diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h

> index ac3bb051f2..ddf334411f 100644

> --- a/include/hw/core/tcg-cpu-ops.h

> +++ b/include/hw/core/tcg-cpu-ops.h

> @@ -88,6 +88,16 @@ struct TCGCPUOps {

>       */

>      bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp);

>

> +    /**

> +     * @io_recompile_replay_branch: Callback for cpu_io_recompile.

> +     *

> +     * The cpu has been stoped, and cpu_restore_state_from_tb has been


"stopped"

> +     * called.  If the faulting instruction is in a delay slot, and the

> +     * target architecture requires re-execution of the branch, then

> +     * adjust the cpu state as required and return true.

> +     */

> +    bool (*io_recompile_replay_branch)(CPUState *cpu,

> +                                       const TranslationBlock *tb);

>  #endif /* CONFIG_SOFTMMU */


thanks
-- PMM
diff mbox series

Patch

diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index ac3bb051f2..ddf334411f 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -88,6 +88,16 @@  struct TCGCPUOps {
      */
     bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp);
 
+    /**
+     * @io_recompile_replay_branch: Callback for cpu_io_recompile.
+     *
+     * The cpu has been stoped, and cpu_restore_state_from_tb has been
+     * called.  If the faulting instruction is in a delay slot, and the
+     * target architecture requires re-execution of the branch, then
+     * adjust the cpu state as required and return true.
+     */
+    bool (*io_recompile_replay_branch)(CPUState *cpu,
+                                       const TranslationBlock *tb);
 #endif /* CONFIG_SOFTMMU */
 #endif /* NEED_CPU_H */
 
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 81d4c83f22..6eb37883bd 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -60,6 +60,7 @@ 
 #include "sysemu/cpu-timers.h"
 #include "sysemu/tcg.h"
 #include "qapi/error.h"
+#include "hw/core/tcg-cpu-ops.h"
 #include "internal.h"
 
 /* #define DEBUG_TB_INVALIDATE */
@@ -2420,6 +2421,7 @@  void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
     CPUArchState *env = cpu->env_ptr;
 #endif
     TranslationBlock *tb;
+    CPUClass *cc;
     uint32_t n;
 
     tb = tcg_tb_lookup(retaddr);
@@ -2429,11 +2431,18 @@  void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
     }
     cpu_restore_state_from_tb(cpu, tb, retaddr, true);
 
-    /* On MIPS and SH, delay slot instructions can only be restarted if
-       they were already the first instruction in the TB.  If this is not
-       the first instruction in a TB then re-execute the preceding
-       branch.  */
+    /*
+     * Some guests must re-execute the branch when re-executing a delay
+     * slot instruction.  When this is the case, adjust icount and N
+     * to account for the re-execution of the branch.
+     */
     n = 1;
+    cc = CPU_GET_CLASS(cpu);
+    if (cc->tcg_ops->io_recompile_replay_branch &&
+        cc->tcg_ops->io_recompile_replay_branch(cpu, tb)) {
+        cpu_neg(cpu)->icount_decr.u16.low++;
+        n = 2;
+    }
 #if defined(TARGET_MIPS)
     if ((env->hflags & MIPS_HFLAG_BMASK) != 0
         && env->active_tc.PC != tb->pc) {