All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH 0/4] translate: [tcg] Generic translation framework
@ 2016-07-15 16:12 Lluís Vilanova
  2016-07-15 16:12 ` [Qemu-devel] [PATCH 1/4] Pass generic CPUState to gen_intermediate_code() Lluís Vilanova
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Lluís Vilanova @ 2016-07-15 16:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Peter Crosthwaite, Paolo Bonzini

This series proposes a generic (target-agnostic) instruction translation
framework.

It basically provides a generic main loop for instruction disassembly, which
calls target-specific functions when necessary. This generalization makes
inserting new code in the main loop easier, and helps in keeping all targets in
synch as to the contents of it.

I've only ported i386 as an example to get some feedback, but I'm planning on
porting ARM next to see how well it fits into the current organization.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---

Lluís Vilanova (4):
      Pass generic CPUState to gen_intermediate_code()
      queue: Add macro for incremental traversal
      target: [tcg] Add generic translation framework
      target: [tcg,i386] Port to generic translation framework


 include/exec/exec-all.h               |    2 
 include/exec/translate-all_template.h |   58 +++++++
 include/qemu/queue.h                  |    5 +
 include/qom/cpu.h                     |   21 ++
 target-alpha/translate.c              |   11 +
 target-arm/translate.c                |   24 +--
 target-cris/translate.c               |   17 +-
 target-i386/cpu.h                     |    2 
 target-i386/translate.c               |  290 +++++++++++++++------------------
 target-lm32/translate.c               |   22 +--
 target-m68k/translate.c               |   15 +-
 target-microblaze/translate.c         |   24 +--
 target-mips/translate.c               |   15 +-
 target-moxie/translate.c              |   14 +-
 target-openrisc/translate.c           |   24 +--
 target-ppc/translate.c                |   15 +-
 target-s390x/translate.c              |   13 +
 target-sh4/translate.c                |   15 +-
 target-sparc/translate.c              |   11 +
 target-tilegx/translate.c             |    7 -
 target-tricore/translate.c            |    9 -
 target-unicore32/translate.c          |   17 +-
 target-xtensa/translate.c             |   13 +
 translate-all.c                       |    2 
 translate-all_template.h              |  160 ++++++++++++++++++
 25 files changed, 503 insertions(+), 303 deletions(-)
 create mode 100644 include/exec/translate-all_template.h
 create mode 100644 translate-all_template.h


To: qemu-devel@nongnu.org
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Crosthwaite <crosthwaite.peter@gmail.com>
Cc: Richard Henderson <rth@twiddle.net>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 1/4] Pass generic CPUState to gen_intermediate_code()
  2016-07-15 16:12 [Qemu-devel] [RFC PATCH 0/4] translate: [tcg] Generic translation framework Lluís Vilanova
@ 2016-07-15 16:12 ` Lluís Vilanova
  2016-07-18  1:39   ` [Qemu-devel] [Qemu-ppc] " David Gibson
  2016-07-15 16:12 ` [Qemu-devel] [PATCH 2/4] queue: Add macro for incremental traversal Lluís Vilanova
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Lluís Vilanova @ 2016-07-15 16:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Richard Henderson, Peter Crosthwaite, Paolo Bonzini,
	Peter Maydell, Edgar E. Iglesias, Eduardo Habkost, Michael Walle,
	Aurelien Jarno, Leon Alrae, Anthony Green, Jia Liu,
	Alexander Graf, Blue Swirl, Mark Cave-Ayland, Bastian Koppelmann,
	Guan Xuetao, Max Filippov, open list:ARM, open list:PowerPC

Needed to implement a target-agnostic gen_intermediate_code() in the
future.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 include/exec/exec-all.h       |    2 +-
 target-alpha/translate.c      |   11 +++++------
 target-arm/translate.c        |   24 ++++++++++++------------
 target-cris/translate.c       |   17 ++++++++---------
 target-i386/translate.c       |   13 ++++++-------
 target-lm32/translate.c       |   22 +++++++++++-----------
 target-m68k/translate.c       |   15 +++++++--------
 target-microblaze/translate.c |   24 ++++++++++++------------
 target-mips/translate.c       |   15 +++++++--------
 target-moxie/translate.c      |   14 +++++++-------
 target-openrisc/translate.c   |   24 ++++++++++++------------
 target-ppc/translate.c        |   15 +++++++--------
 target-s390x/translate.c      |   13 ++++++-------
 target-sh4/translate.c        |   15 +++++++--------
 target-sparc/translate.c      |   11 +++++------
 target-tilegx/translate.c     |    7 +++----
 target-tricore/translate.c    |    9 ++++-----
 target-unicore32/translate.c  |   17 ++++++++---------
 target-xtensa/translate.c     |   13 ++++++-------
 translate-all.c               |    2 +-
 20 files changed, 135 insertions(+), 148 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 7362095..06c2400 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -66,7 +66,7 @@ typedef struct TranslationBlock TranslationBlock;
 
 #include "qemu/log.h"
 
-void gen_intermediate_code(CPUArchState *env, struct TranslationBlock *tb);
+void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
 void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
                           target_ulong *data);
 
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 5b86992..faeccf8 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -2860,10 +2860,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
     return ret;
 }
 
-void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
 {
-    AlphaCPU *cpu = alpha_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUAlphaState *env = cpu->env_ptr;
     DisasContext ctx, *ctxp = &ctx;
     target_ulong pc_start;
     target_ulong pc_mask;
@@ -2878,7 +2877,7 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
     ctx.pc = pc_start;
     ctx.mem_idx = cpu_mmu_index(env, false);
     ctx.implver = env->implver;
-    ctx.singlestep_enabled = cs->singlestep_enabled;
+    ctx.singlestep_enabled = cpu->singlestep_enabled;
 
 #ifdef CONFIG_USER_ONLY
     ctx.ir = cpu_std_ir;
@@ -2917,7 +2916,7 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
         tcg_gen_insn_start(ctx.pc);
         num_insns++;
 
-        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, ctx.pc, BP_ANY))) {
             ret = gen_excp(&ctx, EXCP_DEBUG, 0);
             /* The address covered by the breakpoint must be included in
                [tb->pc, tb->pc + tb->size) in order to for it to be
@@ -2991,7 +2990,7 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
 #ifdef DEBUG_DISAS
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(cs, pc_start, ctx.pc - pc_start, 1);
+        log_target_disas(cpu, pc_start, ctx.pc - pc_start, 1);
         qemu_log("\n");
     }
 #endif
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 940ec8d..837ceda 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -11587,10 +11587,10 @@ static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
-    ARMCPU *cpu = arm_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUARMState *env = cpu->env_ptr;
+    ARMCPU *arm_cpu = arm_env_get_cpu(env);
     DisasContext dc1, *dc = &dc1;
     target_ulong pc_start;
     target_ulong next_page_start;
@@ -11604,7 +11604,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
      * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
      */
     if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
-        gen_intermediate_code_a64(cpu, tb);
+        gen_intermediate_code_a64(arm_cpu, tb);
         return;
     }
 
@@ -11614,7 +11614,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
 
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
-    dc->singlestep_enabled = cs->singlestep_enabled;
+    dc->singlestep_enabled = cpu->singlestep_enabled;
     dc->condjmp = 0;
 
     dc->aarch64 = 0;
@@ -11639,7 +11639,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
     dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
     dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
     dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
-    dc->cp_regs = cpu->cp_regs;
+    dc->cp_regs = arm_cpu->cp_regs;
     dc->features = env->features;
 
     /* Single step state. The code-generation logic here is:
@@ -11746,9 +11746,9 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
         }
 #endif
 
-        if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
+        if (unlikely(!QTAILQ_EMPTY(&cpu->breakpoints))) {
             CPUBreakpoint *bp;
-            QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
+            QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
                 if (bp->pc == dc->pc) {
                     if (bp->flags & BP_CPU) {
                         gen_set_condexec(dc);
@@ -11838,7 +11838,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
             ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc));
 
     } while (!dc->is_jmp && !tcg_op_buf_full() &&
-             !cs->singlestep_enabled &&
+             !cpu->singlestep_enabled &&
              !singlestep &&
              !dc->ss_active &&
              !end_of_page &&
@@ -11848,7 +11848,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
         if (dc->condjmp) {
             /* FIXME:  This can theoretically happen with self-modifying
                code.  */
-            cpu_abort(cs, "IO on conditional branch instruction");
+            cpu_abort(cpu, "IO on conditional branch instruction");
         }
         gen_io_end();
     }
@@ -11856,7 +11856,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
     /* At this stage dc->condjmp will only be set when the skipped
        instruction was a conditional branch or trap, and the PC has
        already been written.  */
-    if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
+    if (unlikely(cpu->singlestep_enabled || dc->ss_active)) {
         /* Unconditional and "condition passed" instruction codepath. */
         gen_set_condexec(dc);
         switch (dc->is_jmp) {
@@ -11962,7 +11962,7 @@ done_generating:
         qemu_log_in_addr_range(pc_start)) {
         qemu_log("----------------\n");
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(cs, pc_start, dc->pc - pc_start,
+        log_target_disas(cpu, pc_start, dc->pc - pc_start,
                          dc->thumb | (dc->sctlr_b << 1));
         qemu_log("\n");
     }
diff --git a/target-cris/translate.c b/target-cris/translate.c
index a73176c..90d63c1 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3071,10 +3071,9 @@ static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
  */
 
 /* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
 {
-    CRISCPU *cpu = cris_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUCRISState *env = cpu->env_ptr;
     uint32_t pc_start;
     unsigned int insn_len;
     struct DisasContext ctx;
@@ -3096,13 +3095,13 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
      * delayslot, like in real hw.
      */
     pc_start = tb->pc & ~1;
-    dc->cpu = cpu;
+    dc->cpu = cris_env_get_cpu(env);
     dc->tb = tb;
 
     dc->is_jmp = DISAS_NEXT;
     dc->ppc = pc_start;
     dc->pc = pc_start;
-    dc->singlestep_enabled = cs->singlestep_enabled;
+    dc->singlestep_enabled = cpu->singlestep_enabled;
     dc->flags_uptodate = 1;
     dc->flagx_known = 1;
     dc->flags_x = tb->flags & X_FLAG;
@@ -3165,7 +3164,7 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
                            ? dc->ppc | 1 : dc->pc);
         num_insns++;
 
-        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
             cris_evaluate_flags(dc);
             tcg_gen_movi_tl(env_pc, dc->pc);
             t_gen_raise_exception(EXCP_DEBUG);
@@ -3239,7 +3238,7 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
 
         /* If we are rexecuting a branch due to exceptions on
            delay slots dont break.  */
-        if (!(tb->pc & 1) && cs->singlestep_enabled) {
+        if (!(tb->pc & 1) && cpu->singlestep_enabled) {
             break;
         }
     } while (!dc->is_jmp && !dc->cpustate_changed
@@ -3272,7 +3271,7 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
 
     cris_evaluate_flags(dc);
 
-    if (unlikely(cs->singlestep_enabled)) {
+    if (unlikely(cpu->singlestep_enabled)) {
         if (dc->is_jmp == DISAS_NEXT) {
             tcg_gen_movi_tl(env_pc, npc);
         }
@@ -3303,7 +3302,7 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
 #ifdef DEBUG_DISAS
 #if !DISAS_CRIS
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
-        log_target_disas(cs, pc_start, dc->pc - pc_start,
+        log_target_disas(cpu, pc_start, dc->pc - pc_start,
                          env->pregs[PR_VR]);
         qemu_log("\nisize=%d osize=%d\n",
                  dc->pc - pc_start, tcg_op_buf_count());
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 1a1214d..68e2593 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -8172,10 +8172,9 @@ void tcg_x86_init(void)
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
-    X86CPU *cpu = x86_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUX86State *env = cpu->env_ptr;
     DisasContext dc1, *dc = &dc1;
     target_ulong pc_ptr;
     uint64_t flags;
@@ -8198,7 +8197,7 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
     dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
     dc->iopl = (flags >> IOPL_SHIFT) & 3;
     dc->tf = (flags >> TF_SHIFT) & 1;
-    dc->singlestep_enabled = cs->singlestep_enabled;
+    dc->singlestep_enabled = cpu->singlestep_enabled;
     dc->cc_op = CC_OP_DYNAMIC;
     dc->cc_op_dirty = false;
     dc->cs_base = cs_base;
@@ -8220,7 +8219,7 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
     dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
 #endif
     dc->flags = flags;
-    dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
+    dc->jmp_opt = !(dc->tf || cpu->singlestep_enabled ||
                     (flags & HF_INHIBIT_IRQ_MASK)
 #ifndef CONFIG_SOFTMMU
                     || (flags & HF_SOFTMMU_MASK)
@@ -8273,7 +8272,7 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
         num_insns++;
 
         /* If RF is set, suppress an internally generated breakpoint.  */
-        if (unlikely(cpu_breakpoint_test(cs, pc_ptr,
+        if (unlikely(cpu_breakpoint_test(cpu, pc_ptr,
                                          tb->flags & HF_RF_MASK
                                          ? BP_GDB : BP_ANY))) {
             gen_debug(dc, pc_ptr - dc->cs_base);
@@ -8347,7 +8346,7 @@ done_generating:
         else
 #endif
             disas_flags = !dc->code32;
-        log_target_disas(cs, pc_start, pc_ptr - pc_start, disas_flags);
+        log_target_disas(cpu, pc_start, pc_ptr - pc_start, disas_flags);
         qemu_log("\n");
     }
 #endif
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 256a51f..9721d31 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1035,10 +1035,10 @@ static inline void decode(DisasContext *dc, uint32_t ir)
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
 {
-    LM32CPU *cpu = lm32_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPULM32State *env = cpu->env_ptr;
+    LM32CPU *lm32_cpu = lm32_env_get_cpu(env);
     struct DisasContext ctx, *dc = &ctx;
     uint32_t pc_start;
     uint32_t next_page_start;
@@ -1046,14 +1046,14 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
     int max_insns;
 
     pc_start = tb->pc;
-    dc->features = cpu->features;
-    dc->num_breakpoints = cpu->num_breakpoints;
-    dc->num_watchpoints = cpu->num_watchpoints;
+    dc->features = lm32_cpu->features;
+    dc->num_breakpoints = lm32_cpu->num_breakpoints;
+    dc->num_watchpoints = lm32_cpu->num_watchpoints;
     dc->tb = tb;
 
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
-    dc->singlestep_enabled = cs->singlestep_enabled;
+    dc->singlestep_enabled = cpu->singlestep_enabled;
 
     if (pc_start & 3) {
         qemu_log_mask(LOG_GUEST_ERROR,
@@ -1076,7 +1076,7 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
         tcg_gen_insn_start(dc->pc);
         num_insns++;
 
-        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
             t_gen_raise_exception(dc, EXCP_DEBUG);
             dc->is_jmp = DISAS_UPDATE;
@@ -1099,7 +1099,7 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
         dc->pc += 4;
     } while (!dc->is_jmp
          && !tcg_op_buf_full()
-         && !cs->singlestep_enabled
+         && !cpu->singlestep_enabled
          && !singlestep
          && (dc->pc < next_page_start)
          && num_insns < max_insns);
@@ -1108,7 +1108,7 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
         gen_io_end();
     }
 
-    if (unlikely(cs->singlestep_enabled)) {
+    if (unlikely(cpu->singlestep_enabled)) {
         if (dc->is_jmp == DISAS_NEXT) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
         }
@@ -1139,7 +1139,7 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
 #ifdef DEBUG_DISAS
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("\n");
-        log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
+        log_target_disas(cpu, pc_start, dc->pc - pc_start, 0);
         qemu_log("\nisize=%d osize=%d\n",
                  dc->pc - pc_start, tcg_op_buf_count());
     }
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 7560c3a..a3aaef2 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2968,10 +2968,9 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
-    M68kCPU *cpu = m68k_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUM68KState *env = cpu->env_ptr;
     DisasContext dc1, *dc = &dc1;
     target_ulong pc_start;
     int pc_offset;
@@ -2987,7 +2986,7 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
     dc->cc_op = CC_OP_DYNAMIC;
-    dc->singlestep_enabled = cs->singlestep_enabled;
+    dc->singlestep_enabled = cpu->singlestep_enabled;
     dc->fpcr = env->fpcr;
     dc->user = (env->sr & SR_S) == 0;
     dc->done_mac = 0;
@@ -3007,7 +3006,7 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
         tcg_gen_insn_start(dc->pc);
         num_insns++;
 
-        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
             gen_exception(dc, dc->pc, EXCP_DEBUG);
             dc->is_jmp = DISAS_JUMP;
             /* The address covered by the breakpoint must be included in
@@ -3025,14 +3024,14 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
         dc->insn_pc = dc->pc;
 	disas_m68k_insn(env, dc);
     } while (!dc->is_jmp && !tcg_op_buf_full() &&
-             !cs->singlestep_enabled &&
+             !cpu->singlestep_enabled &&
              !singlestep &&
              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
              num_insns < max_insns);
 
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
-    if (unlikely(cs->singlestep_enabled)) {
+    if (unlikely(cpu->singlestep_enabled)) {
         /* Make sure the pc is updated, and raise a debug exception.  */
         if (!dc->is_jmp) {
             gen_flush_cc_op(dc);
@@ -3063,7 +3062,7 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("----------------\n");
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
+        log_target_disas(cpu, pc_start, dc->pc - pc_start, 0);
         qemu_log("\n");
     }
 #endif
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index f944965..201e9fd 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1629,10 +1629,10 @@ static inline void decode(DisasContext *dc, uint32_t ir)
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
 {
-    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUMBState *env = cpu->env_ptr;
+    MicroBlazeCPU *mb_cpu = mb_env_get_cpu(env);
     uint32_t pc_start;
     struct DisasContext ctx;
     struct DisasContext *dc = &ctx;
@@ -1642,7 +1642,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
     int max_insns;
 
     pc_start = tb->pc;
-    dc->cpu = cpu;
+    dc->cpu = mb_cpu;
     dc->tb = tb;
     org_flags = dc->synced_flags = dc->tb_flags = tb->flags;
 
@@ -1653,19 +1653,19 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
         dc->jmp = JMP_INDIRECT;
     }
     dc->pc = pc_start;
-    dc->singlestep_enabled = cs->singlestep_enabled;
+    dc->singlestep_enabled = cpu->singlestep_enabled;
     dc->cpustate_changed = 0;
     dc->abort_at_next_insn = 0;
     dc->nr_nops = 0;
 
     if (pc_start & 3) {
-        cpu_abort(cs, "Microblaze: unaligned PC=%x\n", pc_start);
+        cpu_abort(cpu, "Microblaze: unaligned PC=%x\n", pc_start);
     }
 
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
 #if !SIM_COMPAT
         qemu_log("--------------\n");
-        log_cpu_state(CPU(cpu), 0);
+        log_cpu_state(CPU(mb_cpu), 0);
 #endif
     }
 
@@ -1692,7 +1692,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
         }
 #endif
 
-        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
             t_gen_raise_exception(dc, EXCP_DEBUG);
             dc->is_jmp = DISAS_UPDATE;
             /* The address covered by the breakpoint must be included in
@@ -1749,7 +1749,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
                 break;
             }
         }
-        if (cs->singlestep_enabled) {
+        if (cpu->singlestep_enabled) {
             break;
         }
     } while (!dc->is_jmp && !dc->cpustate_changed
@@ -1770,7 +1770,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
 
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
-    /* Force an update if the per-tb cpu state has changed.  */
+    /* Force an update if the per-tb mb_cpu state has changed.  */
     if (dc->is_jmp == DISAS_NEXT
         && (dc->cpustate_changed || org_flags != dc->tb_flags)) {
         dc->is_jmp = DISAS_UPDATE;
@@ -1778,7 +1778,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
     }
     t_sync_flags(dc);
 
-    if (unlikely(cs->singlestep_enabled)) {
+    if (unlikely(cpu->singlestep_enabled)) {
         TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
 
         if (dc->is_jmp != DISAS_JUMP) {
@@ -1813,7 +1813,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("\n");
 #if DISAS_GNU
-        log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
+        log_target_disas(cpu, pc_start, dc->pc - pc_start, 0);
 #endif
         qemu_log("\nisize=%d osize=%d\n",
                  dc->pc - pc_start, tcg_op_buf_count());
diff --git a/target-mips/translate.c b/target-mips/translate.c
index a3a05ec..2c2f14a 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -19737,10 +19737,9 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
     }
 }
 
-void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
 {
-    MIPSCPU *cpu = mips_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUMIPSState *env = cpu->env_ptr;
     DisasContext ctx;
     target_ulong pc_start;
     target_ulong next_page_start;
@@ -19753,7 +19752,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
     ctx.pc = pc_start;
     ctx.saved_pc = -1;
-    ctx.singlestep_enabled = cs->singlestep_enabled;
+    ctx.singlestep_enabled = cpu->singlestep_enabled;
     ctx.insn_flags = env->insn_flags;
     ctx.CP0_Config1 = env->CP0_Config1;
     ctx.tb = tb;
@@ -19798,7 +19797,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
         tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
         num_insns++;
 
-        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, ctx.pc, BP_ANY))) {
             save_cpu_state(&ctx, 1);
             ctx.bstate = BS_BRANCH;
             gen_helper_raise_exception_debug(cpu_env);
@@ -19853,7 +19852,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
            This is what GDB expects and is consistent with what the
            hardware does (e.g. if a delay slot instruction faults, the
            reported PC is the PC of the branch).  */
-        if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
+        if (cpu->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
             break;
         }
 
@@ -19874,7 +19873,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
     if (tb->cflags & CF_LAST_IO) {
         gen_io_end();
     }
-    if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
+    if (cpu->singlestep_enabled && ctx.bstate != BS_BRANCH) {
         save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
         gen_helper_raise_exception_debug(cpu_env);
     } else {
@@ -19904,7 +19903,7 @@ done_generating:
     LOG_DISAS("\n");
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
+        log_target_disas(cpu, pc_start, ctx.pc - pc_start, 0);
         qemu_log("\n");
     }
 #endif
diff --git a/target-moxie/translate.c b/target-moxie/translate.c
index a437e2a..19f7453 100644
--- a/target-moxie/translate.c
+++ b/target-moxie/translate.c
@@ -812,10 +812,10 @@ static int decode_opc(MoxieCPU *cpu, DisasContext *ctx)
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUMoxieState *env, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
 {
-    MoxieCPU *cpu = moxie_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUMoxieState *env = cpu->env_ptr;
+    MoxieCPU *moxie_cpu = moxie_env_get_cpu(env);
     DisasContext ctx;
     target_ulong pc_start;
     int num_insns, max_insns;
@@ -841,7 +841,7 @@ void gen_intermediate_code(CPUMoxieState *env, struct TranslationBlock *tb)
         tcg_gen_insn_start(ctx.pc);
         num_insns++;
 
-        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, ctx.pc, BP_ANY))) {
             tcg_gen_movi_i32(cpu_pc, ctx.pc);
             gen_helper_debug(cpu_env);
             ctx.bstate = BS_EXCP;
@@ -854,12 +854,12 @@ void gen_intermediate_code(CPUMoxieState *env, struct TranslationBlock *tb)
         }
 
         ctx.opcode = cpu_lduw_code(env, ctx.pc);
-        ctx.pc += decode_opc(cpu, &ctx);
+        ctx.pc += decode_opc(moxie_cpu, &ctx);
 
         if (num_insns >= max_insns) {
             break;
         }
-        if (cs->singlestep_enabled) {
+        if (cpu->singlestep_enabled) {
             break;
         }
         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) {
@@ -867,7 +867,7 @@ void gen_intermediate_code(CPUMoxieState *env, struct TranslationBlock *tb)
         }
     } while (ctx.bstate == BS_NONE && !tcg_op_buf_full());
 
-    if (cs->singlestep_enabled) {
+    if (cpu->singlestep_enabled) {
         tcg_gen_movi_tl(cpu_pc, ctx.pc);
         gen_helper_debug(cpu_env);
     } else {
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 5d0ab44..b441625 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1619,10 +1619,10 @@ static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
     }
 }
 
-void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
 {
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUOpenRISCState *env = cpu->env_ptr;
+    OpenRISCCPU *or_cpu = openrisc_env_get_cpu(env);
     struct DisasContext ctx, *dc = &ctx;
     uint32_t pc_start;
     uint32_t next_page_start;
@@ -1635,14 +1635,14 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
     dc->is_jmp = DISAS_NEXT;
     dc->ppc = pc_start;
     dc->pc = pc_start;
-    dc->flags = cpu->env.cpucfgr;
-    dc->mem_idx = cpu_mmu_index(&cpu->env, false);
+    dc->flags = or_cpu->env.cpucfgr;
+    dc->mem_idx = cpu_mmu_index(&or_cpu->env, false);
     dc->synced_flags = dc->tb_flags = tb->flags;
     dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
-    dc->singlestep_enabled = cs->singlestep_enabled;
+    dc->singlestep_enabled = cpu->singlestep_enabled;
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("-----------------------------------------\n");
-        log_cpu_state(CPU(cpu), 0);
+        log_cpu_state(CPU(or_cpu), 0);
     }
 
     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
@@ -1662,7 +1662,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
         tcg_gen_insn_start(dc->pc);
         num_insns++;
 
-        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
             gen_exception(dc, EXCP_DEBUG);
             dc->is_jmp = DISAS_UPDATE;
@@ -1681,7 +1681,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
         dc->npc = dc->pc + 4;
         tcg_gen_movi_tl(cpu_ppc, dc->ppc);
         tcg_gen_movi_tl(cpu_npc, dc->npc);
-        disas_openrisc_insn(dc, cpu);
+        disas_openrisc_insn(dc, or_cpu);
         dc->pc = dc->npc;
         /* delay slot */
         if (dc->delayed_branch) {
@@ -1699,7 +1699,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
         }
     } while (!dc->is_jmp
              && !tcg_op_buf_full()
-             && !cs->singlestep_enabled
+             && !cpu->singlestep_enabled
              && !singlestep
              && (dc->pc < next_page_start)
              && num_insns < max_insns);
@@ -1711,7 +1711,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
         dc->is_jmp = DISAS_UPDATE;
         tcg_gen_movi_tl(cpu_pc, dc->pc);
     }
-    if (unlikely(cs->singlestep_enabled)) {
+    if (unlikely(cpu->singlestep_enabled)) {
         if (dc->is_jmp == DISAS_NEXT) {
             tcg_gen_movi_tl(cpu_pc, dc->pc);
         }
@@ -1743,7 +1743,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
 #ifdef DEBUG_DISAS
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("\n");
-        log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
+        log_target_disas(cpu, pc_start, dc->pc - pc_start, 0);
         qemu_log("\nisize=%d osize=%d\n",
                  dc->pc - pc_start, tcg_op_buf_count());
     }
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index b3860ec..bad896e 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -11438,10 +11438,9 @@ void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
 }
 
 /*****************************************************************************/
-void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
 {
-    PowerPCCPU *cpu = ppc_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUPPCState *env = cpu->env_ptr;
     DisasContext ctx, *ctxp = &ctx;
     opc_handler_t **table, *handler;
     target_ulong pc_start;
@@ -11492,7 +11491,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
         ctx.singlestep_enabled = 0;
     if ((env->flags & POWERPC_FLAG_BE) && msr_be)
         ctx.singlestep_enabled |= CPU_BRANCH_STEP;
-    if (unlikely(cs->singlestep_enabled)) {
+    if (unlikely(cpu->singlestep_enabled)) {
         ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
     }
 #if defined (DO_SINGLE_STEP) && 0
@@ -11515,7 +11514,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
         tcg_gen_insn_start(ctx.nip);
         num_insns++;
 
-        if (unlikely(cpu_breakpoint_test(cs, ctx.nip, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, ctx.nip, BP_ANY))) {
             gen_debug_exception(ctxp);
             /* The address covered by the breakpoint must be included in
                [tb->pc, tb->pc + tb->size) in order to for it to be
@@ -11586,7 +11585,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
                      ctx.exception != POWERPC_EXCP_BRANCH)) {
             gen_exception(ctxp, POWERPC_EXCP_TRACE);
         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
-                            (cs->singlestep_enabled) ||
+                            (cpu->singlestep_enabled) ||
                             singlestep ||
                             num_insns >= max_insns)) {
             /* if we reach a page boundary or are single stepping, stop
@@ -11606,7 +11605,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
     if (ctx.exception == POWERPC_EXCP_NONE) {
         gen_goto_tb(&ctx, 0, ctx.nip);
     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
-        if (unlikely(cs->singlestep_enabled)) {
+        if (unlikely(cpu->singlestep_enabled)) {
             gen_debug_exception(ctxp);
         }
         /* Generate the return instruction */
@@ -11623,7 +11622,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
         flags = env->bfd_mach;
         flags |= ctx.le_mode << 16;
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(cs, pc_start, ctx.nip - pc_start, flags);
+        log_target_disas(cpu, pc_start, ctx.nip - pc_start, flags);
         qemu_log("\n");
     }
 #endif
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index c871ef2..9aac7cd 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -5319,10 +5319,9 @@ static ExitStatus translate_one(CPUS390XState *env, DisasContext *s)
     return ret;
 }
 
-void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
 {
-    S390CPU *cpu = s390_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUS390XState *env = cpu->env_ptr;
     DisasContext dc;
     target_ulong pc_start;
     uint64_t next_page_start;
@@ -5340,7 +5339,7 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
     dc.tb = tb;
     dc.pc = pc_start;
     dc.cc_op = CC_OP_DYNAMIC;
-    do_debug = dc.singlestep_enabled = cs->singlestep_enabled;
+    do_debug = dc.singlestep_enabled = cpu->singlestep_enabled;
 
     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
 
@@ -5359,7 +5358,7 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
         tcg_gen_insn_start(dc.pc, dc.cc_op);
         num_insns++;
 
-        if (unlikely(cpu_breakpoint_test(cs, dc.pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, dc.pc, BP_ANY))) {
             status = EXIT_PC_STALE;
             do_debug = true;
             /* The address covered by the breakpoint must be included in
@@ -5386,7 +5385,7 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
                 || tcg_op_buf_full()
                 || num_insns >= max_insns
                 || singlestep
-                || cs->singlestep_enabled)) {
+                || cpu->singlestep_enabled)) {
             status = EXIT_PC_STALE;
         }
     } while (status == NO_EXIT);
@@ -5425,7 +5424,7 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
 #if defined(S390X_DEBUG_DISAS)
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(cs, pc_start, dc.pc - pc_start, 1);
+        log_target_disas(cpu, pc_start, dc.pc - pc_start, 1);
         qemu_log("\n");
     }
 #endif
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 7c18968..5c7fa2c 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -1816,10 +1816,9 @@ static void decode_opc(DisasContext * ctx)
         gen_store_flags(ctx->flags);
 }
 
-void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
 {
-    SuperHCPU *cpu = sh_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUSH4State * env = cpu->env_ptr;
     DisasContext ctx;
     target_ulong pc_start;
     int num_insns;
@@ -1834,7 +1833,7 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
        so assume it is a dynamic branch.  */
     ctx.delayed_pc = -1; /* use delayed pc from env pointer */
     ctx.tb = tb;
-    ctx.singlestep_enabled = cs->singlestep_enabled;
+    ctx.singlestep_enabled = cpu->singlestep_enabled;
     ctx.features = env->features;
     ctx.has_movcal = (ctx.flags & TB_FLAG_PENDING_MOVCA);
 
@@ -1852,7 +1851,7 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
         tcg_gen_insn_start(ctx.pc, ctx.flags);
         num_insns++;
 
-        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, ctx.pc, BP_ANY))) {
             /* We have hit a breakpoint - make sure PC is up-to-date */
             tcg_gen_movi_i32(cpu_pc, ctx.pc);
             gen_helper_debug(cpu_env);
@@ -1874,7 +1873,7 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
 	ctx.pc += 2;
 	if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
 	    break;
-        if (cs->singlestep_enabled) {
+        if (cpu->singlestep_enabled) {
 	    break;
         }
         if (num_insns >= max_insns)
@@ -1884,7 +1883,7 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
-    if (cs->singlestep_enabled) {
+    if (cpu->singlestep_enabled) {
         tcg_gen_movi_i32(cpu_pc, ctx.pc);
         gen_helper_debug(cpu_env);
     } else {
@@ -1916,7 +1915,7 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
 #ifdef DEBUG_DISAS
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
 	qemu_log("IN:\n");	/* , lookup_symbol(pc_start)); */
-        log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
+        log_target_disas(cpu, pc_start, ctx.pc - pc_start, 0);
 	qemu_log("\n");
     }
 #endif
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 7998ff5..cc634ce 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5217,10 +5217,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
     }
 }
 
-void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
+void gen_intermediate_code(CPUState *cpu, TranslationBlock * tb)
 {
-    SPARCCPU *cpu = sparc_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUSPARCState * env = cpu->env_ptr;
     target_ulong pc_start, last_pc;
     DisasContext dc1, *dc = &dc1;
     int num_insns;
@@ -5238,7 +5237,7 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
     dc->def = env->def;
     dc->fpu_enabled = tb_fpu_enabled(tb->flags);
     dc->address_mask_32bit = tb_am_enabled(tb->flags);
-    dc->singlestep = (cs->singlestep_enabled || singlestep);
+    dc->singlestep = (cpu->singlestep_enabled || singlestep);
 
     num_insns = 0;
     max_insns = tb->cflags & CF_COUNT_MASK;
@@ -5260,7 +5259,7 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
         num_insns++;
         last_pc = dc->pc;
 
-        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
             if (dc->pc != pc_start) {
                 save_state(dc);
             }
@@ -5322,7 +5321,7 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("--------------\n");
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(cs, pc_start, last_pc + 4 - pc_start, 0);
+        log_target_disas(cpu, pc_start, last_pc + 4 - pc_start, 0);
         qemu_log("\n");
     }
 #endif
diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 03918eb..afb248d 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -2369,12 +2369,11 @@ static void translate_one_bundle(DisasContext *dc, uint64_t bundle)
     }
 }
 
-void gen_intermediate_code(CPUTLGState *env, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
 {
-    TileGXCPU *cpu = tilegx_env_get_cpu(env);
+    CPUTLGState *env = cpu->env_ptr;
     DisasContext ctx;
     DisasContext *dc = &ctx;
-    CPUState *cs = CPU(cpu);
     uint64_t pc_start = tb->pc;
     uint64_t next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
     int num_insns = 0;
@@ -2395,7 +2394,7 @@ void gen_intermediate_code(CPUTLGState *env, struct TranslationBlock *tb)
     if (!max_insns) {
         max_insns = CF_COUNT_MASK;
     }
-    if (cs->singlestep_enabled || singlestep) {
+    if (cpu->singlestep_enabled || singlestep) {
         max_insns = 1;
     }
     if (max_insns > TCG_MAX_INSNS) {
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 912bf22..c852ec6 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -8722,10 +8722,9 @@ static void decode_opc(CPUTriCoreState *env, DisasContext *ctx, int *is_branch)
     }
 }
 
-void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
 {
-    TriCoreCPU *cpu = tricore_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUTriCoreState *env = cpu->env_ptr;
     DisasContext ctx;
     target_ulong pc_start;
     int num_insns, max_insns;
@@ -8746,7 +8745,7 @@ void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb)
     ctx.pc = pc_start;
     ctx.saved_pc = -1;
     ctx.tb = tb;
-    ctx.singlestep_enabled = cs->singlestep_enabled;
+    ctx.singlestep_enabled = cpu->singlestep_enabled;
     ctx.bstate = BS_NONE;
     ctx.mem_idx = cpu_mmu_index(env, false);
 
@@ -8778,7 +8777,7 @@ void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb)
 #ifdef DEBUG_DISAS
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
+        log_target_disas(cpu, pc_start, ctx.pc - pc_start, 0);
         qemu_log("\n");
     }
 #endif
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 39af3af..cbe6bc2 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -1861,10 +1861,9 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
-    UniCore32CPU *cpu = uc32_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUUniCore32State *env = cpu->env_ptr;
     DisasContext dc1, *dc = &dc1;
     target_ulong pc_start;
     uint32_t next_page_start;
@@ -1880,7 +1879,7 @@ void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
 
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
-    dc->singlestep_enabled = cs->singlestep_enabled;
+    dc->singlestep_enabled = cpu->singlestep_enabled;
     dc->condjmp = 0;
     cpu_F0s = tcg_temp_new_i32();
     cpu_F1s = tcg_temp_new_i32();
@@ -1909,7 +1908,7 @@ void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
         tcg_gen_insn_start(dc->pc);
         num_insns++;
 
-        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
             gen_set_pc_im(dc->pc);
             gen_exception(EXCP_DEBUG);
             dc->is_jmp = DISAS_JUMP;
@@ -1941,7 +1940,7 @@ void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
          * Also stop translation when a page boundary is reached.  This
          * ensures prefetch aborts occur at the right place.  */
     } while (!dc->is_jmp && !tcg_op_buf_full() &&
-             !cs->singlestep_enabled &&
+             !cpu->singlestep_enabled &&
              !singlestep &&
              dc->pc < next_page_start &&
              num_insns < max_insns);
@@ -1950,7 +1949,7 @@ void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
         if (dc->condjmp) {
             /* FIXME:  This can theoretically happen with self-modifying
                code.  */
-            cpu_abort(cs, "IO on conditional branch instruction");
+            cpu_abort(cpu, "IO on conditional branch instruction");
         }
         gen_io_end();
     }
@@ -1958,7 +1957,7 @@ void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
     /* At this stage dc->condjmp will only be set when the skipped
        instruction was a conditional branch or trap, and the PC has
        already been written.  */
-    if (unlikely(cs->singlestep_enabled)) {
+    if (unlikely(cpu->singlestep_enabled)) {
         /* Make sure the pc is updated, and raise a debug exception.  */
         if (dc->condjmp) {
             if (dc->is_jmp == DISAS_SYSCALL) {
@@ -2017,7 +2016,7 @@ done_generating:
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("----------------\n");
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
+        log_target_disas(cpu, pc_start, dc->pc - pc_start, 0);
         qemu_log("\n");
     }
 #endif
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 9894488..51803d5 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -3031,10 +3031,9 @@ static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
     }
 }
 
-void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
-    XtensaCPU *cpu = xtensa_env_get_cpu(env);
-    CPUState *cs = CPU(cpu);
+    CPUXtensaState *env = cpu->env_ptr;
     DisasContext dc;
     int insn_count = 0;
     int max_insns = tb->cflags & CF_COUNT_MASK;
@@ -3050,7 +3049,7 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
     }
 
     dc.config = env->config;
-    dc.singlestep_enabled = cs->singlestep_enabled;
+    dc.singlestep_enabled = cpu->singlestep_enabled;
     dc.tb = tb;
     dc.pc = pc_start;
     dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK;
@@ -3085,7 +3084,7 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
 
         ++dc.ccount_delta;
 
-        if (unlikely(cpu_breakpoint_test(cs, dc.pc, BP_ANY))) {
+        if (unlikely(cpu_breakpoint_test(cpu, dc.pc, BP_ANY))) {
             tcg_gen_movi_i32(cpu_pc, dc.pc);
             gen_exception(&dc, EXCP_DEBUG);
             dc.is_jmp = DISAS_UPDATE;
@@ -3121,7 +3120,7 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
         if (dc.icount) {
             tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount);
         }
-        if (cs->singlestep_enabled) {
+        if (cpu->singlestep_enabled) {
             tcg_gen_movi_i32(cpu_pc, dc.pc);
             gen_exception(&dc, EXCP_DEBUG);
             break;
@@ -3151,7 +3150,7 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("----------------\n");
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(cs, pc_start, dc.pc - pc_start, 0);
+        log_target_disas(cpu, pc_start, dc.pc - pc_start, 0);
         qemu_log("\n");
     }
 #endif
diff --git a/translate-all.c b/translate-all.c
index 8329ea6..940652c 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1094,7 +1094,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
 
     tcg_func_start(&tcg_ctx);
 
-    gen_intermediate_code(env, tb);
+    gen_intermediate_code(cpu, tb);
 
     trace_translate_block(tb, tb->pc, tb->tc_ptr);
 

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 2/4] queue: Add macro for incremental traversal
  2016-07-15 16:12 [Qemu-devel] [RFC PATCH 0/4] translate: [tcg] Generic translation framework Lluís Vilanova
  2016-07-15 16:12 ` [Qemu-devel] [PATCH 1/4] Pass generic CPUState to gen_intermediate_code() Lluís Vilanova
@ 2016-07-15 16:12 ` Lluís Vilanova
  2016-07-15 16:12 ` [Qemu-devel] [PATCH 3/4] target: [tcg] Add generic translation framework Lluís Vilanova
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Lluís Vilanova @ 2016-07-15 16:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Richard Henderson, Peter Crosthwaite, Paolo Bonzini

Adds macro QTAILQ_FOREACH_CONTINUE to support incremental list
traversal.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 include/qemu/queue.h |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index f781aa2..c19f7ee 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -414,6 +414,11 @@ struct {                                                                \
                 (var);                                                  \
                 (var) = ((var)->field.tqe_next))
 
+#define QTAILQ_FOREACH_CONTINUE(var, field)                             \
+        for ((var) = ((var)->field.tqe_next);                           \
+                (var);                                                  \
+                (var) = ((var)->field.tqe_next))
+
 #define QTAILQ_FOREACH_SAFE(var, head, field, next_var)                 \
         for ((var) = ((head)->tqh_first);                               \
                 (var) && ((next_var) = ((var)->field.tqe_next), 1);     \

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 3/4] target: [tcg] Add generic translation framework
  2016-07-15 16:12 [Qemu-devel] [RFC PATCH 0/4] translate: [tcg] Generic translation framework Lluís Vilanova
  2016-07-15 16:12 ` [Qemu-devel] [PATCH 1/4] Pass generic CPUState to gen_intermediate_code() Lluís Vilanova
  2016-07-15 16:12 ` [Qemu-devel] [PATCH 2/4] queue: Add macro for incremental traversal Lluís Vilanova
@ 2016-07-15 16:12 ` Lluís Vilanova
  2016-07-18 13:10   ` Richard Henderson
  2016-07-15 16:12 ` [Qemu-devel] [PATCH 4/4] target: [tcg, i386] Port to " Lluís Vilanova
  2016-07-15 16:27 ` [Qemu-devel] [RFC PATCH 0/4] translate: [tcg] Generic " Lluís Vilanova
  4 siblings, 1 reply; 9+ messages in thread
From: Lluís Vilanova @ 2016-07-15 16:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Richard Henderson, Peter Crosthwaite, Paolo Bonzini, Andreas Färber

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 include/exec/translate-all_template.h |   58 ++++++++++++
 include/qom/cpu.h                     |   21 ++++
 translate-all_template.h              |  160 +++++++++++++++++++++++++++++++++
 3 files changed, 239 insertions(+)
 create mode 100644 include/exec/translate-all_template.h
 create mode 100644 translate-all_template.h

diff --git a/include/exec/translate-all_template.h b/include/exec/translate-all_template.h
new file mode 100644
index 0000000..9e0c361
--- /dev/null
+++ b/include/exec/translate-all_template.h
@@ -0,0 +1,58 @@
+/*
+ * Generic intermediate code generation.
+ *
+ * Copyright (C) 2016 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef EXEC__TRANSLATE_ALL_TEMPLATE_H
+#define EXEC__TRANSLATE_ALL_TEMPLATE_H
+
+/*
+ * Include this header from a target-specific file, and add a
+ *
+ *     DisasContextBase base;
+ *
+ * member in your target-specific DisasContext.
+ */
+
+
+#include "exec/exec-all.h"
+
+
+/**
+ * DisasJumpType:
+ * @DJ_NEXT: Next instruction in program order
+ * @DJ_TOO_MANY: Too many instructions executed
+ * @DJ_TARGET: Start of target-specific conditions
+ *
+ * What instruction to disassemble next.
+ */
+typedef enum DisasJumpType
+{
+    DJ_NEXT,
+    DJ_TOO_MANY,
+    DJ_TARGET,
+} DisasJumpType;
+
+/**
+ * DisasContextBase:
+ * @tb: Translation block for this disassembly.
+ * @singlestep_enabled: "Hardware" single stepping enabled.
+ * @pc_first: Address of first guest instruction in this TB.
+ * @pc_next: Address of next guest instruction in this TB.
+ *
+ * Architecture-agnostic disassembly context.
+ */
+typedef struct DisasContextBase
+{
+    TranslationBlock *tb;
+    bool singlestep_enabled;
+    target_ulong pc_first;
+    target_ulong pc_next;
+    DisasJumpType jmp_type;
+} DisasContextBase;
+
+#endif  /* EXEC__TRANSLATE_ALL_TEMPLATE_H */
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index b7a10f7..de20927 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -808,6 +808,27 @@ static inline bool cpu_breakpoint_test(CPUState *cpu, vaddr pc, int mask)
     return false;
 }
 
+/* Get first breakpoint matching a PC */
+static inline CPUBreakpoint *cpu_breakpoint_get(CPUState *cpu, vaddr pc, CPUBreakpoint *bp)
+{
+    if (likely(bp == NULL)) {
+        if (unlikely(!QTAILQ_EMPTY(&cpu->breakpoints))) {
+            QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
+                if (bp->pc == pc) {
+                    return bp;
+                }
+            }
+        }
+    } else {
+        QTAILQ_FOREACH_CONTINUE(bp, entry) {
+            if (bp->pc == pc) {
+                return bp;
+            }
+        }
+    }
+    return NULL;
+}
+
 int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
                           int flags, CPUWatchpoint **watchpoint);
 int cpu_watchpoint_remove(CPUState *cpu, vaddr addr,
diff --git a/translate-all_template.h b/translate-all_template.h
new file mode 100644
index 0000000..afbd088
--- /dev/null
+++ b/translate-all_template.h
@@ -0,0 +1,160 @@
+/*
+ * Generic intermediate code generation.
+ *
+ * Copyright (C) 2016 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef TRANSLATE_ALL_TEMPLATE_H
+#define TRANSLATE_ALL_TEMPLATE_H
+
+/*
+ * Include this header from a target-specific file, which must define the
+ * target-specific functions declared below.
+ *
+ * These must be paired with instructions in "exec/translate-all_template.h".
+ */
+
+
+#include "cpu.h"
+
+
+static void gen_intermediate_code_target_init_disas_context(
+    DisasContext * restrict dc, const CPUArchState * restrict env);
+
+static void gen_intermediate_code_target_init_globals(
+    DisasContext * restrict dc, const CPUArchState * restrict env);
+
+static bool gen_intermediate_code_target_breakpoint_hit(
+    DisasContext * restrict dc, const CPUArchState * restrict env,
+    const CPUBreakpoint * restrict bp);
+
+static DisasJumpType gen_intermediate_code_target_stop_check(
+    DisasContext * restrict dc, const CPUArchState * restrict env);
+
+static void gen_intermediate_code_target_stop(
+    DisasContext * restrict dc, const CPUArchState * restrict env);
+
+static int gen_intermediate_code_target_get_disas_flags(
+    const DisasContext *dc);
+
+
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
+{
+    CPUArchState *env = cpu->env_ptr;
+    DisasContext dc1, *dc = &dc1;
+    int num_insns;
+    int max_insns;
+
+    /* Initialize DisasContext */
+    dc->base.tb = tb;
+    dc->base.singlestep_enabled = cpu->singlestep_enabled;
+    dc->base.pc_first = tb->pc;
+    dc->base.pc_next = dc->base.pc_first;
+    dc->base.jmp_type = DJ_NEXT;
+    gen_intermediate_code_target_init_disas_context(dc, env);
+
+    /* Target-specific globals */
+    gen_intermediate_code_target_init_globals(dc, env);
+
+    /* Instruction counting */
+    num_insns = 0;
+    max_insns = dc->base.tb->cflags & CF_COUNT_MASK;
+    if (max_insns == 0) {
+        max_insns = CF_COUNT_MASK;
+    }
+    if (max_insns > TCG_MAX_INSNS) {
+        max_insns = TCG_MAX_INSNS;
+    }
+
+    /* Start translating */
+    gen_tb_start(dc->base.tb);
+
+    while (true) {
+        CPUBreakpoint *bp;
+
+        tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
+        num_insns++;
+
+        /* Pass breakpoint hits to target for further processing */
+        bp = NULL;
+        do {
+            bp = cpu_breakpoint_get(cpu, dc->base.pc_next, bp);
+            if (unlikely(bp)) {
+                if (gen_intermediate_code_target_breakpoint_hit(dc, env, bp)) {
+                    goto done_generating;
+                }
+            }
+        } while (bp != NULL);
+
+        /* Accept I/O on last instruction */
+        if (num_insns == max_insns && (dc->base.tb->cflags & CF_LAST_IO)) {
+            gen_io_start();
+        }
+
+        /* Disassemble one instruction */
+        dc->base.pc_next = disas_insn(env, dc, dc->base.pc_next);
+
+        /**************************************************/
+        /* Conditions to stop translation                 */
+        /**************************************************/
+
+        /* Too many instructions */
+        if (tcg_op_buf_full() || num_insns >= max_insns) {
+            dc->base.jmp_type = DJ_TOO_MANY;
+            break;
+        }
+
+        /* Single-stepping */
+        if (dc->base.singlestep_enabled || singlestep) {
+            dc->base.jmp_type = DJ_TOO_MANY;
+            break;
+        }
+
+        /*
+         * Next instruction is on next page, which can cause an exception.
+         *
+         * NOTE: Target-specific code must check a single instruction does not
+         *       cross page boundaries; the first in the TB (already
+         *       disassembled), is always allowed to cross pages.
+         */
+        if ((dc->base.pc_first & TARGET_PAGE_MASK)
+            != (dc->base.pc_next & TARGET_PAGE_MASK)) {
+            dc->base.jmp_type = DJ_TOO_MANY;
+            break;
+        }
+
+        /* Target-specific conditions */
+        dc->base.jmp_type = gen_intermediate_code_target_stop_check(dc, env);
+        if (dc->base.jmp_type >= DJ_TARGET) {
+            break;
+        }
+    }
+
+    gen_intermediate_code_target_stop(dc, env);
+
+    if (dc->base.tb->cflags & CF_LAST_IO) {
+        gen_io_end();
+    }
+
+done_generating:
+    gen_tb_end(dc->base.tb, num_insns);
+
+#ifdef DEBUG_DISAS
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
+        qemu_log_in_addr_range(dc->base.pc_first)) {
+        qemu_log("----------------\n");
+        qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
+        log_target_disas(cpu, dc->base.pc_first, dc->base.pc_next - dc->base.pc_first,
+                         gen_intermediate_code_target_get_disas_flags(dc));
+        qemu_log("\n");
+    }
+#endif
+
+    dc->base.tb->size = dc->base.pc_next - dc->base.pc_first;
+    dc->base.tb->icount = num_insns;
+}
+
+#endif  /* TRANSLATE_ALL_TEMPLATE_H */

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH 4/4] target: [tcg, i386] Port to generic translation framework
  2016-07-15 16:12 [Qemu-devel] [RFC PATCH 0/4] translate: [tcg] Generic translation framework Lluís Vilanova
                   ` (2 preceding siblings ...)
  2016-07-15 16:12 ` [Qemu-devel] [PATCH 3/4] target: [tcg] Add generic translation framework Lluís Vilanova
@ 2016-07-15 16:12 ` Lluís Vilanova
  2016-07-15 16:27 ` [Qemu-devel] [RFC PATCH 0/4] translate: [tcg] Generic " Lluís Vilanova
  4 siblings, 0 replies; 9+ messages in thread
From: Lluís Vilanova @ 2016-07-15 16:12 UTC (permalink / raw)
  To: qemu-devel
  Cc: Richard Henderson, Peter Crosthwaite, Paolo Bonzini, Eduardo Habkost

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 target-i386/cpu.h       |    2 
 target-i386/translate.c |  289 +++++++++++++++++++++--------------------------
 2 files changed, 130 insertions(+), 161 deletions(-)

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 732eb6d..f6486ce 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1221,7 +1221,7 @@ uint64_t cpu_get_tsc(CPUX86State *env);
 #define MMU_KSMAP_IDX   0
 #define MMU_USER_IDX    1
 #define MMU_KNOSMAP_IDX 2
-static inline int cpu_mmu_index(CPUX86State *env, bool ifetch)
+static inline int cpu_mmu_index(const CPUX86State *env, bool ifetch)
 {
     return (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER_IDX :
         (!(env->hflags & HF_SMAP_MASK) || (env->eflags & AC_MASK))
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 68e2593..2f23e75 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -68,6 +68,10 @@
     case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
     case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
 
+#include "exec/translate-all_template.h"
+#define DJ_JUMP DJ_TARGET+0             /* end of block due to call/jump */
+#define DJ_MISC DJ_TARGET+1             /* some other reason */
+
 //#define MACRO_TEST   1
 
 /* global register indexes */
@@ -93,7 +97,11 @@ static TCGv_i64 cpu_tmp1_i64;
 static int x86_64_hregs;
 #endif
 
-typedef struct DisasContext {
+
+typedef struct DisasContext
+{
+    DisasContextBase base;
+
     /* current insn context */
     int override; /* -1 if no override */
     int prefix;
@@ -101,8 +109,6 @@ typedef struct DisasContext {
     TCGMemOp dflag;
     target_ulong pc_start;
     target_ulong pc; /* pc = eip + cs_base */
-    int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
-                   static state change (stop translation) */
     /* current block context */
     target_ulong cs_base; /* base of CS segment */
     int pe;     /* protected mode */
@@ -123,12 +129,10 @@ typedef struct DisasContext {
     int cpl;
     int iopl;
     int tf;     /* TF cpu flag */
-    int singlestep_enabled; /* "hardware" single step enabled */
     int jmp_opt; /* use direct block chaining for direct jumps */
     int repz_opt; /* optimize jumps within repz instructions */
     int mem_index; /* select memory access functions */
     uint64_t flags; /* all execution flags */
-    struct TranslationBlock *tb;
     int popl_esp_hack; /* for correct popl with esp base handling */
     int rip_offset; /* only used in x86_64, but left for simplicity */
     int cpuid_features;
@@ -139,6 +143,7 @@ typedef struct DisasContext {
     int cpuid_xsave_features;
 } DisasContext;
 
+
 static void gen_eob(DisasContext *s);
 static void gen_jmp(DisasContext *s, target_ulong eip);
 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
@@ -1112,7 +1117,7 @@ static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
 
 static inline void gen_ins(DisasContext *s, TCGMemOp ot)
 {
-    if (s->tb->cflags & CF_USE_ICOUNT) {
+    if (s->base.tb->cflags & CF_USE_ICOUNT) {
         gen_io_start();
     }
     gen_string_movl_A0_EDI(s);
@@ -1127,14 +1132,14 @@ static inline void gen_ins(DisasContext *s, TCGMemOp ot)
     gen_op_movl_T0_Dshift(ot);
     gen_op_add_reg_T0(s->aflag, R_EDI);
     gen_bpt_io(s, cpu_tmp2_i32, ot);
-    if (s->tb->cflags & CF_USE_ICOUNT) {
+    if (s->base.tb->cflags & CF_USE_ICOUNT) {
         gen_io_end();
     }
 }
 
 static inline void gen_outs(DisasContext *s, TCGMemOp ot)
 {
-    if (s->tb->cflags & CF_USE_ICOUNT) {
+    if (s->base.tb->cflags & CF_USE_ICOUNT) {
         gen_io_start();
     }
     gen_string_movl_A0_ESI(s);
@@ -1147,7 +1152,7 @@ static inline void gen_outs(DisasContext *s, TCGMemOp ot)
     gen_op_movl_T0_Dshift(ot);
     gen_op_add_reg_T0(s->aflag, R_ESI);
     gen_bpt_io(s, cpu_tmp2_i32, ot);
-    if (s->tb->cflags & CF_USE_ICOUNT) {
+    if (s->base.tb->cflags & CF_USE_ICOUNT) {
         gen_io_end();
     }
 }
@@ -2091,7 +2096,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
     target_ulong pc;
 
     pc = s->cs_base + eip;
-    tb = s->tb;
+    tb = s->base.tb;
     /* NOTE: we handle the case where the TB spans two pages here */
     if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
         (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
@@ -2119,7 +2124,7 @@ static inline void gen_jcc(DisasContext *s, int b,
 
         gen_set_label(l1);
         gen_goto_tb(s, 1, val);
-        s->is_jmp = DISAS_TB_JUMP;
+        s->base.jmp_type = DJ_JUMP;
     } else {
         l1 = gen_new_label();
         l2 = gen_new_label();
@@ -2190,11 +2195,11 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg)
            stop as a special handling must be done to disable hardware
            interrupts for the next instruction */
         if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
-            s->is_jmp = DISAS_TB_JUMP;
+            s->base.jmp_type = DJ_JUMP;
     } else {
         gen_op_movl_seg_T0_vm(seg_reg);
         if (seg_reg == R_SS)
-            s->is_jmp = DISAS_TB_JUMP;
+            s->base.jmp_type = DJ_JUMP;
     }
 }
 
@@ -2366,7 +2371,7 @@ static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
     gen_update_cc_op(s);
     gen_jmp_im(cur_eip);
     gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
-    s->is_jmp = DISAS_TB_JUMP;
+    s->base.jmp_type = DJ_JUMP;
 }
 
 /* Generate #UD for the current instruction.  The assumption here is that
@@ -2402,7 +2407,7 @@ static void gen_interrupt(DisasContext *s, int intno,
     gen_jmp_im(cur_eip);
     gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
                                tcg_const_i32(next_eip - cur_eip));
-    s->is_jmp = DISAS_TB_JUMP;
+    s->base.jmp_type = DJ_JUMP;
 }
 
 static void gen_debug(DisasContext *s, target_ulong cur_eip)
@@ -2410,7 +2415,7 @@ static void gen_debug(DisasContext *s, target_ulong cur_eip)
     gen_update_cc_op(s);
     gen_jmp_im(cur_eip);
     gen_helper_debug(cpu_env);
-    s->is_jmp = DISAS_TB_JUMP;
+    s->base.jmp_type = DJ_JUMP;
 }
 
 static void gen_set_hflag(DisasContext *s, uint32_t mask)
@@ -2463,17 +2468,17 @@ static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)
         gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
     }
 
-    if (s->tb->flags & HF_RF_MASK) {
+    if (s->base.tb->flags & HF_RF_MASK) {
         gen_helper_reset_rf(cpu_env);
     }
-    if (s->singlestep_enabled) {
+    if (s->base.singlestep_enabled) {
         gen_helper_debug(cpu_env);
     } else if (s->tf) {
         gen_helper_single_step(cpu_env);
     } else {
         tcg_gen_exit_tb(0);
     }
-    s->is_jmp = DISAS_TB_JUMP;
+    s->base.jmp_type = DJ_JUMP;
 }
 
 /* End of block, resetting the inhibit irq flag.  */
@@ -2490,7 +2495,7 @@ static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
     set_cc_op(s, CC_OP_DYNAMIC);
     if (s->jmp_opt) {
         gen_goto_tb(s, tb_num, eip);
-        s->is_jmp = DISAS_TB_JUMP;
+        s->base.jmp_type = DJ_JUMP;
     } else {
         gen_jmp_im(eip);
         gen_eob(s);
@@ -4327,7 +4332,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
     }
 }
 
-/* convert one instruction. s->is_jmp is set if the translation must
+/* convert one instruction. s->base.jmp_type is set if the translation must
    be stopped. Return the next pc value */
 static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
                                target_ulong pc_start)
@@ -5224,7 +5229,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
         gen_movl_seg_T0(s, reg);
         gen_pop_update(s, ot);
         /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp.  */
-        if (s->is_jmp) {
+        if (s->base.jmp_type) {
             gen_jmp_im(s->pc - s->cs_base);
             if (reg == R_SS) {
                 s->tf = 0;
@@ -5239,7 +5244,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
         ot = gen_pop_T0(s);
         gen_movl_seg_T0(s, (b >> 3) & 7);
         gen_pop_update(s, ot);
-        if (s->is_jmp) {
+        if (s->base.jmp_type) {
             gen_jmp_im(s->pc - s->cs_base);
             gen_eob(s);
         }
@@ -5290,7 +5295,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
         gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
         gen_movl_seg_T0(s, reg);
         /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp.  */
-        if (s->is_jmp) {
+        if (s->base.jmp_type) {
             gen_jmp_im(s->pc - s->cs_base);
             if (reg == R_SS) {
                 s->tf = 0;
@@ -5498,7 +5503,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
         gen_movl_seg_T0(s, op);
         /* then put the data */
         gen_op_mov_reg_v(ot, reg, cpu_T1);
-        if (s->is_jmp) {
+        if (s->base.jmp_type) {
             gen_jmp_im(s->pc - s->cs_base);
             gen_eob(s);
         }
@@ -6154,7 +6159,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
             gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
             gen_ins(s, ot);
-            if (s->tb->cflags & CF_USE_ICOUNT) {
+            if (s->base.tb->cflags & CF_USE_ICOUNT) {
                 gen_jmp(s, s->pc - s->cs_base);
             }
         }
@@ -6169,7 +6174,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
             gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
         } else {
             gen_outs(s, ot);
-            if (s->tb->cflags & CF_USE_ICOUNT) {
+            if (s->base.tb->cflags & CF_USE_ICOUNT) {
                 gen_jmp(s, s->pc - s->cs_base);
             }
         }
@@ -6185,14 +6190,14 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
         tcg_gen_movi_tl(cpu_T0, val);
         gen_check_io(s, ot, pc_start - s->cs_base,
                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
-        if (s->tb->cflags & CF_USE_ICOUNT) {
+        if (s->base.tb->cflags & CF_USE_ICOUNT) {
             gen_io_start();
 	}
         tcg_gen_movi_i32(cpu_tmp2_i32, val);
         gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
         gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
         gen_bpt_io(s, cpu_tmp2_i32, ot);
-        if (s->tb->cflags & CF_USE_ICOUNT) {
+        if (s->base.tb->cflags & CF_USE_ICOUNT) {
             gen_io_end();
             gen_jmp(s, s->pc - s->cs_base);
         }
@@ -6206,14 +6211,14 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
                      svm_is_rep(prefixes));
         gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
 
-        if (s->tb->cflags & CF_USE_ICOUNT) {
+        if (s->base.tb->cflags & CF_USE_ICOUNT) {
             gen_io_start();
 	}
         tcg_gen_movi_i32(cpu_tmp2_i32, val);
         tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
         gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
         gen_bpt_io(s, cpu_tmp2_i32, ot);
-        if (s->tb->cflags & CF_USE_ICOUNT) {
+        if (s->base.tb->cflags & CF_USE_ICOUNT) {
             gen_io_end();
             gen_jmp(s, s->pc - s->cs_base);
         }
@@ -6224,14 +6229,14 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
         tcg_gen_ext16u_tl(cpu_T0, cpu_regs[R_EDX]);
         gen_check_io(s, ot, pc_start - s->cs_base,
                      SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
-        if (s->tb->cflags & CF_USE_ICOUNT) {
+        if (s->base.tb->cflags & CF_USE_ICOUNT) {
             gen_io_start();
 	}
         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
         gen_helper_in_func(ot, cpu_T1, cpu_tmp2_i32);
         gen_op_mov_reg_v(ot, R_EAX, cpu_T1);
         gen_bpt_io(s, cpu_tmp2_i32, ot);
-        if (s->tb->cflags & CF_USE_ICOUNT) {
+        if (s->base.tb->cflags & CF_USE_ICOUNT) {
             gen_io_end();
             gen_jmp(s, s->pc - s->cs_base);
         }
@@ -6244,14 +6249,14 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
                      svm_is_rep(prefixes));
         gen_op_mov_v_reg(ot, cpu_T1, R_EAX);
 
-        if (s->tb->cflags & CF_USE_ICOUNT) {
+        if (s->base.tb->cflags & CF_USE_ICOUNT) {
             gen_io_start();
 	}
         tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
         tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T1);
         gen_helper_out_func(ot, cpu_tmp2_i32, cpu_tmp3_i32);
         gen_bpt_io(s, cpu_tmp2_i32, ot);
-        if (s->tb->cflags & CF_USE_ICOUNT) {
+        if (s->base.tb->cflags & CF_USE_ICOUNT) {
             gen_io_end();
             gen_jmp(s, s->pc - s->cs_base);
         }
@@ -6766,7 +6771,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
             gen_update_cc_op(s);
             gen_jmp_im(pc_start - s->cs_base);
             gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
-            s->is_jmp = DISAS_TB_JUMP;
+            s->base.jmp_type = DJ_JUMP;
         }
         break;
     case 0x9b: /* fwait */
@@ -6935,11 +6940,11 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
     case 0x131: /* rdtsc */
         gen_update_cc_op(s);
         gen_jmp_im(pc_start - s->cs_base);
-        if (s->tb->cflags & CF_USE_ICOUNT) {
+        if (s->base.tb->cflags & CF_USE_ICOUNT) {
             gen_io_start();
 	}
         gen_helper_rdtsc(cpu_env);
-        if (s->tb->cflags & CF_USE_ICOUNT) {
+        if (s->base.tb->cflags & CF_USE_ICOUNT) {
             gen_io_end();
             gen_jmp(s, s->pc - s->cs_base);
         }
@@ -7004,7 +7009,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
             gen_update_cc_op(s);
             gen_jmp_im(pc_start - s->cs_base);
             gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
-            s->is_jmp = DISAS_TB_JUMP;
+            s->base.jmp_type = DJ_JUMP;
         }
         break;
     case 0x100:
@@ -7187,7 +7192,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
             gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
                              tcg_const_i32(s->pc - pc_start));
             tcg_gen_exit_tb(0);
-            s->is_jmp = DISAS_TB_JUMP;
+            s->base.jmp_type = DJ_JUMP;
             break;
 
         case 0xd9: /* VMMCALL */
@@ -7387,11 +7392,11 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
             }
             gen_update_cc_op(s);
             gen_jmp_im(pc_start - s->cs_base);
-            if (s->tb->cflags & CF_USE_ICOUNT) {
+            if (s->base.tb->cflags & CF_USE_ICOUNT) {
                 gen_io_start();
             }
             gen_helper_rdtscp(cpu_env);
-            if (s->tb->cflags & CF_USE_ICOUNT) {
+            if (s->base.tb->cflags & CF_USE_ICOUNT) {
                 gen_io_end();
                 gen_jmp(s, s->pc - s->cs_base);
             }
@@ -8171,22 +8176,23 @@ void tcg_x86_init(void)
     helper_lock_init();
 }
 
-/* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
+void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
+                          target_ulong *data)
 {
-    CPUX86State *env = cpu->env_ptr;
-    DisasContext dc1, *dc = &dc1;
-    target_ulong pc_ptr;
-    uint64_t flags;
-    target_ulong pc_start;
-    target_ulong cs_base;
-    int num_insns;
-    int max_insns;
+    int cc_op = data[1];
+    env->eip = data[0] - tb->cs_base;
+    if (cc_op != CC_OP_DYNAMIC) {
+        env->cc_op = cc_op;
+    }
+}
 
-    /* generate intermediate code */
-    pc_start = tb->pc;
-    cs_base = tb->cs_base;
-    flags = tb->flags;
+
+#include "translate-all_template.h"
+
+static void gen_intermediate_code_target_init_disas_context(
+    DisasContext * restrict dc, const CPUX86State * restrict env)
+{
+    uint64_t flags = dc->base.tb->flags;
 
     dc->pe = (flags >> HF_PE_SHIFT) & 1;
     dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
@@ -8197,17 +8203,17 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
     dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
     dc->iopl = (flags >> IOPL_SHIFT) & 3;
     dc->tf = (flags >> TF_SHIFT) & 1;
-    dc->singlestep_enabled = cpu->singlestep_enabled;
     dc->cc_op = CC_OP_DYNAMIC;
     dc->cc_op_dirty = false;
-    dc->cs_base = cs_base;
-    dc->tb = tb;
+    dc->cs_base = dc->base.tb->cs_base;
     dc->popl_esp_hack = 0;
+
     /* select memory access functions */
     dc->mem_index = 0;
     if (flags & HF_SOFTMMU_MASK) {
 	dc->mem_index = cpu_mmu_index(env, false);
     }
+
     dc->cpuid_features = env->features[FEAT_1_EDX];
     dc->cpuid_ext_features = env->features[FEAT_1_ECX];
     dc->cpuid_ext2_features = env->features[FEAT_8000_0001_EDX];
@@ -8219,7 +8225,7 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
     dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
 #endif
     dc->flags = flags;
-    dc->jmp_opt = !(dc->tf || cpu->singlestep_enabled ||
+    dc->jmp_opt = !(dc->tf || dc->base.singlestep_enabled ||
                     (flags & HF_INHIBIT_IRQ_MASK)
 #ifndef CONFIG_SOFTMMU
                     || (flags & HF_SOFTMMU_MASK)
@@ -8235,13 +8241,17 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
        record/replay modes and there will always be an
        additional step for ecx=0 when icount is enabled.
      */
-    dc->repz_opt = !dc->jmp_opt && !(tb->cflags & CF_USE_ICOUNT);
+    dc->repz_opt = !dc->jmp_opt && !(dc->base.tb->cflags & CF_USE_ICOUNT);
 #if 0
     /* check addseg logic */
     if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
         printf("ERROR addseg\n");
 #endif
+}
 
+static void gen_intermediate_code_target_init_globals(
+    DisasContext * restrict dc, const CPUX86State * restrict env)
+{
     cpu_T0 = tcg_temp_new();
     cpu_T1 = tcg_temp_new();
     cpu_A0 = tcg_temp_new();
@@ -8254,113 +8264,72 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
     cpu_ptr0 = tcg_temp_new_ptr();
     cpu_ptr1 = tcg_temp_new_ptr();
     cpu_cc_srcT = tcg_temp_local_new();
+}
 
-    dc->is_jmp = DISAS_NEXT;
-    pc_ptr = pc_start;
-    num_insns = 0;
-    max_insns = tb->cflags & CF_COUNT_MASK;
-    if (max_insns == 0) {
-        max_insns = CF_COUNT_MASK;
-    }
-    if (max_insns > TCG_MAX_INSNS) {
-        max_insns = TCG_MAX_INSNS;
+static bool gen_intermediate_code_target_breakpoint_hit(
+    DisasContext * restrict dc, const CPUX86State * restrict env,
+    const CPUBreakpoint * restrict bp)
+{
+    /* If RF is set, suppress an internally generated breakpoint.  */
+    int flags = dc->base.tb->flags & HF_RF_MASK ? BP_GDB : BP_ANY;
+    if (bp->flags & flags) {
+        gen_debug(dc, dc->base.pc_next - dc->cs_base);
+        /* The address covered by the breakpoint must be included in [tb->pc,
+           tb->pc + tb->size) in order to for it to be properly cleared -- thus
+           we increment the PC here so that the generic logic setting tb->size
+           later does the right thing.  */
+        dc->base.pc_next += 1;
+        return true;
+    } else {
+        return false;
     }
+}
 
-    gen_tb_start(tb);
-    for(;;) {
-        tcg_gen_insn_start(pc_ptr, dc->cc_op);
-        num_insns++;
-
-        /* If RF is set, suppress an internally generated breakpoint.  */
-        if (unlikely(cpu_breakpoint_test(cpu, pc_ptr,
-                                         tb->flags & HF_RF_MASK
-                                         ? BP_GDB : BP_ANY))) {
-            gen_debug(dc, pc_ptr - dc->cs_base);
-            /* The address covered by the breakpoint must be included in
-               [tb->pc, tb->pc + tb->size) in order to for it to be
-               properly cleared -- thus we increment the PC here so that
-               the logic setting tb->size below does the right thing.  */
-            pc_ptr += 1;
-            goto done_generating;
-        }
-        if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
-            gen_io_start();
-        }
-
-        pc_ptr = disas_insn(env, dc, pc_ptr);
-        /* stop translation if indicated */
-        if (dc->is_jmp)
-            break;
-        /* if single step mode, we generate only one instruction and
-           generate an exception */
-        /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
-           the flag and abort the translation to give the irqs a
-           change to be happen */
-        if (dc->tf || dc->singlestep_enabled ||
-            (flags & HF_INHIBIT_IRQ_MASK)) {
-            gen_jmp_im(pc_ptr - dc->cs_base);
-            gen_eob(dc);
-            break;
-        }
-        /* Do not cross the boundary of the pages in icount mode,
-           it can cause an exception. Do it only when boundary is
-           crossed by the first instruction in the block.
-           If current instruction already crossed the bound - it's ok,
-           because an exception hasn't stopped this code.
+static DisasJumpType gen_intermediate_code_target_stop_check(
+    DisasContext * restrict dc, const CPUX86State * restrict env)
+{
+    if (dc->tf) {
+        /*
+         * If single step mode, we generate only one instruction and generate an
+         * exception.
          */
-        if ((tb->cflags & CF_USE_ICOUNT)
-            && ((pc_ptr & TARGET_PAGE_MASK)
-                != ((pc_ptr + TARGET_MAX_INSN_SIZE - 1) & TARGET_PAGE_MASK)
-                || (pc_ptr & ~TARGET_PAGE_MASK) == 0)) {
-            gen_jmp_im(pc_ptr - dc->cs_base);
-            gen_eob(dc);
-            break;
-        }
-        /* if too long translation, stop generation too */
-        if (tcg_op_buf_full() ||
-            (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
-            num_insns >= max_insns) {
-            gen_jmp_im(pc_ptr - dc->cs_base);
-            gen_eob(dc);
-            break;
-        }
-        if (singlestep) {
-            gen_jmp_im(pc_ptr - dc->cs_base);
-            gen_eob(dc);
-            break;
-        }
-    }
-    if (tb->cflags & CF_LAST_IO)
-        gen_io_end();
-done_generating:
-    gen_tb_end(tb, num_insns);
-
-#ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
-        int disas_flags;
-        qemu_log("----------------\n");
-        qemu_log("IN: %s\n", lookup_symbol(pc_start));
-#ifdef TARGET_X86_64
-        if (dc->code64)
-            disas_flags = 2;
-        else
-#endif
-            disas_flags = !dc->code32;
-        log_target_disas(cpu, pc_start, pc_ptr - pc_start, disas_flags);
-        qemu_log("\n");
+        return DJ_MISC;
+    } else if (dc->flags & HF_INHIBIT_IRQ_MASK) {
+        /*
+         * If irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear the flag and
+         * abort the translation to give the irqs a change to be happen.
+         */
+        return DJ_MISC;
+    } else if ((dc->base.pc_next & TARGET_PAGE_MASK)
+               != ((dc->base.pc_next + TARGET_MAX_INSN_SIZE - 1) & TARGET_PAGE_MASK)) {
+        /* next instruction crosses page boundary */
+        return DJ_MISC;
+    } else {
+        /* previously set during target disassembly */
+        return dc->base.jmp_type;
     }
-#endif
+}
 
-    tb->size = pc_ptr - pc_start;
-    tb->icount = num_insns;
+static void gen_intermediate_code_target_stop(
+    DisasContext * restrict dc, const CPUX86State * restrict env)
+{
+    DisasJumpType j = dc->base.jmp_type;
+    if (j == DJ_TOO_MANY || j == DJ_MISC) {
+        gen_jmp_im(dc->base.pc_next - dc->cs_base);
+        gen_eob(dc);
+    }
 }
 
-void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
-                          target_ulong *data)
+static int gen_intermediate_code_target_get_disas_flags(
+    const DisasContext *dc)
 {
-    int cc_op = data[1];
-    env->eip = data[0] - tb->cs_base;
-    if (cc_op != CC_OP_DYNAMIC) {
-        env->cc_op = cc_op;
+#ifdef TARGET_X86_64
+    if (dc->code64) {
+        return 2;
+    } else {
+        return !dc->code32;
     }
+#else
+    return !dc->code32;
+#endif
 }

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 0/4] translate: [tcg] Generic translation framework
  2016-07-15 16:12 [Qemu-devel] [RFC PATCH 0/4] translate: [tcg] Generic translation framework Lluís Vilanova
                   ` (3 preceding siblings ...)
  2016-07-15 16:12 ` [Qemu-devel] [PATCH 4/4] target: [tcg, i386] Port to " Lluís Vilanova
@ 2016-07-15 16:27 ` Lluís Vilanova
  4 siblings, 0 replies; 9+ messages in thread
From: Lluís Vilanova @ 2016-07-15 16:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Peter Crosthwaite, Richard Henderson

Lluís Vilanova writes:

> This series proposes a generic (target-agnostic) instruction translation
> framework.

> It basically provides a generic main loop for instruction disassembly, which
> calls target-specific functions when necessary. This generalization makes
> inserting new code in the main loop easier, and helps in keeping all targets in
> synch as to the contents of it.

> I've only ported i386 as an example to get some feedback, but I'm planning on
> porting ARM next to see how well it fits into the current organization.

BTW, the original discussion is here:

  https://lists.gnu.org/archive/html/qemu-devel/2016-03/msg02143.html


Cheers,
  Lluis

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 1/4] Pass generic CPUState to gen_intermediate_code()
  2016-07-15 16:12 ` [Qemu-devel] [PATCH 1/4] Pass generic CPUState to gen_intermediate_code() Lluís Vilanova
@ 2016-07-18  1:39   ` David Gibson
  0 siblings, 0 replies; 9+ messages in thread
From: David Gibson @ 2016-07-18  1:39 UTC (permalink / raw)
  To: Lluís Vilanova
  Cc: qemu-devel, Peter Maydell, Guan Xuetao, Eduardo Habkost,
	Peter Crosthwaite, Jia Liu, Anthony Green, Blue Swirl,
	Max Filippov, Michael Walle, open list:ARM, open list:PowerPC,
	Paolo Bonzini, Bastian Koppelmann, Leon Alrae, Richard Henderson

[-- Attachment #1: Type: text/plain, Size: 51232 bytes --]

On Fri, Jul 15, 2016 at 06:12:05PM +0200, Lluís Vilanova wrote:
> Needed to implement a target-agnostic gen_intermediate_code() in the
> future.
> 
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
>  include/exec/exec-all.h       |    2 +-
>  target-alpha/translate.c      |   11 +++++------
>  target-arm/translate.c        |   24 ++++++++++++------------
>  target-cris/translate.c       |   17 ++++++++---------
>  target-i386/translate.c       |   13 ++++++-------
>  target-lm32/translate.c       |   22 +++++++++++-----------
>  target-m68k/translate.c       |   15 +++++++--------
>  target-microblaze/translate.c |   24 ++++++++++++------------
>  target-mips/translate.c       |   15 +++++++--------
>  target-moxie/translate.c      |   14 +++++++-------
>  target-openrisc/translate.c   |   24 ++++++++++++------------
>  target-ppc/translate.c        |   15 +++++++--------
>  target-s390x/translate.c      |   13 ++++++-------
>  target-sh4/translate.c        |   15 +++++++--------
>  target-sparc/translate.c      |   11 +++++------
>  target-tilegx/translate.c     |    7 +++----
>  target-tricore/translate.c    |    9 ++++-----
>  target-unicore32/translate.c  |   17 ++++++++---------
>  target-xtensa/translate.c     |   13 ++++++-------
>  translate-all.c               |    2 +-
>  20 files changed, 135 insertions(+), 148 deletions(-)

target-ppc portion

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
> index 7362095..06c2400 100644
> --- a/include/exec/exec-all.h
> +++ b/include/exec/exec-all.h
> @@ -66,7 +66,7 @@ typedef struct TranslationBlock TranslationBlock;
>  
>  #include "qemu/log.h"
>  
> -void gen_intermediate_code(CPUArchState *env, struct TranslationBlock *tb);
> +void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
>  void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
>                            target_ulong *data);
>  
> diff --git a/target-alpha/translate.c b/target-alpha/translate.c
> index 5b86992..faeccf8 100644
> --- a/target-alpha/translate.c
> +++ b/target-alpha/translate.c
> @@ -2860,10 +2860,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
>      return ret;
>  }
>  
> -void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
>  {
> -    AlphaCPU *cpu = alpha_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUAlphaState *env = cpu->env_ptr;
>      DisasContext ctx, *ctxp = &ctx;
>      target_ulong pc_start;
>      target_ulong pc_mask;
> @@ -2878,7 +2877,7 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
>      ctx.pc = pc_start;
>      ctx.mem_idx = cpu_mmu_index(env, false);
>      ctx.implver = env->implver;
> -    ctx.singlestep_enabled = cs->singlestep_enabled;
> +    ctx.singlestep_enabled = cpu->singlestep_enabled;
>  
>  #ifdef CONFIG_USER_ONLY
>      ctx.ir = cpu_std_ir;
> @@ -2917,7 +2916,7 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
>          tcg_gen_insn_start(ctx.pc);
>          num_insns++;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, ctx.pc, BP_ANY))) {
>              ret = gen_excp(&ctx, EXCP_DEBUG, 0);
>              /* The address covered by the breakpoint must be included in
>                 [tb->pc, tb->pc + tb->size) in order to for it to be
> @@ -2991,7 +2990,7 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
>  #ifdef DEBUG_DISAS
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>          qemu_log("IN: %s\n", lookup_symbol(pc_start));
> -        log_target_disas(cs, pc_start, ctx.pc - pc_start, 1);
> +        log_target_disas(cpu, pc_start, ctx.pc - pc_start, 1);
>          qemu_log("\n");
>      }
>  #endif
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index 940ec8d..837ceda 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -11587,10 +11587,10 @@ static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
>  }
>  
>  /* generate intermediate code for basic block 'tb'.  */
> -void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
>  {
> -    ARMCPU *cpu = arm_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUARMState *env = cpu->env_ptr;
> +    ARMCPU *arm_cpu = arm_env_get_cpu(env);
>      DisasContext dc1, *dc = &dc1;
>      target_ulong pc_start;
>      target_ulong next_page_start;
> @@ -11604,7 +11604,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
>       * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
>       */
>      if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
> -        gen_intermediate_code_a64(cpu, tb);
> +        gen_intermediate_code_a64(arm_cpu, tb);
>          return;
>      }
>  
> @@ -11614,7 +11614,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
>  
>      dc->is_jmp = DISAS_NEXT;
>      dc->pc = pc_start;
> -    dc->singlestep_enabled = cs->singlestep_enabled;
> +    dc->singlestep_enabled = cpu->singlestep_enabled;
>      dc->condjmp = 0;
>  
>      dc->aarch64 = 0;
> @@ -11639,7 +11639,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
>      dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
>      dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
>      dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
> -    dc->cp_regs = cpu->cp_regs;
> +    dc->cp_regs = arm_cpu->cp_regs;
>      dc->features = env->features;
>  
>      /* Single step state. The code-generation logic here is:
> @@ -11746,9 +11746,9 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
>          }
>  #endif
>  
> -        if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> +        if (unlikely(!QTAILQ_EMPTY(&cpu->breakpoints))) {
>              CPUBreakpoint *bp;
> -            QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> +            QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
>                  if (bp->pc == dc->pc) {
>                      if (bp->flags & BP_CPU) {
>                          gen_set_condexec(dc);
> @@ -11838,7 +11838,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
>              ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc));
>  
>      } while (!dc->is_jmp && !tcg_op_buf_full() &&
> -             !cs->singlestep_enabled &&
> +             !cpu->singlestep_enabled &&
>               !singlestep &&
>               !dc->ss_active &&
>               !end_of_page &&
> @@ -11848,7 +11848,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
>          if (dc->condjmp) {
>              /* FIXME:  This can theoretically happen with self-modifying
>                 code.  */
> -            cpu_abort(cs, "IO on conditional branch instruction");
> +            cpu_abort(cpu, "IO on conditional branch instruction");
>          }
>          gen_io_end();
>      }
> @@ -11856,7 +11856,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
>      /* At this stage dc->condjmp will only be set when the skipped
>         instruction was a conditional branch or trap, and the PC has
>         already been written.  */
> -    if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
> +    if (unlikely(cpu->singlestep_enabled || dc->ss_active)) {
>          /* Unconditional and "condition passed" instruction codepath. */
>          gen_set_condexec(dc);
>          switch (dc->is_jmp) {
> @@ -11962,7 +11962,7 @@ done_generating:
>          qemu_log_in_addr_range(pc_start)) {
>          qemu_log("----------------\n");
>          qemu_log("IN: %s\n", lookup_symbol(pc_start));
> -        log_target_disas(cs, pc_start, dc->pc - pc_start,
> +        log_target_disas(cpu, pc_start, dc->pc - pc_start,
>                           dc->thumb | (dc->sctlr_b << 1));
>          qemu_log("\n");
>      }
> diff --git a/target-cris/translate.c b/target-cris/translate.c
> index a73176c..90d63c1 100644
> --- a/target-cris/translate.c
> +++ b/target-cris/translate.c
> @@ -3071,10 +3071,9 @@ static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
>   */
>  
>  /* generate intermediate code for basic block 'tb'.  */
> -void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
>  {
> -    CRISCPU *cpu = cris_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUCRISState *env = cpu->env_ptr;
>      uint32_t pc_start;
>      unsigned int insn_len;
>      struct DisasContext ctx;
> @@ -3096,13 +3095,13 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
>       * delayslot, like in real hw.
>       */
>      pc_start = tb->pc & ~1;
> -    dc->cpu = cpu;
> +    dc->cpu = cris_env_get_cpu(env);
>      dc->tb = tb;
>  
>      dc->is_jmp = DISAS_NEXT;
>      dc->ppc = pc_start;
>      dc->pc = pc_start;
> -    dc->singlestep_enabled = cs->singlestep_enabled;
> +    dc->singlestep_enabled = cpu->singlestep_enabled;
>      dc->flags_uptodate = 1;
>      dc->flagx_known = 1;
>      dc->flags_x = tb->flags & X_FLAG;
> @@ -3165,7 +3164,7 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
>                             ? dc->ppc | 1 : dc->pc);
>          num_insns++;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
>              cris_evaluate_flags(dc);
>              tcg_gen_movi_tl(env_pc, dc->pc);
>              t_gen_raise_exception(EXCP_DEBUG);
> @@ -3239,7 +3238,7 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
>  
>          /* If we are rexecuting a branch due to exceptions on
>             delay slots dont break.  */
> -        if (!(tb->pc & 1) && cs->singlestep_enabled) {
> +        if (!(tb->pc & 1) && cpu->singlestep_enabled) {
>              break;
>          }
>      } while (!dc->is_jmp && !dc->cpustate_changed
> @@ -3272,7 +3271,7 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
>  
>      cris_evaluate_flags(dc);
>  
> -    if (unlikely(cs->singlestep_enabled)) {
> +    if (unlikely(cpu->singlestep_enabled)) {
>          if (dc->is_jmp == DISAS_NEXT) {
>              tcg_gen_movi_tl(env_pc, npc);
>          }
> @@ -3303,7 +3302,7 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
>  #ifdef DEBUG_DISAS
>  #if !DISAS_CRIS
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
> -        log_target_disas(cs, pc_start, dc->pc - pc_start,
> +        log_target_disas(cpu, pc_start, dc->pc - pc_start,
>                           env->pregs[PR_VR]);
>          qemu_log("\nisize=%d osize=%d\n",
>                   dc->pc - pc_start, tcg_op_buf_count());
> diff --git a/target-i386/translate.c b/target-i386/translate.c
> index 1a1214d..68e2593 100644
> --- a/target-i386/translate.c
> +++ b/target-i386/translate.c
> @@ -8172,10 +8172,9 @@ void tcg_x86_init(void)
>  }
>  
>  /* generate intermediate code for basic block 'tb'.  */
> -void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
>  {
> -    X86CPU *cpu = x86_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUX86State *env = cpu->env_ptr;
>      DisasContext dc1, *dc = &dc1;
>      target_ulong pc_ptr;
>      uint64_t flags;
> @@ -8198,7 +8197,7 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
>      dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
>      dc->iopl = (flags >> IOPL_SHIFT) & 3;
>      dc->tf = (flags >> TF_SHIFT) & 1;
> -    dc->singlestep_enabled = cs->singlestep_enabled;
> +    dc->singlestep_enabled = cpu->singlestep_enabled;
>      dc->cc_op = CC_OP_DYNAMIC;
>      dc->cc_op_dirty = false;
>      dc->cs_base = cs_base;
> @@ -8220,7 +8219,7 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
>      dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
>  #endif
>      dc->flags = flags;
> -    dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
> +    dc->jmp_opt = !(dc->tf || cpu->singlestep_enabled ||
>                      (flags & HF_INHIBIT_IRQ_MASK)
>  #ifndef CONFIG_SOFTMMU
>                      || (flags & HF_SOFTMMU_MASK)
> @@ -8273,7 +8272,7 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
>          num_insns++;
>  
>          /* If RF is set, suppress an internally generated breakpoint.  */
> -        if (unlikely(cpu_breakpoint_test(cs, pc_ptr,
> +        if (unlikely(cpu_breakpoint_test(cpu, pc_ptr,
>                                           tb->flags & HF_RF_MASK
>                                           ? BP_GDB : BP_ANY))) {
>              gen_debug(dc, pc_ptr - dc->cs_base);
> @@ -8347,7 +8346,7 @@ done_generating:
>          else
>  #endif
>              disas_flags = !dc->code32;
> -        log_target_disas(cs, pc_start, pc_ptr - pc_start, disas_flags);
> +        log_target_disas(cpu, pc_start, pc_ptr - pc_start, disas_flags);
>          qemu_log("\n");
>      }
>  #endif
> diff --git a/target-lm32/translate.c b/target-lm32/translate.c
> index 256a51f..9721d31 100644
> --- a/target-lm32/translate.c
> +++ b/target-lm32/translate.c
> @@ -1035,10 +1035,10 @@ static inline void decode(DisasContext *dc, uint32_t ir)
>  }
>  
>  /* generate intermediate code for basic block 'tb'.  */
> -void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
>  {
> -    LM32CPU *cpu = lm32_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPULM32State *env = cpu->env_ptr;
> +    LM32CPU *lm32_cpu = lm32_env_get_cpu(env);
>      struct DisasContext ctx, *dc = &ctx;
>      uint32_t pc_start;
>      uint32_t next_page_start;
> @@ -1046,14 +1046,14 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
>      int max_insns;
>  
>      pc_start = tb->pc;
> -    dc->features = cpu->features;
> -    dc->num_breakpoints = cpu->num_breakpoints;
> -    dc->num_watchpoints = cpu->num_watchpoints;
> +    dc->features = lm32_cpu->features;
> +    dc->num_breakpoints = lm32_cpu->num_breakpoints;
> +    dc->num_watchpoints = lm32_cpu->num_watchpoints;
>      dc->tb = tb;
>  
>      dc->is_jmp = DISAS_NEXT;
>      dc->pc = pc_start;
> -    dc->singlestep_enabled = cs->singlestep_enabled;
> +    dc->singlestep_enabled = cpu->singlestep_enabled;
>  
>      if (pc_start & 3) {
>          qemu_log_mask(LOG_GUEST_ERROR,
> @@ -1076,7 +1076,7 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
>          tcg_gen_insn_start(dc->pc);
>          num_insns++;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
>              tcg_gen_movi_tl(cpu_pc, dc->pc);
>              t_gen_raise_exception(dc, EXCP_DEBUG);
>              dc->is_jmp = DISAS_UPDATE;
> @@ -1099,7 +1099,7 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
>          dc->pc += 4;
>      } while (!dc->is_jmp
>           && !tcg_op_buf_full()
> -         && !cs->singlestep_enabled
> +         && !cpu->singlestep_enabled
>           && !singlestep
>           && (dc->pc < next_page_start)
>           && num_insns < max_insns);
> @@ -1108,7 +1108,7 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
>          gen_io_end();
>      }
>  
> -    if (unlikely(cs->singlestep_enabled)) {
> +    if (unlikely(cpu->singlestep_enabled)) {
>          if (dc->is_jmp == DISAS_NEXT) {
>              tcg_gen_movi_tl(cpu_pc, dc->pc);
>          }
> @@ -1139,7 +1139,7 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
>  #ifdef DEBUG_DISAS
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>          qemu_log("\n");
> -        log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
> +        log_target_disas(cpu, pc_start, dc->pc - pc_start, 0);
>          qemu_log("\nisize=%d osize=%d\n",
>                   dc->pc - pc_start, tcg_op_buf_count());
>      }
> diff --git a/target-m68k/translate.c b/target-m68k/translate.c
> index 7560c3a..a3aaef2 100644
> --- a/target-m68k/translate.c
> +++ b/target-m68k/translate.c
> @@ -2968,10 +2968,9 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
>  }
>  
>  /* generate intermediate code for basic block 'tb'.  */
> -void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
>  {
> -    M68kCPU *cpu = m68k_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUM68KState *env = cpu->env_ptr;
>      DisasContext dc1, *dc = &dc1;
>      target_ulong pc_start;
>      int pc_offset;
> @@ -2987,7 +2986,7 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
>      dc->is_jmp = DISAS_NEXT;
>      dc->pc = pc_start;
>      dc->cc_op = CC_OP_DYNAMIC;
> -    dc->singlestep_enabled = cs->singlestep_enabled;
> +    dc->singlestep_enabled = cpu->singlestep_enabled;
>      dc->fpcr = env->fpcr;
>      dc->user = (env->sr & SR_S) == 0;
>      dc->done_mac = 0;
> @@ -3007,7 +3006,7 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
>          tcg_gen_insn_start(dc->pc);
>          num_insns++;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
>              gen_exception(dc, dc->pc, EXCP_DEBUG);
>              dc->is_jmp = DISAS_JUMP;
>              /* The address covered by the breakpoint must be included in
> @@ -3025,14 +3024,14 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
>          dc->insn_pc = dc->pc;
>  	disas_m68k_insn(env, dc);
>      } while (!dc->is_jmp && !tcg_op_buf_full() &&
> -             !cs->singlestep_enabled &&
> +             !cpu->singlestep_enabled &&
>               !singlestep &&
>               (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
>               num_insns < max_insns);
>  
>      if (tb->cflags & CF_LAST_IO)
>          gen_io_end();
> -    if (unlikely(cs->singlestep_enabled)) {
> +    if (unlikely(cpu->singlestep_enabled)) {
>          /* Make sure the pc is updated, and raise a debug exception.  */
>          if (!dc->is_jmp) {
>              gen_flush_cc_op(dc);
> @@ -3063,7 +3062,7 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>          qemu_log("----------------\n");
>          qemu_log("IN: %s\n", lookup_symbol(pc_start));
> -        log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
> +        log_target_disas(cpu, pc_start, dc->pc - pc_start, 0);
>          qemu_log("\n");
>      }
>  #endif
> diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
> index f944965..201e9fd 100644
> --- a/target-microblaze/translate.c
> +++ b/target-microblaze/translate.c
> @@ -1629,10 +1629,10 @@ static inline void decode(DisasContext *dc, uint32_t ir)
>  }
>  
>  /* generate intermediate code for basic block 'tb'.  */
> -void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
>  {
> -    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUMBState *env = cpu->env_ptr;
> +    MicroBlazeCPU *mb_cpu = mb_env_get_cpu(env);
>      uint32_t pc_start;
>      struct DisasContext ctx;
>      struct DisasContext *dc = &ctx;
> @@ -1642,7 +1642,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
>      int max_insns;
>  
>      pc_start = tb->pc;
> -    dc->cpu = cpu;
> +    dc->cpu = mb_cpu;
>      dc->tb = tb;
>      org_flags = dc->synced_flags = dc->tb_flags = tb->flags;
>  
> @@ -1653,19 +1653,19 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
>          dc->jmp = JMP_INDIRECT;
>      }
>      dc->pc = pc_start;
> -    dc->singlestep_enabled = cs->singlestep_enabled;
> +    dc->singlestep_enabled = cpu->singlestep_enabled;
>      dc->cpustate_changed = 0;
>      dc->abort_at_next_insn = 0;
>      dc->nr_nops = 0;
>  
>      if (pc_start & 3) {
> -        cpu_abort(cs, "Microblaze: unaligned PC=%x\n", pc_start);
> +        cpu_abort(cpu, "Microblaze: unaligned PC=%x\n", pc_start);
>      }
>  
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>  #if !SIM_COMPAT
>          qemu_log("--------------\n");
> -        log_cpu_state(CPU(cpu), 0);
> +        log_cpu_state(CPU(mb_cpu), 0);
>  #endif
>      }
>  
> @@ -1692,7 +1692,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
>          }
>  #endif
>  
> -        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
>              t_gen_raise_exception(dc, EXCP_DEBUG);
>              dc->is_jmp = DISAS_UPDATE;
>              /* The address covered by the breakpoint must be included in
> @@ -1749,7 +1749,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
>                  break;
>              }
>          }
> -        if (cs->singlestep_enabled) {
> +        if (cpu->singlestep_enabled) {
>              break;
>          }
>      } while (!dc->is_jmp && !dc->cpustate_changed
> @@ -1770,7 +1770,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
>  
>      if (tb->cflags & CF_LAST_IO)
>          gen_io_end();
> -    /* Force an update if the per-tb cpu state has changed.  */
> +    /* Force an update if the per-tb mb_cpu state has changed.  */
>      if (dc->is_jmp == DISAS_NEXT
>          && (dc->cpustate_changed || org_flags != dc->tb_flags)) {
>          dc->is_jmp = DISAS_UPDATE;
> @@ -1778,7 +1778,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
>      }
>      t_sync_flags(dc);
>  
> -    if (unlikely(cs->singlestep_enabled)) {
> +    if (unlikely(cpu->singlestep_enabled)) {
>          TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
>  
>          if (dc->is_jmp != DISAS_JUMP) {
> @@ -1813,7 +1813,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>          qemu_log("\n");
>  #if DISAS_GNU
> -        log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
> +        log_target_disas(cpu, pc_start, dc->pc - pc_start, 0);
>  #endif
>          qemu_log("\nisize=%d osize=%d\n",
>                   dc->pc - pc_start, tcg_op_buf_count());
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index a3a05ec..2c2f14a 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -19737,10 +19737,9 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
>      }
>  }
>  
> -void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
>  {
> -    MIPSCPU *cpu = mips_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUMIPSState *env = cpu->env_ptr;
>      DisasContext ctx;
>      target_ulong pc_start;
>      target_ulong next_page_start;
> @@ -19753,7 +19752,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
>      next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
>      ctx.pc = pc_start;
>      ctx.saved_pc = -1;
> -    ctx.singlestep_enabled = cs->singlestep_enabled;
> +    ctx.singlestep_enabled = cpu->singlestep_enabled;
>      ctx.insn_flags = env->insn_flags;
>      ctx.CP0_Config1 = env->CP0_Config1;
>      ctx.tb = tb;
> @@ -19798,7 +19797,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
>          tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
>          num_insns++;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, ctx.pc, BP_ANY))) {
>              save_cpu_state(&ctx, 1);
>              ctx.bstate = BS_BRANCH;
>              gen_helper_raise_exception_debug(cpu_env);
> @@ -19853,7 +19852,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
>             This is what GDB expects and is consistent with what the
>             hardware does (e.g. if a delay slot instruction faults, the
>             reported PC is the PC of the branch).  */
> -        if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
> +        if (cpu->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
>              break;
>          }
>  
> @@ -19874,7 +19873,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
>      if (tb->cflags & CF_LAST_IO) {
>          gen_io_end();
>      }
> -    if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
> +    if (cpu->singlestep_enabled && ctx.bstate != BS_BRANCH) {
>          save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
>          gen_helper_raise_exception_debug(cpu_env);
>      } else {
> @@ -19904,7 +19903,7 @@ done_generating:
>      LOG_DISAS("\n");
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>          qemu_log("IN: %s\n", lookup_symbol(pc_start));
> -        log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
> +        log_target_disas(cpu, pc_start, ctx.pc - pc_start, 0);
>          qemu_log("\n");
>      }
>  #endif
> diff --git a/target-moxie/translate.c b/target-moxie/translate.c
> index a437e2a..19f7453 100644
> --- a/target-moxie/translate.c
> +++ b/target-moxie/translate.c
> @@ -812,10 +812,10 @@ static int decode_opc(MoxieCPU *cpu, DisasContext *ctx)
>  }
>  
>  /* generate intermediate code for basic block 'tb'.  */
> -void gen_intermediate_code(CPUMoxieState *env, struct TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
>  {
> -    MoxieCPU *cpu = moxie_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUMoxieState *env = cpu->env_ptr;
> +    MoxieCPU *moxie_cpu = moxie_env_get_cpu(env);
>      DisasContext ctx;
>      target_ulong pc_start;
>      int num_insns, max_insns;
> @@ -841,7 +841,7 @@ void gen_intermediate_code(CPUMoxieState *env, struct TranslationBlock *tb)
>          tcg_gen_insn_start(ctx.pc);
>          num_insns++;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, ctx.pc, BP_ANY))) {
>              tcg_gen_movi_i32(cpu_pc, ctx.pc);
>              gen_helper_debug(cpu_env);
>              ctx.bstate = BS_EXCP;
> @@ -854,12 +854,12 @@ void gen_intermediate_code(CPUMoxieState *env, struct TranslationBlock *tb)
>          }
>  
>          ctx.opcode = cpu_lduw_code(env, ctx.pc);
> -        ctx.pc += decode_opc(cpu, &ctx);
> +        ctx.pc += decode_opc(moxie_cpu, &ctx);
>  
>          if (num_insns >= max_insns) {
>              break;
>          }
> -        if (cs->singlestep_enabled) {
> +        if (cpu->singlestep_enabled) {
>              break;
>          }
>          if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) {
> @@ -867,7 +867,7 @@ void gen_intermediate_code(CPUMoxieState *env, struct TranslationBlock *tb)
>          }
>      } while (ctx.bstate == BS_NONE && !tcg_op_buf_full());
>  
> -    if (cs->singlestep_enabled) {
> +    if (cpu->singlestep_enabled) {
>          tcg_gen_movi_tl(cpu_pc, ctx.pc);
>          gen_helper_debug(cpu_env);
>      } else {
> diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
> index 5d0ab44..b441625 100644
> --- a/target-openrisc/translate.c
> +++ b/target-openrisc/translate.c
> @@ -1619,10 +1619,10 @@ static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
>      }
>  }
>  
> -void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
>  {
> -    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUOpenRISCState *env = cpu->env_ptr;
> +    OpenRISCCPU *or_cpu = openrisc_env_get_cpu(env);
>      struct DisasContext ctx, *dc = &ctx;
>      uint32_t pc_start;
>      uint32_t next_page_start;
> @@ -1635,14 +1635,14 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
>      dc->is_jmp = DISAS_NEXT;
>      dc->ppc = pc_start;
>      dc->pc = pc_start;
> -    dc->flags = cpu->env.cpucfgr;
> -    dc->mem_idx = cpu_mmu_index(&cpu->env, false);
> +    dc->flags = or_cpu->env.cpucfgr;
> +    dc->mem_idx = cpu_mmu_index(&or_cpu->env, false);
>      dc->synced_flags = dc->tb_flags = tb->flags;
>      dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
> -    dc->singlestep_enabled = cs->singlestep_enabled;
> +    dc->singlestep_enabled = cpu->singlestep_enabled;
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>          qemu_log("-----------------------------------------\n");
> -        log_cpu_state(CPU(cpu), 0);
> +        log_cpu_state(CPU(or_cpu), 0);
>      }
>  
>      next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
> @@ -1662,7 +1662,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
>          tcg_gen_insn_start(dc->pc);
>          num_insns++;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
>              tcg_gen_movi_tl(cpu_pc, dc->pc);
>              gen_exception(dc, EXCP_DEBUG);
>              dc->is_jmp = DISAS_UPDATE;
> @@ -1681,7 +1681,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
>          dc->npc = dc->pc + 4;
>          tcg_gen_movi_tl(cpu_ppc, dc->ppc);
>          tcg_gen_movi_tl(cpu_npc, dc->npc);
> -        disas_openrisc_insn(dc, cpu);
> +        disas_openrisc_insn(dc, or_cpu);
>          dc->pc = dc->npc;
>          /* delay slot */
>          if (dc->delayed_branch) {
> @@ -1699,7 +1699,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
>          }
>      } while (!dc->is_jmp
>               && !tcg_op_buf_full()
> -             && !cs->singlestep_enabled
> +             && !cpu->singlestep_enabled
>               && !singlestep
>               && (dc->pc < next_page_start)
>               && num_insns < max_insns);
> @@ -1711,7 +1711,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
>          dc->is_jmp = DISAS_UPDATE;
>          tcg_gen_movi_tl(cpu_pc, dc->pc);
>      }
> -    if (unlikely(cs->singlestep_enabled)) {
> +    if (unlikely(cpu->singlestep_enabled)) {
>          if (dc->is_jmp == DISAS_NEXT) {
>              tcg_gen_movi_tl(cpu_pc, dc->pc);
>          }
> @@ -1743,7 +1743,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
>  #ifdef DEBUG_DISAS
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>          qemu_log("\n");
> -        log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
> +        log_target_disas(cpu, pc_start, dc->pc - pc_start, 0);
>          qemu_log("\nisize=%d osize=%d\n",
>                   dc->pc - pc_start, tcg_op_buf_count());
>      }
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index b3860ec..bad896e 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -11438,10 +11438,9 @@ void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
>  }
>  
>  /*****************************************************************************/
> -void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
>  {
> -    PowerPCCPU *cpu = ppc_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUPPCState *env = cpu->env_ptr;
>      DisasContext ctx, *ctxp = &ctx;
>      opc_handler_t **table, *handler;
>      target_ulong pc_start;
> @@ -11492,7 +11491,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
>          ctx.singlestep_enabled = 0;
>      if ((env->flags & POWERPC_FLAG_BE) && msr_be)
>          ctx.singlestep_enabled |= CPU_BRANCH_STEP;
> -    if (unlikely(cs->singlestep_enabled)) {
> +    if (unlikely(cpu->singlestep_enabled)) {
>          ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
>      }
>  #if defined (DO_SINGLE_STEP) && 0
> @@ -11515,7 +11514,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
>          tcg_gen_insn_start(ctx.nip);
>          num_insns++;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, ctx.nip, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, ctx.nip, BP_ANY))) {
>              gen_debug_exception(ctxp);
>              /* The address covered by the breakpoint must be included in
>                 [tb->pc, tb->pc + tb->size) in order to for it to be
> @@ -11586,7 +11585,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
>                       ctx.exception != POWERPC_EXCP_BRANCH)) {
>              gen_exception(ctxp, POWERPC_EXCP_TRACE);
>          } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
> -                            (cs->singlestep_enabled) ||
> +                            (cpu->singlestep_enabled) ||
>                              singlestep ||
>                              num_insns >= max_insns)) {
>              /* if we reach a page boundary or are single stepping, stop
> @@ -11606,7 +11605,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
>      if (ctx.exception == POWERPC_EXCP_NONE) {
>          gen_goto_tb(&ctx, 0, ctx.nip);
>      } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
> -        if (unlikely(cs->singlestep_enabled)) {
> +        if (unlikely(cpu->singlestep_enabled)) {
>              gen_debug_exception(ctxp);
>          }
>          /* Generate the return instruction */
> @@ -11623,7 +11622,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
>          flags = env->bfd_mach;
>          flags |= ctx.le_mode << 16;
>          qemu_log("IN: %s\n", lookup_symbol(pc_start));
> -        log_target_disas(cs, pc_start, ctx.nip - pc_start, flags);
> +        log_target_disas(cpu, pc_start, ctx.nip - pc_start, flags);
>          qemu_log("\n");
>      }
>  #endif
> diff --git a/target-s390x/translate.c b/target-s390x/translate.c
> index c871ef2..9aac7cd 100644
> --- a/target-s390x/translate.c
> +++ b/target-s390x/translate.c
> @@ -5319,10 +5319,9 @@ static ExitStatus translate_one(CPUS390XState *env, DisasContext *s)
>      return ret;
>  }
>  
> -void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
>  {
> -    S390CPU *cpu = s390_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUS390XState *env = cpu->env_ptr;
>      DisasContext dc;
>      target_ulong pc_start;
>      uint64_t next_page_start;
> @@ -5340,7 +5339,7 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
>      dc.tb = tb;
>      dc.pc = pc_start;
>      dc.cc_op = CC_OP_DYNAMIC;
> -    do_debug = dc.singlestep_enabled = cs->singlestep_enabled;
> +    do_debug = dc.singlestep_enabled = cpu->singlestep_enabled;
>  
>      next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
>  
> @@ -5359,7 +5358,7 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
>          tcg_gen_insn_start(dc.pc, dc.cc_op);
>          num_insns++;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, dc.pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, dc.pc, BP_ANY))) {
>              status = EXIT_PC_STALE;
>              do_debug = true;
>              /* The address covered by the breakpoint must be included in
> @@ -5386,7 +5385,7 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
>                  || tcg_op_buf_full()
>                  || num_insns >= max_insns
>                  || singlestep
> -                || cs->singlestep_enabled)) {
> +                || cpu->singlestep_enabled)) {
>              status = EXIT_PC_STALE;
>          }
>      } while (status == NO_EXIT);
> @@ -5425,7 +5424,7 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
>  #if defined(S390X_DEBUG_DISAS)
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>          qemu_log("IN: %s\n", lookup_symbol(pc_start));
> -        log_target_disas(cs, pc_start, dc.pc - pc_start, 1);
> +        log_target_disas(cpu, pc_start, dc.pc - pc_start, 1);
>          qemu_log("\n");
>      }
>  #endif
> diff --git a/target-sh4/translate.c b/target-sh4/translate.c
> index 7c18968..5c7fa2c 100644
> --- a/target-sh4/translate.c
> +++ b/target-sh4/translate.c
> @@ -1816,10 +1816,9 @@ static void decode_opc(DisasContext * ctx)
>          gen_store_flags(ctx->flags);
>  }
>  
> -void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
>  {
> -    SuperHCPU *cpu = sh_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUSH4State * env = cpu->env_ptr;
>      DisasContext ctx;
>      target_ulong pc_start;
>      int num_insns;
> @@ -1834,7 +1833,7 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
>         so assume it is a dynamic branch.  */
>      ctx.delayed_pc = -1; /* use delayed pc from env pointer */
>      ctx.tb = tb;
> -    ctx.singlestep_enabled = cs->singlestep_enabled;
> +    ctx.singlestep_enabled = cpu->singlestep_enabled;
>      ctx.features = env->features;
>      ctx.has_movcal = (ctx.flags & TB_FLAG_PENDING_MOVCA);
>  
> @@ -1852,7 +1851,7 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
>          tcg_gen_insn_start(ctx.pc, ctx.flags);
>          num_insns++;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, ctx.pc, BP_ANY))) {
>              /* We have hit a breakpoint - make sure PC is up-to-date */
>              tcg_gen_movi_i32(cpu_pc, ctx.pc);
>              gen_helper_debug(cpu_env);
> @@ -1874,7 +1873,7 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
>  	ctx.pc += 2;
>  	if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
>  	    break;
> -        if (cs->singlestep_enabled) {
> +        if (cpu->singlestep_enabled) {
>  	    break;
>          }
>          if (num_insns >= max_insns)
> @@ -1884,7 +1883,7 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
>      }
>      if (tb->cflags & CF_LAST_IO)
>          gen_io_end();
> -    if (cs->singlestep_enabled) {
> +    if (cpu->singlestep_enabled) {
>          tcg_gen_movi_i32(cpu_pc, ctx.pc);
>          gen_helper_debug(cpu_env);
>      } else {
> @@ -1916,7 +1915,7 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
>  #ifdef DEBUG_DISAS
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>  	qemu_log("IN:\n");	/* , lookup_symbol(pc_start)); */
> -        log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
> +        log_target_disas(cpu, pc_start, ctx.pc - pc_start, 0);
>  	qemu_log("\n");
>      }
>  #endif
> diff --git a/target-sparc/translate.c b/target-sparc/translate.c
> index 7998ff5..cc634ce 100644
> --- a/target-sparc/translate.c
> +++ b/target-sparc/translate.c
> @@ -5217,10 +5217,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
>      }
>  }
>  
> -void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
> +void gen_intermediate_code(CPUState *cpu, TranslationBlock * tb)
>  {
> -    SPARCCPU *cpu = sparc_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUSPARCState * env = cpu->env_ptr;
>      target_ulong pc_start, last_pc;
>      DisasContext dc1, *dc = &dc1;
>      int num_insns;
> @@ -5238,7 +5237,7 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
>      dc->def = env->def;
>      dc->fpu_enabled = tb_fpu_enabled(tb->flags);
>      dc->address_mask_32bit = tb_am_enabled(tb->flags);
> -    dc->singlestep = (cs->singlestep_enabled || singlestep);
> +    dc->singlestep = (cpu->singlestep_enabled || singlestep);
>  
>      num_insns = 0;
>      max_insns = tb->cflags & CF_COUNT_MASK;
> @@ -5260,7 +5259,7 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
>          num_insns++;
>          last_pc = dc->pc;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
>              if (dc->pc != pc_start) {
>                  save_state(dc);
>              }
> @@ -5322,7 +5321,7 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>          qemu_log("--------------\n");
>          qemu_log("IN: %s\n", lookup_symbol(pc_start));
> -        log_target_disas(cs, pc_start, last_pc + 4 - pc_start, 0);
> +        log_target_disas(cpu, pc_start, last_pc + 4 - pc_start, 0);
>          qemu_log("\n");
>      }
>  #endif
> diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
> index 03918eb..afb248d 100644
> --- a/target-tilegx/translate.c
> +++ b/target-tilegx/translate.c
> @@ -2369,12 +2369,11 @@ static void translate_one_bundle(DisasContext *dc, uint64_t bundle)
>      }
>  }
>  
> -void gen_intermediate_code(CPUTLGState *env, struct TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
>  {
> -    TileGXCPU *cpu = tilegx_env_get_cpu(env);
> +    CPUTLGState *env = cpu->env_ptr;
>      DisasContext ctx;
>      DisasContext *dc = &ctx;
> -    CPUState *cs = CPU(cpu);
>      uint64_t pc_start = tb->pc;
>      uint64_t next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
>      int num_insns = 0;
> @@ -2395,7 +2394,7 @@ void gen_intermediate_code(CPUTLGState *env, struct TranslationBlock *tb)
>      if (!max_insns) {
>          max_insns = CF_COUNT_MASK;
>      }
> -    if (cs->singlestep_enabled || singlestep) {
> +    if (cpu->singlestep_enabled || singlestep) {
>          max_insns = 1;
>      }
>      if (max_insns > TCG_MAX_INSNS) {
> diff --git a/target-tricore/translate.c b/target-tricore/translate.c
> index 912bf22..c852ec6 100644
> --- a/target-tricore/translate.c
> +++ b/target-tricore/translate.c
> @@ -8722,10 +8722,9 @@ static void decode_opc(CPUTriCoreState *env, DisasContext *ctx, int *is_branch)
>      }
>  }
>  
> -void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
>  {
> -    TriCoreCPU *cpu = tricore_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUTriCoreState *env = cpu->env_ptr;
>      DisasContext ctx;
>      target_ulong pc_start;
>      int num_insns, max_insns;
> @@ -8746,7 +8745,7 @@ void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb)
>      ctx.pc = pc_start;
>      ctx.saved_pc = -1;
>      ctx.tb = tb;
> -    ctx.singlestep_enabled = cs->singlestep_enabled;
> +    ctx.singlestep_enabled = cpu->singlestep_enabled;
>      ctx.bstate = BS_NONE;
>      ctx.mem_idx = cpu_mmu_index(env, false);
>  
> @@ -8778,7 +8777,7 @@ void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb)
>  #ifdef DEBUG_DISAS
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>          qemu_log("IN: %s\n", lookup_symbol(pc_start));
> -        log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
> +        log_target_disas(cpu, pc_start, ctx.pc - pc_start, 0);
>          qemu_log("\n");
>      }
>  #endif
> diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
> index 39af3af..cbe6bc2 100644
> --- a/target-unicore32/translate.c
> +++ b/target-unicore32/translate.c
> @@ -1861,10 +1861,9 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
>  }
>  
>  /* generate intermediate code for basic block 'tb'.  */
> -void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
>  {
> -    UniCore32CPU *cpu = uc32_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUUniCore32State *env = cpu->env_ptr;
>      DisasContext dc1, *dc = &dc1;
>      target_ulong pc_start;
>      uint32_t next_page_start;
> @@ -1880,7 +1879,7 @@ void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
>  
>      dc->is_jmp = DISAS_NEXT;
>      dc->pc = pc_start;
> -    dc->singlestep_enabled = cs->singlestep_enabled;
> +    dc->singlestep_enabled = cpu->singlestep_enabled;
>      dc->condjmp = 0;
>      cpu_F0s = tcg_temp_new_i32();
>      cpu_F1s = tcg_temp_new_i32();
> @@ -1909,7 +1908,7 @@ void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
>          tcg_gen_insn_start(dc->pc);
>          num_insns++;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, dc->pc, BP_ANY))) {
>              gen_set_pc_im(dc->pc);
>              gen_exception(EXCP_DEBUG);
>              dc->is_jmp = DISAS_JUMP;
> @@ -1941,7 +1940,7 @@ void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
>           * Also stop translation when a page boundary is reached.  This
>           * ensures prefetch aborts occur at the right place.  */
>      } while (!dc->is_jmp && !tcg_op_buf_full() &&
> -             !cs->singlestep_enabled &&
> +             !cpu->singlestep_enabled &&
>               !singlestep &&
>               dc->pc < next_page_start &&
>               num_insns < max_insns);
> @@ -1950,7 +1949,7 @@ void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
>          if (dc->condjmp) {
>              /* FIXME:  This can theoretically happen with self-modifying
>                 code.  */
> -            cpu_abort(cs, "IO on conditional branch instruction");
> +            cpu_abort(cpu, "IO on conditional branch instruction");
>          }
>          gen_io_end();
>      }
> @@ -1958,7 +1957,7 @@ void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
>      /* At this stage dc->condjmp will only be set when the skipped
>         instruction was a conditional branch or trap, and the PC has
>         already been written.  */
> -    if (unlikely(cs->singlestep_enabled)) {
> +    if (unlikely(cpu->singlestep_enabled)) {
>          /* Make sure the pc is updated, and raise a debug exception.  */
>          if (dc->condjmp) {
>              if (dc->is_jmp == DISAS_SYSCALL) {
> @@ -2017,7 +2016,7 @@ done_generating:
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>          qemu_log("----------------\n");
>          qemu_log("IN: %s\n", lookup_symbol(pc_start));
> -        log_target_disas(cs, pc_start, dc->pc - pc_start, 0);
> +        log_target_disas(cpu, pc_start, dc->pc - pc_start, 0);
>          qemu_log("\n");
>      }
>  #endif
> diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
> index 9894488..51803d5 100644
> --- a/target-xtensa/translate.c
> +++ b/target-xtensa/translate.c
> @@ -3031,10 +3031,9 @@ static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
>      }
>  }
>  
> -void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
> +void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
>  {
> -    XtensaCPU *cpu = xtensa_env_get_cpu(env);
> -    CPUState *cs = CPU(cpu);
> +    CPUXtensaState *env = cpu->env_ptr;
>      DisasContext dc;
>      int insn_count = 0;
>      int max_insns = tb->cflags & CF_COUNT_MASK;
> @@ -3050,7 +3049,7 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
>      }
>  
>      dc.config = env->config;
> -    dc.singlestep_enabled = cs->singlestep_enabled;
> +    dc.singlestep_enabled = cpu->singlestep_enabled;
>      dc.tb = tb;
>      dc.pc = pc_start;
>      dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK;
> @@ -3085,7 +3084,7 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
>  
>          ++dc.ccount_delta;
>  
> -        if (unlikely(cpu_breakpoint_test(cs, dc.pc, BP_ANY))) {
> +        if (unlikely(cpu_breakpoint_test(cpu, dc.pc, BP_ANY))) {
>              tcg_gen_movi_i32(cpu_pc, dc.pc);
>              gen_exception(&dc, EXCP_DEBUG);
>              dc.is_jmp = DISAS_UPDATE;
> @@ -3121,7 +3120,7 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
>          if (dc.icount) {
>              tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount);
>          }
> -        if (cs->singlestep_enabled) {
> +        if (cpu->singlestep_enabled) {
>              tcg_gen_movi_i32(cpu_pc, dc.pc);
>              gen_exception(&dc, EXCP_DEBUG);
>              break;
> @@ -3151,7 +3150,7 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
>      if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
>          qemu_log("----------------\n");
>          qemu_log("IN: %s\n", lookup_symbol(pc_start));
> -        log_target_disas(cs, pc_start, dc.pc - pc_start, 0);
> +        log_target_disas(cpu, pc_start, dc.pc - pc_start, 0);
>          qemu_log("\n");
>      }
>  #endif
> diff --git a/translate-all.c b/translate-all.c
> index 8329ea6..940652c 100644
> --- a/translate-all.c
> +++ b/translate-all.c
> @@ -1094,7 +1094,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
>  
>      tcg_func_start(&tcg_ctx);
>  
> -    gen_intermediate_code(env, tb);
> +    gen_intermediate_code(cpu, tb);
>  
>      trace_translate_block(tb, tb->pc, tb->tc_ptr);
>  
> 
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH 3/4] target: [tcg] Add generic translation framework
  2016-07-15 16:12 ` [Qemu-devel] [PATCH 3/4] target: [tcg] Add generic translation framework Lluís Vilanova
@ 2016-07-18 13:10   ` Richard Henderson
  2016-07-18 13:55     ` Lluís Vilanova
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2016-07-18 13:10 UTC (permalink / raw)
  To: Lluís Vilanova, qemu-devel
  Cc: Peter Crosthwaite, Paolo Bonzini, Andreas Färber

On 07/15/2016 09:42 PM, Lluís Vilanova wrote:
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
>  include/exec/translate-all_template.h |   58 ++++++++++++
>  include/qom/cpu.h                     |   21 ++++
>  translate-all_template.h              |  160 +++++++++++++++++++++++++++++++++
>  3 files changed, 239 insertions(+)
>  create mode 100644 include/exec/translate-all_template.h
>  create mode 100644 translate-all_template.h
>
> diff --git a/include/exec/translate-all_template.h b/include/exec/translate-all_template.h
> new file mode 100644
> index 0000000..9e0c361
> --- /dev/null
> +++ b/include/exec/translate-all_template.h
> @@ -0,0 +1,58 @@
> +/*
> + * Generic intermediate code generation.
> + *
> + * Copyright (C) 2016 Lluís Vilanova <vilanova@ac.upc.edu>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#ifndef EXEC__TRANSLATE_ALL_TEMPLATE_H
> +#define EXEC__TRANSLATE_ALL_TEMPLATE_H
> +
> +/*
> + * Include this header from a target-specific file, and add a
> + *
> + *     DisasContextBase base;
> + *
> + * member in your target-specific DisasContext.
> + */
> +
> +
> +#include "exec/exec-all.h"
> +
> +
> +/**
> + * DisasJumpType:
> + * @DJ_NEXT: Next instruction in program order
> + * @DJ_TOO_MANY: Too many instructions executed
> + * @DJ_TARGET: Start of target-specific conditions
> + *
> + * What instruction to disassemble next.
> + */
> +typedef enum DisasJumpType
> +{
> +    DJ_NEXT,
> +    DJ_TOO_MANY,
> +    DJ_TARGET,
> +} DisasJumpType;

I think you might as well add the common cases: exit tb via exception, exit via 
goto_tb, exit via indirect jump (pc updated), exit for state change (pc not 
updated).

See the set used for alpha.

> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
> +{
> +    CPUArchState *env = cpu->env_ptr;
> +    DisasContext dc1, *dc = &dc1;
> +    int num_insns;
> +    int max_insns;
> +
> +    /* Initialize DisasContext */
> +    dc->base.tb = tb;
> +    dc->base.singlestep_enabled = cpu->singlestep_enabled;
> +    dc->base.pc_first = tb->pc;
> +    dc->base.pc_next = dc->base.pc_first;
> +    dc->base.jmp_type = DJ_NEXT;
> +    gen_intermediate_code_target_init_disas_context(dc, env);
> +
> +    /* Target-specific globals */
> +    gen_intermediate_code_target_init_globals(dc, env);
> +
> +    /* Instruction counting */
> +    num_insns = 0;
> +    max_insns = dc->base.tb->cflags & CF_COUNT_MASK;
> +    if (max_insns == 0) {
> +        max_insns = CF_COUNT_MASK;
> +    }
> +    if (max_insns > TCG_MAX_INSNS) {
> +        max_insns = TCG_MAX_INSNS;
> +    }

I've started adding the singlestep check here, outside the loop, setting 
max_insns to 1.

> +
> +    /* Start translating */
> +    gen_tb_start(dc->base.tb);
> +
> +    while (true) {
> +        CPUBreakpoint *bp;
> +
> +        tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);

You've probably discovered that this will have to be its own hook.

> +        num_insns++;
> +
> +        /* Pass breakpoint hits to target for further processing */
> +        bp = NULL;
> +        do {
> +            bp = cpu_breakpoint_get(cpu, dc->base.pc_next, bp);
> +            if (unlikely(bp)) {
> +                if (gen_intermediate_code_target_breakpoint_hit(dc, env, bp)) {
> +                    goto done_generating;
> +                }
> +            }
> +        } while (bp != NULL);

Why would you need to loop here?


r~

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH 3/4] target: [tcg] Add generic translation framework
  2016-07-18 13:10   ` Richard Henderson
@ 2016-07-18 13:55     ` Lluís Vilanova
  0 siblings, 0 replies; 9+ messages in thread
From: Lluís Vilanova @ 2016-07-18 13:55 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel, Paolo Bonzini, Andreas Färber, Peter Crosthwaite

Richard Henderson writes:

> On 07/15/2016 09:42 PM, Lluís Vilanova wrote:
>> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
>> ---
>> include/exec/translate-all_template.h |   58 ++++++++++++
>> include/qom/cpu.h                     |   21 ++++
>> translate-all_template.h              |  160 +++++++++++++++++++++++++++++++++
>> 3 files changed, 239 insertions(+)
>> create mode 100644 include/exec/translate-all_template.h
>> create mode 100644 translate-all_template.h
>> 
>> diff --git a/include/exec/translate-all_template.h b/include/exec/translate-all_template.h
>> new file mode 100644
>> index 0000000..9e0c361
>> --- /dev/null
>> +++ b/include/exec/translate-all_template.h
>> @@ -0,0 +1,58 @@
>> +/*
>> + * Generic intermediate code generation.
>> + *
>> + * Copyright (C) 2016 Lluís Vilanova <vilanova@ac.upc.edu>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
>> + * See the COPYING file in the top-level directory.
>> + */
>> +
>> +#ifndef EXEC__TRANSLATE_ALL_TEMPLATE_H
>> +#define EXEC__TRANSLATE_ALL_TEMPLATE_H
>> +
>> +/*
>> + * Include this header from a target-specific file, and add a
>> + *
>> + *     DisasContextBase base;
>> + *
>> + * member in your target-specific DisasContext.
>> + */
>> +
>> +
>> +#include "exec/exec-all.h"
>> +
>> +
>> +/**
>> + * DisasJumpType:
>> + * @DJ_NEXT: Next instruction in program order
>> + * @DJ_TOO_MANY: Too many instructions executed
>> + * @DJ_TARGET: Start of target-specific conditions
>> + *
>> + * What instruction to disassemble next.
>> + */
>> +typedef enum DisasJumpType
>> +{
>> +    DJ_NEXT,
>> +    DJ_TOO_MANY,
>> +    DJ_TARGET,
>> +} DisasJumpType;

> I think you might as well add the common cases: exit tb via exception, exit via
> goto_tb, exit via indirect jump (pc updated), exit for state change (pc not
> updated).

> See the set used for alpha.

Do you mean the "DISAS_*" values in "exec-all.h"? I looked into it, but could
not fully understand when they are supposed to be used (seem inconsistent across
targets), so I decided to defer this to the target.


>> +void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
>> +{
>> +    CPUArchState *env = cpu->env_ptr;
>> +    DisasContext dc1, *dc = &dc1;
>> +    int num_insns;
>> +    int max_insns;
>> +
>> +    /* Initialize DisasContext */
>> +    dc->base.tb = tb;
>> +    dc->base.singlestep_enabled = cpu->singlestep_enabled;
>> +    dc->base.pc_first = tb->pc;
>> +    dc->base.pc_next = dc->base.pc_first;
>> +    dc->base.jmp_type = DJ_NEXT;
>> +    gen_intermediate_code_target_init_disas_context(dc, env);
>> +
>> +    /* Target-specific globals */
>> +    gen_intermediate_code_target_init_globals(dc, env);
>> +
>> +    /* Instruction counting */
>> +    num_insns = 0;
>> +    max_insns = dc->base.tb->cflags & CF_COUNT_MASK;
>> +    if (max_insns == 0) {
>> +        max_insns = CF_COUNT_MASK;
>> +    }
>> +    if (max_insns > TCG_MAX_INSNS) {
>> +        max_insns = TCG_MAX_INSNS;
>> +    }

> I've started adding the singlestep check here, outside the loop, setting
> max_insns to 1.

That makes sense, and could eliminate one field in DisasContextBase.


>> +
>> +    /* Start translating */
>> +    gen_tb_start(dc->base.tb);
>> +
>> +    while (true) {
>> +        CPUBreakpoint *bp;
>> +
>> +        tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);

> You've probably discovered that this will have to be its own hook.

Yes, sorry about not fixing it before sending.


>> +        num_insns++;
>> +
>> +        /* Pass breakpoint hits to target for further processing */
>> +        bp = NULL;
>> +        do {
>> +            bp = cpu_breakpoint_get(cpu, dc->base.pc_next, bp);
>> +            if (unlikely(bp)) {
>> +                if (gen_intermediate_code_target_breakpoint_hit(dc, env, bp)) {
>> +                    goto done_generating;
>> +                }
>> +            }
>> +        } while (bp != NULL);

> Why would you need to loop here?

cpu_breakpoint_get() just returns breakpoints matching a PC, and delays other
checks (like flags) to target code. That's why cpu_breakpoint_get() is now used
as a looping construct (thus the change in qlist to continue a previous
foreach).


Thanks,
  Lluis

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-07-18 13:55 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-15 16:12 [Qemu-devel] [RFC PATCH 0/4] translate: [tcg] Generic translation framework Lluís Vilanova
2016-07-15 16:12 ` [Qemu-devel] [PATCH 1/4] Pass generic CPUState to gen_intermediate_code() Lluís Vilanova
2016-07-18  1:39   ` [Qemu-devel] [Qemu-ppc] " David Gibson
2016-07-15 16:12 ` [Qemu-devel] [PATCH 2/4] queue: Add macro for incremental traversal Lluís Vilanova
2016-07-15 16:12 ` [Qemu-devel] [PATCH 3/4] target: [tcg] Add generic translation framework Lluís Vilanova
2016-07-18 13:10   ` Richard Henderson
2016-07-18 13:55     ` Lluís Vilanova
2016-07-15 16:12 ` [Qemu-devel] [PATCH 4/4] target: [tcg, i386] Port to " Lluís Vilanova
2016-07-15 16:27 ` [Qemu-devel] [RFC PATCH 0/4] translate: [tcg] Generic " Lluís Vilanova

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.