All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework
@ 2016-09-09 13:03 Lluís Vilanova
  2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 1/6] Pass generic CPUState to gen_intermediate_code() Lluís Vilanova
                   ` (9 more replies)
  0 siblings, 10 replies; 15+ messages in thread
From: Lluís Vilanova @ 2016-09-09 13:03 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>
---

Changes in v2
=============

* Port ARM and AARCH64 targets.
* Fold single-stepping checks into "max_insns" [Richard Henderson].
* Move instruction start marks to target code [Richard Henderson].
* Add target hook for TB start.
* Check for TCG temporary leaks.
* Move instruction disassembly into a target hook.
* Make breakpoint_hit() return an enum to accomodate target's needs (ARM).


Lluís Vilanova (6):
      Pass generic CPUState to gen_intermediate_code()
      queue: Add macro for incremental traversal
      target: [tcg] Add generic translation framework
      target: [tcg] Redefine DISAS_* onto the generic translation framework (DJ_*)
      target: [tcg,i386] Port to generic translation framework
      target: [tcg,arm] Port to generic translation framework


 include/exec/exec-all.h               |   13 -
 include/exec/gen-icount.h             |    2 
 include/exec/translate-all_template.h |   76 +++
 include/qemu/queue.h                  |    5 
 include/qom/cpu.h                     |   21 +
 target-alpha/translate.c              |   11 -
 target-arm/translate-a64.c            |  342 ++++++++--------
 target-arm/translate.c                |  718 +++++++++++++++++----------------
 target-arm/translate.h                |   41 +-
 target-cris/translate.c               |   20 -
 target-i386/translate.c               |  307 +++++++-------
 target-lm32/translate.c               |   22 +
 target-m68k/translate.c               |   18 -
 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              |   16 -
 target-sh4/translate.c                |   15 -
 target-sparc/translate.c              |   11 -
 target-tilegx/translate.c             |    7 
 target-tricore/translate.c            |    9 
 target-unicore32/translate.c          |   20 -
 target-xtensa/translate.c             |   13 -
 translate-all.c                       |    2 
 translate-all_template.h              |  200 +++++++++
 27 files changed, 1130 insertions(+), 851 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] 15+ messages in thread

* [Qemu-devel] [PATCH v2 1/6] Pass generic CPUState to gen_intermediate_code()
  2016-09-09 13:03 [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework Lluís Vilanova
@ 2016-09-09 13:03 ` Lluís Vilanova
  2016-09-16 23:01   ` Richard Henderson
  2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 2/6] queue: Add macro for incremental traversal Lluís Vilanova
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 15+ messages in thread
From: Lluís Vilanova @ 2016-09-09 13:03 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, David Gibson,
	Alexander Graf, Mark Cave-Ayland, Artyom Tarasenko,
	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>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 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 d008296..17659e6 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -43,7 +43,7 @@ typedef ram_addr_t tb_page_addr_t;
 
 #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 0ea0e6e..5f77467 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -2869,10 +2869,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;
@@ -2887,7 +2886,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;
@@ -2926,7 +2925,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
@@ -3001,7 +3000,7 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
         && qemu_log_in_addr_range(pc_start)) {
         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 bd5d5cb..721a3d4 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -11624,10 +11624,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;
@@ -11641,7 +11641,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;
     }
 
@@ -11651,7 +11651,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;
@@ -11676,7 +11676,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:
@@ -11784,9 +11784,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);
@@ -11876,7 +11876,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 &&
@@ -11886,7 +11886,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();
     }
@@ -11894,7 +11894,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) {
@@ -12000,7 +12000,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 f4a8d7d..284543a 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3080,10 +3080,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;
@@ -3105,13 +3104,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;
@@ -3174,7 +3173,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);
@@ -3248,7 +3247,7 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
 
         /* If we are rexecuting a branch due to exceptions on
            delay slots don't break.  */
-        if (!(tb->pc & 1) && cs->singlestep_enabled) {
+        if (!(tb->pc & 1) && cpu->singlestep_enabled) {
             break;
         }
     } while (!dc->is_jmp && !dc->cpustate_changed
@@ -3281,7 +3280,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);
         }
@@ -3313,7 +3312,7 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb)
 #if !DISAS_CRIS
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
         && qemu_log_in_addr_range(pc_start)) {
-        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 fa2ac48..bfd9aed 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -8190,10 +8190,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;
     uint32_t flags;
@@ -8216,7 +8215,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;
@@ -8238,7 +8237,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));
     /* Do not optimize repz jumps at all in icount mode, because
        rep movsS instructions are execured with different paths
@@ -8287,7 +8286,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);
@@ -8362,7 +8361,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 2d8caeb..2e66b0c 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1045,10 +1045,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;
@@ -1056,14 +1056,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,
@@ -1086,7 +1086,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;
@@ -1109,7 +1109,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);
@@ -1118,7 +1118,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);
         }
@@ -1150,7 +1150,7 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
         && qemu_log_in_addr_range(pc_start)) {
         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 ecd5e5c..f7d131f 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2976,10 +2976,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;
@@ -2995,7 +2994,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;
@@ -3015,7 +3014,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
@@ -3033,14 +3032,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);
@@ -3072,7 +3071,7 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
         && 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, 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 80098ec..b92b98f 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1637,10 +1637,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;
@@ -1650,7 +1650,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;
 
@@ -1661,19 +1661,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
     }
 
@@ -1700,7 +1700,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
@@ -1757,7 +1757,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
@@ -1778,7 +1778,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;
@@ -1786,7 +1786,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) {
@@ -1822,7 +1822,7 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb)
         && qemu_log_in_addr_range(pc_start)) {
         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 bab52cb..4a372d1 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -19846,10 +19846,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;
@@ -19862,7 +19861,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;
@@ -19909,7 +19908,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);
@@ -19964,7 +19963,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;
         }
 
@@ -19985,7 +19984,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 {
@@ -20016,7 +20015,7 @@ done_generating:
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
         && qemu_log_in_addr_range(pc_start)) {
         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 0660b44..176063a 100644
--- a/target-moxie/translate.c
+++ b/target-moxie/translate.c
@@ -822,10 +822,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;
@@ -851,7 +851,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;
@@ -864,12 +864,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) {
@@ -877,7 +877,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 28c9446..9df1f7c 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1630,10 +1630,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;
@@ -1646,14 +1646,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;
@@ -1673,7 +1673,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;
@@ -1692,7 +1692,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) {
@@ -1710,7 +1710,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);
@@ -1722,7 +1722,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);
         }
@@ -1755,7 +1755,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb)
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
         && qemu_log_in_addr_range(pc_start)) {
         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 92030b6..5d628d7 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -11545,10 +11545,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;
@@ -11607,7 +11606,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
@@ -11630,7 +11629,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
@@ -11701,7 +11700,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
@@ -11721,7 +11720,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 */
@@ -11739,7 +11738,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 1a07d70..468531a 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -5326,10 +5326,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;
@@ -5347,7 +5346,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;
 
@@ -5366,7 +5365,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
@@ -5393,7 +5392,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);
@@ -5433,7 +5432,7 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
         && qemu_log_in_addr_range(pc_start)) {
         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 ca80cf7..3bc5bd5 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -1827,10 +1827,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;
@@ -1845,7 +1844,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);
 
@@ -1863,7 +1862,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);
@@ -1885,7 +1884,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)
@@ -1895,7 +1894,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 {
@@ -1928,7 +1927,7 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
         && qemu_log_in_addr_range(pc_start)) {
 	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 e7691e4..3761622 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5564,10 +5564,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;
@@ -5585,7 +5584,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);
 #ifdef TARGET_SPARC64
     dc->fprs_dirty = 0;
     dc->asi = (tb->flags >> TB_FLAG_ASI_SHIFT) & 0xff;
@@ -5611,7 +5610,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);
             }
@@ -5674,7 +5673,7 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
         && 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, 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 11c9732..973e6b6 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -2370,12 +2370,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;
@@ -2396,7 +2395,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 9a50df9..dd45c88 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -8733,10 +8733,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;
@@ -8757,7 +8756,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);
 
@@ -8790,7 +8789,7 @@ void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb)
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
         && qemu_log_in_addr_range(pc_start)) {
         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 09354f9..7499748 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -1869,10 +1869,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;
@@ -1888,7 +1887,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();
@@ -1917,7 +1916,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;
@@ -1949,7 +1948,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);
@@ -1958,7 +1957,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();
     }
@@ -1966,7 +1965,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) {
@@ -2026,7 +2025,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, 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 4c1e487..8425e99 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -3037,10 +3037,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;
@@ -3056,7 +3055,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;
@@ -3091,7 +3090,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;
@@ -3127,7 +3126,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;
@@ -3158,7 +3157,7 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
         && 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, 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 0dd6466..1549604 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1186,7 +1186,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
     tcg_func_start(&tcg_ctx);
 
     tcg_ctx.cpu = ENV_GET_CPU(env);
-    gen_intermediate_code(env, tb);
+    gen_intermediate_code(cpu, tb);
     tcg_ctx.cpu = NULL;
 
     trace_translate_block(tb, tb->pc, tb->tc_ptr);

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

* [Qemu-devel] [PATCH v2 2/6] queue: Add macro for incremental traversal
  2016-09-09 13:03 [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework Lluís Vilanova
  2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 1/6] Pass generic CPUState to gen_intermediate_code() Lluís Vilanova
@ 2016-09-09 13:03 ` Lluís Vilanova
  2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 3/6] target: [tcg] Add generic translation framework Lluís Vilanova
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Lluís Vilanova @ 2016-09-09 13:03 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 c2b6c81..4d57166 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] 15+ messages in thread

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

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 include/exec/gen-icount.h             |    2 
 include/exec/translate-all_template.h |   76 +++++++++++++
 include/qom/cpu.h                     |   21 +++
 translate-all_template.h              |  200 +++++++++++++++++++++++++++++++++
 4 files changed, 298 insertions(+), 1 deletion(-)
 create mode 100644 include/exec/translate-all_template.h
 create mode 100644 translate-all_template.h

diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 050de59..c91ac95 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -45,7 +45,7 @@ static inline void gen_tb_start(TranslationBlock *tb)
     tcg_temp_free_i32(count);
 }
 
-static void gen_tb_end(TranslationBlock *tb, int num_insns)
+static inline void gen_tb_end(TranslationBlock *tb, int num_insns)
 {
     gen_set_label(exitreq_label);
     tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_REQUESTED);
diff --git a/include/exec/translate-all_template.h b/include/exec/translate-all_template.h
new file mode 100644
index 0000000..a552db0
--- /dev/null
+++ b/include/exec/translate-all_template.h
@@ -0,0 +1,76 @@
+/*
+ * 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"
+
+
+/**
+ * BreakpointHitType:
+ * @BH_MISS: No hit
+ * @BH_HIT_INSN: Hit, but continue translating instruction
+ * @BH_HIT_TB: Hit, stop translating TB
+ *
+ * How to react to a breakpoint hit.
+ */
+typedef enum BreakpointHitType
+{
+    BH_MISS,
+    BH_HIT_INSN,
+    BH_HIT_TB,
+} BreakpointHitType;
+
+/**
+ * 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 (current during
+ *           disassembly).
+ * @num_insns: Number of translated instructions (including current).
+ *
+ * Architecture-agnostic disassembly context.
+ */
+typedef struct DisasContextBase
+{
+    TranslationBlock *tb;
+    bool singlestep_enabled;
+    target_ulong pc_first;
+    target_ulong pc_next;
+    DisasJumpType jmp_type;
+    unsigned int num_insns;
+} DisasContextBase;
+
+#endif  /* EXEC__TRANSLATE_ALL_TEMPLATE_H */
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index ce0c406..68b72b9 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -848,6 +848,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..f1e4d89
--- /dev/null
+++ b/translate-all_template.h
@@ -0,0 +1,200 @@
+/*
+ * 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"
+#include "qemu/error-report.h"
+
+
+static void gen_intermediate_code_target_init_disas_context(
+    DisasContext * restrict dc, CPUArchState * restrict env);
+
+static void gen_intermediate_code_target_init_globals(
+    DisasContext * restrict dc, CPUArchState * restrict env);
+
+static void gen_intermediate_code_target_tb_start(
+    DisasContext * restrict dc, CPUArchState * restrict env);
+
+static void gen_intermediate_code_target_insn_start(
+    DisasContext * restrict dc, CPUArchState * restrict env);
+
+static BreakpointHitType gen_intermediate_code_target_breakpoint_hit(
+    DisasContext * restrict dc, CPUArchState * restrict env,
+    const CPUBreakpoint * restrict bp);
+
+static target_ulong gen_intermediate_code_target_disas_insn(
+    DisasContext * restrict dc, CPUArchState * restrict env);
+
+static DisasJumpType gen_intermediate_code_target_stop_check(
+    DisasContext * restrict dc, CPUArchState * restrict env);
+
+static void gen_intermediate_code_target_stop(
+    DisasContext * restrict dc, CPUArchState * restrict env);
+
+static int gen_intermediate_code_target_get_disas_flags(
+    const DisasContext *dc);
+
+
+static inline void gen_intermediate_code_tcg_check(const DisasContext *dc)
+{
+    if (tcg_check_temp_count()) {
+        error_report("warning: TCG temporary leaks before "TARGET_FMT_lx,
+                     dc->base.pc_next);
+    }
+}
+
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
+{
+    CPUArchState *env = cpu->env_ptr;
+    DisasContext dc1, *dc = &dc1;
+    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;
+    dc->base.num_insns = 0;
+    gen_intermediate_code_target_init_disas_context(dc, env);
+
+    /* Initialize globals */
+    gen_intermediate_code_target_init_globals(dc, env);
+    tcg_clear_temp_count();
+
+    /* Instruction counting */
+    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;
+    }
+    if (dc->base.singlestep_enabled || singlestep) {
+        max_insns = 1;
+    }
+
+    /* Start translating */
+    gen_tb_start(dc->base.tb);
+    gen_intermediate_code_target_tb_start(dc, env);
+
+    while (true) {
+        CPUBreakpoint *bp;
+
+        dc->base.num_insns++;
+        gen_intermediate_code_target_insn_start(dc, env);
+
+        /* Early exit before breakpoint checks */
+        if (unlikely(dc->base.jmp_type != DJ_NEXT)) {
+            break;
+        }
+
+        /* Pass breakpoint hits to target for further processing */
+        bp = NULL;
+        do {
+            bp = cpu_breakpoint_get(cpu, dc->base.pc_next, bp);
+            if (unlikely(bp)) {
+                BreakpointHitType bh = gen_intermediate_code_target_breakpoint_hit(dc, env, bp);
+                if (bh == BH_HIT_INSN) {
+                    /* Hit, keep translating */
+                    /*
+                     * TODO: if we're never going to have more than one BP in a
+                     *       single address, we can simply use a bool here.
+                     */
+                    break;
+                } else if (bh == BH_HIT_TB) {
+                    goto done_generating;
+                }
+            }
+        } while (bp != NULL);
+
+        /* Accept I/O on last instruction */
+        if (dc->base.num_insns == max_insns &&
+            (dc->base.tb->cflags & CF_LAST_IO)) {
+            gen_io_start();
+        }
+
+        /* Disassemble one instruction */
+        dc->base.pc_next = gen_intermediate_code_target_disas_insn(dc, env);
+
+        /**************************************************/
+        /* Conditions to stop translation                 */
+        /**************************************************/
+
+        /* Disassembly already set a stop condition */
+        if (dc->base.jmp_type >= DJ_TARGET) {
+            break;
+        }
+
+        /* Target-specific conditions */
+        dc->base.jmp_type = gen_intermediate_code_target_stop_check(dc, env);
+        if (dc->base.jmp_type >= DJ_TARGET) {
+            break;
+        }
+
+        /* Too many instructions */
+        if (tcg_op_buf_full() || dc->base.num_insns >= max_insns) {
+            dc->base.jmp_type = DJ_TOO_MANY;
+            break;
+        }
+
+        /*
+         * Check if 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 is always allowed to
+         *       cross pages (never goes through this check).
+         */
+        if ((dc->base.pc_first & TARGET_PAGE_MASK)
+            != (dc->base.pc_next & TARGET_PAGE_MASK)) {
+            dc->base.jmp_type = DJ_TOO_MANY;
+            break;
+        }
+
+        gen_intermediate_code_tcg_check(dc);
+    }
+
+    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, dc->base.num_insns);
+
+    gen_intermediate_code_tcg_check(dc);
+
+#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 = dc->base.num_insns;
+}
+
+#endif  /* TRANSLATE_ALL_TEMPLATE_H */

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

* [Qemu-devel] [PATCH v2 4/6] target: [tcg] Redefine DISAS_* onto the generic translation framework (DJ_*)
  2016-09-09 13:03 [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework Lluís Vilanova
                   ` (2 preceding siblings ...)
  2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 3/6] target: [tcg] Add generic translation framework Lluís Vilanova
@ 2016-09-09 13:03 ` Lluís Vilanova
  2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 5/6] target: [tcg, i386] Port to generic translation framework Lluís Vilanova
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Lluís Vilanova @ 2016-09-09 13:03 UTC (permalink / raw)
  To: qemu-devel
  Cc: Richard Henderson, Peter Crosthwaite, Paolo Bonzini,
	Peter Maydell, Edgar E. Iglesias, Alexander Graf, Guan Xuetao,
	open list:ARM

Temporarily redefine DISAS_* values based on DJ_TARGET. They should
disappear as targets get ported to the generic framework.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 include/exec/exec-all.h      |   11 +++++++----
 target-arm/translate.h       |   15 ++++++++-------
 target-cris/translate.c      |    3 ++-
 target-m68k/translate.c      |    3 ++-
 target-s390x/translate.c     |    3 ++-
 target-unicore32/translate.c |    3 ++-
 6 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 17659e6..54dc4ad 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -36,10 +36,13 @@ typedef ram_addr_t tb_page_addr_t;
 #endif
 
 /* is_jmp field values */
-#define DISAS_NEXT    0 /* next instruction can be analyzed */
-#define DISAS_JUMP    1 /* only pc was modified dynamically */
-#define DISAS_UPDATE  2 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP 3 /* only pc was modified statically */
+/* TODO: delete after all targets are transitioned to generic translation */
+#include "exec/translate-all_template.h"
+#define DISAS_NEXT    DJ_NEXT           /* next instruction can be analyzed */
+#define DISAS_JUMP    (DJ_TARGET+0)     /* only pc was modified dynamically */
+#define DISAS_UPDATE  (DJ_TARGET+1)     /* cpu state was modified dynamically */
+#define DISAS_TB_JUMP (DJ_TARGET+2)     /* only pc was modified statically */
+#define DISAS_TARGET  (DJ_TARGET+3)     /* base for target-specific values */
 
 #include "qemu/log.h"
 
diff --git a/target-arm/translate.h b/target-arm/translate.h
index dbd7ac8..602763c 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -107,21 +107,22 @@ static inline int default_exception_el(DisasContext *s)
 }
 
 /* target-specific extra values for is_jmp */
+/* TODO: rename as DJ_* when transitioning this target to generic translation */
 /* These instructions trap after executing, so the A32/T32 decoder must
  * defer them until after the conditional execution state has been updated.
  * WFI also needs special handling when single-stepping.
  */
-#define DISAS_WFI 4
-#define DISAS_SWI 5
+#define DISAS_WFI DISAS_TARGET + 0
+#define DISAS_SWI DISAS_TARGET + 1
 /* For instructions which unconditionally cause an exception we can skip
  * emitting unreachable code at the end of the TB in the A64 decoder
  */
-#define DISAS_EXC 6
+#define DISAS_EXC DISAS_TARGET + 2
 /* WFE */
-#define DISAS_WFE 7
-#define DISAS_HVC 8
-#define DISAS_SMC 9
-#define DISAS_YIELD 10
+#define DISAS_WFE DISAS_TARGET + 3
+#define DISAS_HVC DISAS_TARGET + 4
+#define DISAS_SMC DISAS_TARGET + 5
+#define DISAS_YIELD DISAS_TARGET + 6
 
 #ifdef TARGET_AARCH64
 void a64_translate_init(void);
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 284543a..ab48679 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -50,7 +50,8 @@
 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
 #define BUG_ON(x) ({if (x) BUG();})
 
-#define DISAS_SWI 5
+/* TODO: rename as DJ_* when transitioning this target to generic translation */
+#define DISAS_SWI DISAS_TARGET + 0
 
 /* Used by the decoder.  */
 #define EXTRACT_FIELD(src, start, end) \
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index f7d131f..75ffcc3 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -141,7 +141,8 @@ typedef struct DisasContext {
     int done_mac;
 } DisasContext;
 
-#define DISAS_JUMP_NEXT 4
+/* TODO: rename as DJ_* when transitioning this target to generic translation */
+#define DISAS_JUMP_NEXT DISAS_TARGET + 0
 
 #if defined(CONFIG_USER_ONLY)
 #define IS_USER(s) 1
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 468531a..69ca717 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -74,7 +74,8 @@ typedef struct {
     } u;
 } DisasCompare;
 
-#define DISAS_EXCP 4
+/* TODO: rename as DJ_* when transitioning this target to generic translation */
+#define DISAS_EXCP DISAS_TARGET + 0
 
 #ifdef DEBUG_INLINE_BRANCHES
 static uint64_t inline_branch_hit[CC_OP_MAX];
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 7499748..1cd2dab 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -45,9 +45,10 @@ typedef struct DisasContext {
 #define IS_USER(s)      1
 #endif
 
+/* TODO: rename as DJ_* when transitioning this target to generic translation */
 /* These instructions trap after executing, so defer them until after the
    conditional executions state has been updated.  */
-#define DISAS_SYSCALL 5
+#define DISAS_SYSCALL DISAS_TARGET + 0
 
 static TCGv_env cpu_env;
 static TCGv_i32 cpu_R[32];

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

* [Qemu-devel] [PATCH v2 5/6] target: [tcg, i386] Port to generic translation framework
  2016-09-09 13:03 [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework Lluís Vilanova
                   ` (3 preceding siblings ...)
  2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 4/6] target: [tcg] Redefine DISAS_* onto the generic translation framework (DJ_*) Lluís Vilanova
@ 2016-09-09 13:03 ` Lluís Vilanova
  2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 6/6] target: [tcg, arm] " Lluís Vilanova
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Lluís Vilanova @ 2016-09-09 13:03 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/translate.c |  306 ++++++++++++++++++++++-------------------------
 1 file changed, 142 insertions(+), 164 deletions(-)

diff --git a/target-i386/translate.c b/target-i386/translate.c
index bfd9aed..a02398d 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -69,6 +69,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 */
@@ -94,7 +98,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;
@@ -102,8 +110,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 */
@@ -124,12 +130,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;
@@ -140,6 +144,8 @@ typedef struct DisasContext {
     int cpuid_xsave_features;
 } DisasContext;
 
+#include "translate-all_template.h"
+
 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);
@@ -1113,7 +1119,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);
@@ -1128,14 +1134,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);
@@ -1148,7 +1154,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();
     }
 }
@@ -2089,7 +2095,7 @@ static inline int insn_const_size(TCGMemOp ot)
 static inline bool use_goto_tb(DisasContext *s, target_ulong pc)
 {
 #ifndef CONFIG_USER_ONLY
-    return (pc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) ||
+    return (pc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) ||
            (pc & TARGET_PAGE_MASK) == (s->pc_start & TARGET_PAGE_MASK);
 #else
     return true;
@@ -2104,7 +2110,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
         /* jump to same page: we can use a direct jump */
         tcg_gen_goto_tb(tb_num);
         gen_jmp_im(eip);
-        tcg_gen_exit_tb((uintptr_t)s->tb + tb_num);
+        tcg_gen_exit_tb((uintptr_t)s->base.tb + tb_num);
     } else {
         /* jump to another page: currently not optimized */
         gen_jmp_im(eip);
@@ -2125,7 +2131,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();
@@ -2196,11 +2202,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;
     }
 }
 
@@ -2372,7 +2378,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
@@ -2408,7 +2414,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)
@@ -2416,7 +2422,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)
@@ -2469,17 +2475,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.  */
@@ -2496,7 +2502,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);
@@ -4333,10 +4339,10 @@ 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)
+static target_ulong gen_intermediate_code_target_disas_insn(
+    DisasContext * restrict s, CPUX86State * restrict env)
 {
     int b, prefixes;
     int shift;
@@ -4344,6 +4350,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
     int modrm, reg, rm, mod, op, opreg, val;
     target_ulong next_eip, tval;
     int rex_w, rex_r;
+    target_ulong pc_start = s->base.pc_next;
 
     s->pc_start = s->pc = pc_start;
     prefixes = 0;
@@ -5230,7 +5237,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;
@@ -5245,7 +5252,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);
         }
@@ -5296,7 +5303,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;
@@ -5504,7 +5511,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);
         }
@@ -6160,7 +6167,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);
             }
         }
@@ -6175,7 +6182,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);
             }
         }
@@ -6191,14 +6198,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);
         }
@@ -6212,14 +6219,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);
         }
@@ -6230,14 +6237,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);
         }
@@ -6250,14 +6257,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);
         }
@@ -6772,7 +6779,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 */
@@ -6941,11 +6948,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);
         }
@@ -7010,7 +7017,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:
@@ -7193,7 +7200,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 */
@@ -7393,11 +7400,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);
             }
@@ -8189,22 +8196,20 @@ 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;
-    uint32_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;
+static void gen_intermediate_code_target_init_disas_context(
+    DisasContext * restrict dc, CPUX86State * restrict env)
+{
+    uint64_t flags = dc->base.tb->flags;
 
     dc->pe = (flags >> HF_PE_SHIFT) & 1;
     dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
@@ -8215,17 +8220,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;
 #ifdef CONFIG_SOFTMMU
     dc->mem_index = cpu_mmu_index(env, false);
 #endif
+
     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];
@@ -8237,7 +8242,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));
     /* Do not optimize repz jumps at all in icount mode, because
        rep movsS instructions are execured with different paths
@@ -8249,13 +8254,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, CPUX86State * restrict env)
+{
     cpu_T0 = tcg_temp_new();
     cpu_T1 = tcg_temp_new();
     cpu_A0 = tcg_temp_new();
@@ -8268,114 +8277,83 @@ 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 void gen_intermediate_code_target_tb_start(
+    DisasContext * restrict dc, CPUX86State * restrict env)
+{
+}
 
-    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();
-        }
+static void gen_intermediate_code_target_insn_start(
+    DisasContext * restrict dc, CPUX86State * restrict env)
+{
+    tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
+}
 
-        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.
-         */
-        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;
-        }
+static BreakpointHitType gen_intermediate_code_target_breakpoint_hit(
+    DisasContext * restrict dc, 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 BH_HIT_TB;
+    } else {
+        return BH_MISS;
     }
-    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)
-        && qemu_log_in_addr_range(pc_start)) {
-        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");
+}
+
+static DisasJumpType gen_intermediate_code_target_stop_check(
+    DisasContext * restrict dc, CPUX86State * restrict env)
+{
+    if (dc->tf) {
+        /*
+         * If single step mode, we generate only one instruction and generate an
+         * exception.
+         */
+        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, 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] 15+ messages in thread

* [Qemu-devel] [PATCH v2 6/6] target: [tcg, arm] Port to generic translation framework
  2016-09-09 13:03 [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework Lluís Vilanova
                   ` (4 preceding siblings ...)
  2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 5/6] target: [tcg, i386] Port to generic translation framework Lluís Vilanova
@ 2016-09-09 13:03 ` Lluís Vilanova
  2016-09-12  3:56 ` [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic " no-reply
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Lluís Vilanova @ 2016-09-09 13:03 UTC (permalink / raw)
  To: qemu-devel
  Cc: Richard Henderson, Peter Crosthwaite, Paolo Bonzini,
	Peter Maydell, open list:ARM

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 target-arm/translate-a64.c |  342 ++++++++++-----------
 target-arm/translate.c     |  718 ++++++++++++++++++++++----------------------
 target-arm/translate.h     |   42 ++-
 3 files changed, 553 insertions(+), 549 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index f5e29d2..6ce4dff 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -225,17 +225,17 @@ static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
 
 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
 {
-    gen_a64_set_pc_im(s->pc - offset);
+    gen_a64_set_pc_im(s->base.pc_next - offset);
     gen_exception_internal(excp);
-    s->is_jmp = DISAS_EXC;
+    s->base.jmp_type = DJ_EXC;
 }
 
 static void gen_exception_insn(DisasContext *s, int offset, int excp,
                                uint32_t syndrome, uint32_t target_el)
 {
-    gen_a64_set_pc_im(s->pc - offset);
+    gen_a64_set_pc_im(s->base.pc_next - offset);
     gen_exception(excp, syndrome, target_el);
-    s->is_jmp = DISAS_EXC;
+    s->base.jmp_type = DJ_EXC;
 }
 
 static void gen_ss_advance(DisasContext *s)
@@ -263,7 +263,7 @@ static void gen_step_complete_exception(DisasContext *s)
     gen_ss_advance(s);
     gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
                   default_exception_el(s));
-    s->is_jmp = DISAS_EXC;
+    s->base.jmp_type = DJ_EXC;
 }
 
 static inline bool use_goto_tb(DisasContext *s, int n, uint64_t dest)
@@ -271,13 +271,13 @@ static inline bool use_goto_tb(DisasContext *s, int n, uint64_t dest)
     /* No direct tb linking with singlestep (either QEMU's or the ARM
      * debug architecture kind) or deterministic io
      */
-    if (s->singlestep_enabled || s->ss_active || (s->tb->cflags & CF_LAST_IO)) {
+    if (s->base.singlestep_enabled || s->ss_active || (s->base.tb->cflags & CF_LAST_IO)) {
         return false;
     }
 
 #ifndef CONFIG_USER_ONLY
     /* Only link tbs from inside the same guest page */
-    if ((s->tb->pc & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
+    if ((s->base.tb->pc & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
         return false;
     }
 #endif
@@ -289,21 +289,21 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
 {
     TranslationBlock *tb;
 
-    tb = s->tb;
+    tb = s->base.tb;
     if (use_goto_tb(s, n, dest)) {
         tcg_gen_goto_tb(n);
         gen_a64_set_pc_im(dest);
         tcg_gen_exit_tb((intptr_t)tb + n);
-        s->is_jmp = DISAS_TB_JUMP;
+        s->base.jmp_type = DJ_TB_JUMP;
     } else {
         gen_a64_set_pc_im(dest);
         if (s->ss_active) {
             gen_step_complete_exception(s);
-        } else if (s->singlestep_enabled) {
+        } else if (s->base.singlestep_enabled) {
             gen_exception_internal(EXCP_DEBUG);
         } else {
             tcg_gen_exit_tb(0);
-            s->is_jmp = DISAS_TB_JUMP;
+            s->base.jmp_type = DJ_TB_JUMP;
         }
     }
 }
@@ -334,11 +334,11 @@ static void unallocated_encoding(DisasContext *s)
         qemu_log_mask(LOG_UNIMP,                                         \
                       "%s:%d: unsupported instruction encoding 0x%08x "  \
                       "at pc=%016" PRIx64 "\n",                          \
-                      __FILE__, __LINE__, insn, s->pc - 4);              \
+                      __FILE__, __LINE__, insn, s->base.pc_next - 4);              \
         unallocated_encoding(s);                                         \
     } while (0);
 
-static void init_tmp_a64_array(DisasContext *s)
+void init_tmp_a64_array(DisasContext *s)
 {
 #ifdef CONFIG_DEBUG_TCG
     int i;
@@ -1152,11 +1152,11 @@ static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
  */
 static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
 {
-    uint64_t addr = s->pc + sextract32(insn, 0, 26) * 4 - 4;
+    uint64_t addr = s->base.pc_next + sextract32(insn, 0, 26) * 4 - 4;
 
     if (insn & (1U << 31)) {
         /* C5.6.26 BL Branch with link */
-        tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
+        tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
     }
 
     /* C5.6.20 B Branch / C5.6.26 BL Branch with link */
@@ -1179,7 +1179,7 @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
     sf = extract32(insn, 31, 1);
     op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
     rt = extract32(insn, 0, 5);
-    addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
+    addr = s->base.pc_next + sextract32(insn, 5, 19) * 4 - 4;
 
     tcg_cmp = read_cpu_reg(s, rt, sf);
     label_match = gen_new_label();
@@ -1187,7 +1187,7 @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
     tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
                         tcg_cmp, 0, label_match);
 
-    gen_goto_tb(s, 0, s->pc);
+    gen_goto_tb(s, 0, s->base.pc_next);
     gen_set_label(label_match);
     gen_goto_tb(s, 1, addr);
 }
@@ -1207,7 +1207,7 @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
 
     bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
     op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
-    addr = s->pc + sextract32(insn, 5, 14) * 4 - 4;
+    addr = s->base.pc_next + sextract32(insn, 5, 14) * 4 - 4;
     rt = extract32(insn, 0, 5);
 
     tcg_cmp = tcg_temp_new_i64();
@@ -1216,7 +1216,7 @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
     tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
                         tcg_cmp, 0, label_match);
     tcg_temp_free_i64(tcg_cmp);
-    gen_goto_tb(s, 0, s->pc);
+    gen_goto_tb(s, 0, s->base.pc_next);
     gen_set_label(label_match);
     gen_goto_tb(s, 1, addr);
 }
@@ -1236,14 +1236,14 @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
         unallocated_encoding(s);
         return;
     }
-    addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
+    addr = s->base.pc_next + sextract32(insn, 5, 19) * 4 - 4;
     cond = extract32(insn, 0, 4);
 
     if (cond < 0x0e) {
         /* genuinely conditional branches */
         TCGLabel *label_match = gen_new_label();
         arm_gen_test_cc(cond, label_match);
-        gen_goto_tb(s, 0, s->pc);
+        gen_goto_tb(s, 0, s->base.pc_next);
         gen_set_label(label_match);
         gen_goto_tb(s, 1, addr);
     } else {
@@ -1267,13 +1267,13 @@ static void handle_hint(DisasContext *s, uint32_t insn,
     case 0: /* NOP */
         return;
     case 3: /* WFI */
-        s->is_jmp = DISAS_WFI;
+        s->base.jmp_type = DJ_WFI;
         return;
     case 1: /* YIELD */
-        s->is_jmp = DISAS_YIELD;
+        s->base.jmp_type = DJ_YIELD;
         return;
     case 2: /* WFE */
-        s->is_jmp = DISAS_WFE;
+        s->base.jmp_type = DJ_WFE;
         return;
     case 4: /* SEV */
     case 5: /* SEVL */
@@ -1312,7 +1312,7 @@ static void handle_sync(DisasContext *s, uint32_t insn,
          * a self-modified code correctly and also to take
          * any pending interrupts immediately.
          */
-        s->is_jmp = DISAS_UPDATE;
+        s->base.jmp_type = DJ_UPDATE;
         return;
     default:
         unallocated_encoding(s);
@@ -1337,11 +1337,11 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
     {
         TCGv_i32 tcg_imm = tcg_const_i32(crm);
         TCGv_i32 tcg_op = tcg_const_i32(op);
-        gen_a64_set_pc_im(s->pc - 4);
+        gen_a64_set_pc_im(s->base.pc_next - 4);
         gen_helper_msr_i_pstate(cpu_env, tcg_op, tcg_imm);
         tcg_temp_free_i32(tcg_imm);
         tcg_temp_free_i32(tcg_op);
-        s->is_jmp = DISAS_UPDATE;
+        s->base.jmp_type = DJ_UPDATE;
         break;
     }
     default:
@@ -1437,7 +1437,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
         TCGv_i32 tcg_syn, tcg_isread;
         uint32_t syndrome;
 
-        gen_a64_set_pc_im(s->pc - 4);
+        gen_a64_set_pc_im(s->base.pc_next - 4);
         tmpptr = tcg_const_ptr(ri);
         syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
         tcg_syn = tcg_const_i32(syndrome);
@@ -1476,7 +1476,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
         break;
     }
 
-    if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
+    if ((s->base.tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
         gen_io_start();
     }
 
@@ -1507,16 +1507,16 @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
         }
     }
 
-    if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
+    if ((s->base.tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
         /* I/O operations must end the TB here (whether read or write) */
         gen_io_end();
-        s->is_jmp = DISAS_UPDATE;
+        s->base.jmp_type = DJ_UPDATE;
     } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
         /* We default to ending the TB on a coprocessor register write,
          * but allow this to be suppressed by the register definition
          * (usually only necessary to work around guest bugs).
          */
-        s->is_jmp = DISAS_UPDATE;
+        s->base.jmp_type = DJ_UPDATE;
     }
 }
 
@@ -1596,7 +1596,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
             /* The pre HVC helper handles cases when HVC gets trapped
              * as an undefined insn by runtime configuration.
              */
-            gen_a64_set_pc_im(s->pc - 4);
+            gen_a64_set_pc_im(s->base.pc_next - 4);
             gen_helper_pre_hvc(cpu_env);
             gen_ss_advance(s);
             gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16), 2);
@@ -1606,7 +1606,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
                 unallocated_encoding(s);
                 break;
             }
-            gen_a64_set_pc_im(s->pc - 4);
+            gen_a64_set_pc_im(s->base.pc_next - 4);
             tmp = tcg_const_i32(syn_aa64_smc(imm16));
             gen_helper_pre_smc(cpu_env, tmp);
             tcg_temp_free_i32(tmp);
@@ -1696,7 +1696,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
         break;
     case 1: /* BLR */
         tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
-        tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
+        tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
         break;
     case 4: /* ERET */
         if (s->current_el == 0) {
@@ -1704,7 +1704,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
             return;
         }
         gen_helper_exception_return(cpu_env);
-        s->is_jmp = DISAS_JUMP;
+        s->base.jmp_type = DJ_JUMP;
         return;
     case 5: /* DRPS */
         if (rn != 0x1f) {
@@ -1718,7 +1718,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
         return;
     }
 
-    s->is_jmp = DISAS_JUMP;
+    s->base.jmp_type = DJ_JUMP;
 }
 
 /* C3.2 Branches, exception generating and system instructions */
@@ -1995,7 +1995,7 @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
 
     tcg_rt = cpu_reg(s, rt);
 
-    tcg_addr = tcg_const_i64((s->pc - 4) + imm);
+    tcg_addr = tcg_const_i64((s->base.pc_next - 4) + imm);
     if (is_vector) {
         do_fp_ld(s, rt, tcg_addr, size);
     } else {
@@ -2813,7 +2813,7 @@ static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
     offset = sextract64(insn, 5, 19);
     offset = offset << 2 | extract32(insn, 29, 2);
     rd = extract32(insn, 0, 5);
-    base = s->pc - 4;
+    base = s->base.pc_next - 4;
 
     if (page) {
         /* ADRP (page based) */
@@ -11076,13 +11076,14 @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
 }
 
 /* C3.1 A64 instruction index by encoding */
-static void disas_a64_insn(CPUARMState *env, DisasContext *s)
+void disas_a64_insn(CPUARMState *env, DisasContext *s);
+void disas_a64_insn(CPUARMState *env, DisasContext *s)
 {
     uint32_t insn;
 
-    insn = arm_ldl_code(env, s->pc, s->sctlr_b);
+    insn = arm_ldl_code(env, s->base.pc_next, s->sctlr_b);
     s->insn = insn;
-    s->pc += 4;
+    s->base.pc_next += 4;
 
     s->fp_access_checked = false;
 
@@ -11119,23 +11120,16 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
     free_tmp_a64(s);
 }
 
-void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb)
-{
-    CPUState *cs = CPU(cpu);
-    CPUARMState *env = &cpu->env;
-    DisasContext dc1, *dc = &dc1;
-    target_ulong pc_start;
-    target_ulong next_page_start;
-    int num_insns;
-    int max_insns;
 
-    pc_start = tb->pc;
 
-    dc->tb = tb;
+/* Use separate top-level templates for each architecture */
+#define gen_intermediate_code gen_intermediate_code_aarch64
+#include "translate-all_template.h"
+#undef gen_intermediate_code
 
-    dc->is_jmp = DISAS_NEXT;
-    dc->pc = pc_start;
-    dc->singlestep_enabled = cs->singlestep_enabled;
+static void gen_intermediate_code_target_init_disas_context(
+    DisasContext * restrict dc, CPUArchState * restrict env)
+{
     dc->condjmp = 0;
 
     dc->aarch64 = 1;
@@ -11146,18 +11140,18 @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb)
                                !arm_el_is_aa64(env, 3);
     dc->thumb = 0;
     dc->sctlr_b = 0;
-    dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
+    dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
     dc->condexec_mask = 0;
     dc->condexec_cond = 0;
-    dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
+    dc->mmu_idx = ARM_TBFLAG_MMUIDX(dc->base.tb->flags);
     dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
 #if !defined(CONFIG_USER_ONLY)
     dc->user = (dc->current_el == 0);
 #endif
-    dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
+    dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
     dc->vec_len = 0;
     dc->vec_stride = 0;
-    dc->cp_regs = cpu->cp_regs;
+    dc->cp_regs = arm_env_get_cpu(env)->cp_regs;
     dc->features = env->features;
 
     /* Single step state. The code-generation logic here is:
@@ -11175,147 +11169,149 @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb)
      *   emit code to generate a software step exception
      *   end the TB
      */
-    dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
-    dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
+    dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
+    dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
     dc->is_ldex = false;
     dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el);
 
     init_tmp_a64_array(dc);
 
-    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
-    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;
-    }
-
-    gen_tb_start(tb);
-
-    tcg_clear_temp_count();
-
-    do {
-        dc->insn_start_idx = tcg_op_buf_count();
-        tcg_gen_insn_start(dc->pc, 0, 0);
-        num_insns++;
+    dc->next_page_start =
+        (dc->base.pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
+}
 
-        if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
-            CPUBreakpoint *bp;
-            QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
-                if (bp->pc == dc->pc) {
-                    if (bp->flags & BP_CPU) {
-                        gen_a64_set_pc_im(dc->pc);
-                        gen_helper_check_breakpoints(cpu_env);
-                        /* End the TB early; it likely won't be executed */
-                        dc->is_jmp = DISAS_UPDATE;
-                    } else {
-                        gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
-                        /* 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.  */
-                        dc->pc += 4;
-                        goto done_generating;
-                    }
-                    break;
-                }
-            }
-        }
+static void gen_intermediate_code_target_init_globals(
+    DisasContext * restrict dc, CPUArchState * restrict env)
+{
+}
 
-        if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
-            gen_io_start();
-        }
+static void gen_intermediate_code_target_tb_start(
+    DisasContext * restrict dc, CPUArchState * restrict env)
+{
+}
 
-        if (dc->ss_active && !dc->pstate_ss) {
-            /* Singlestep state is Active-pending.
-             * If we're in this state at the start of a TB then either
-             *  a) we just took an exception to an EL which is being debugged
-             *     and this is the first insn in the exception handler
-             *  b) debug exceptions were masked and we just unmasked them
-             *     without changing EL (eg by clearing PSTATE.D)
-             * In either case we're going to take a swstep exception in the
-             * "did not step an insn" case, and so the syndrome ISV and EX
-             * bits should be zero.
-             */
-            assert(num_insns == 1);
-            gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
-                          default_exception_el(dc));
-            dc->is_jmp = DISAS_EXC;
-            break;
-        }
+static void gen_intermediate_code_target_insn_start(
+    DisasContext * restrict dc, CPUArchState * restrict env)
+{
+    dc->insn_start_idx = tcg_op_buf_count();
+    tcg_gen_insn_start(dc->base.pc_next, 0, 0);
+}
 
+static BreakpointHitType gen_intermediate_code_target_breakpoint_hit(
+    DisasContext * restrict dc, CPUArchState * restrict env,
+    const CPUBreakpoint * restrict bp)
+{
+    if (bp->flags & BP_CPU) {
+        gen_a64_set_pc_im(dc->base.pc_next);
+        gen_helper_check_breakpoints(cpu_env);
+        /* End the TB early; it likely won't be executed */
+        dc->base.jmp_type = DJ_UPDATE;
+        return BH_HIT_INSN;
+    } else {
+        gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
+        /* 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.  */
+        dc->base.pc_next += 4;
+        return BH_HIT_TB;
+    }
+}
+
+static target_ulong gen_intermediate_code_target_disas_insn(
+    DisasContext * restrict dc, CPUArchState * restrict env)
+{
+    if (dc->ss_active && !dc->pstate_ss) {
+        /* Singlestep state is Active-pending.
+         * If we're in this state at the start of a TB then either
+         *  a) we just took an exception to an EL which is being debugged
+         *     and this is the first insn in the exception handler
+         *  b) debug exceptions were masked and we just unmasked them
+         *     without changing EL (eg by clearing PSTATE.D)
+         * In either case we're going to take a swstep exception in the
+         * "did not step an insn" case, and so the syndrome ISV and EX
+         * bits should be zero.
+         */
+        assert(dc->base.num_insns == 1);
+        gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
+                      default_exception_el(dc));
+        dc->base.jmp_type = DJ_EXC;
+    } else {
         disas_a64_insn(env, dc);
+    }
+    return dc->base.pc_next;
+}
 
-        if (tcg_check_temp_count()) {
-            fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
-                    dc->pc);
-        }
-
-        /* Translation stops when a conditional branch is encountered.
-         * Otherwise the subsequent code could get translated several times.
-         * 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 &&
-             !singlestep &&
-             !dc->ss_active &&
-             dc->pc < next_page_start &&
-             num_insns < max_insns);
-
-    if (tb->cflags & CF_LAST_IO) {
-        gen_io_end();
+static DisasJumpType gen_intermediate_code_target_stop_check(
+    DisasContext * restrict dc, CPUArchState * restrict env)
+{
+    /* Translation stops when a conditional branch is encountered.
+     * Otherwise the subsequent code could get translated several times.
+     * Also stop translation when a page boundary is reached.  This
+     * ensures prefetch aborts occur at the right place.
+     */
+    if (dc->ss_active) {
+        return DJ_SS;
+    } else {
+        return dc->base.jmp_type;
     }
+}
 
-    if (unlikely(cs->singlestep_enabled || dc->ss_active)
-        && dc->is_jmp != DISAS_EXC) {
+static void gen_intermediate_code_target_stop(
+    DisasContext * restrict dc, CPUArchState * restrict env)
+{
+    if (unlikely(dc->base.singlestep_enabled || dc->ss_active)
+        && dc->base.jmp_type != DJ_EXC) {
         /* Note that this means single stepping WFI doesn't halt the CPU.
          * For conditional branch insns this is harmless unreachable code as
          * gen_goto_tb() has already handled emitting the debug exception
          * (and thus a tb-jump is not possible when singlestepping).
          */
-        assert(dc->is_jmp != DISAS_TB_JUMP);
-        if (dc->is_jmp != DISAS_JUMP) {
-            gen_a64_set_pc_im(dc->pc);
+        assert(dc->base.jmp_type != DJ_TB_JUMP);
+        if (dc->base.jmp_type != DJ_JUMP) {
+            gen_a64_set_pc_im(dc->base.pc_next);
         }
-        if (cs->singlestep_enabled) {
+        if (dc->base.singlestep_enabled) {
             gen_exception_internal(EXCP_DEBUG);
         } else {
             gen_step_complete_exception(dc);
         }
     } else {
-        switch (dc->is_jmp) {
-        case DISAS_NEXT:
-            gen_goto_tb(dc, 1, dc->pc);
+        /* Cast because target-specific values are not in generic enum */
+        unsigned int jt = (unsigned int)dc->base.jmp_type;
+
+        switch (jt) {
+        case DJ_NEXT:
+        case DJ_TOO_MANY:               /* target set DJ_NEXT */
+            gen_goto_tb(dc, 1, dc->base.pc_next);
             break;
         default:
-        case DISAS_UPDATE:
-            gen_a64_set_pc_im(dc->pc);
+        case DJ_UPDATE:
+            gen_a64_set_pc_im(dc->base.pc_next);
             /* fall through */
-        case DISAS_JUMP:
+        case DJ_JUMP:
             /* indicate that the hash table must be used to find the next TB */
             tcg_gen_exit_tb(0);
             break;
-        case DISAS_TB_JUMP:
-        case DISAS_EXC:
-        case DISAS_SWI:
+        case DJ_TB_JUMP:
+        case DJ_EXC:
+        case DJ_SWI:
+            /* nothing to generate */
             break;
-        case DISAS_WFE:
-            gen_a64_set_pc_im(dc->pc);
+        case DJ_WFE:
+            gen_a64_set_pc_im(dc->base.pc_next);
             gen_helper_wfe(cpu_env);
             break;
-        case DISAS_YIELD:
-            gen_a64_set_pc_im(dc->pc);
+        case DJ_YIELD:
+            gen_a64_set_pc_im(dc->base.pc_next);
             gen_helper_yield(cpu_env);
             break;
-        case DISAS_WFI:
+        case DJ_WFI:
             /* This is a special case because we don't want to just halt the CPU
              * if trying to debug across a WFI.
              */
-            gen_a64_set_pc_im(dc->pc);
+            gen_a64_set_pc_im(dc->base.pc_next);
             gen_helper_wfi(cpu_env);
             /* The helper doesn't necessarily throw an exception, but we
              * must go back to the main loop to check for interrupts anyway.
@@ -11324,20 +11320,10 @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb)
             break;
         }
     }
+}
 
-done_generating:
-    gen_tb_end(tb, num_insns);
-
-#ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
-        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,
-                         4 | (bswap_code(dc->sctlr_b) ? 2 : 0));
-        qemu_log("\n");
-    }
-#endif
-    tb->size = dc->pc - pc_start;
-    tb->icount = num_insns;
+static int gen_intermediate_code_target_get_disas_flags(
+    const DisasContext *dc)
+{
+    return 4 | (bswap_code(dc->sctlr_b) ? 2 : 0);
 }
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 721a3d4..3d9dd66 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -158,9 +158,9 @@ static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
         uint32_t addr;
         /* normally, since we updated PC, we need only to add one insn */
         if (s->thumb)
-            addr = (long)s->pc + 2;
+            addr = (long)s->base.pc_next + 2;
         else
-            addr = (long)s->pc + 4;
+            addr = (long)s->base.pc_next + 4;
         tcg_gen_movi_i32(var, addr);
     } else {
         tcg_gen_mov_i32(var, cpu_R[reg]);
@@ -181,7 +181,7 @@ static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
 {
     if (reg == 15) {
         tcg_gen_andi_i32(var, var, ~1);
-        s->is_jmp = DISAS_JUMP;
+        s->base.jmp_type = DJ_JUMP;
     }
     tcg_gen_mov_i32(cpu_R[reg], var);
     tcg_temp_free_i32(var);
@@ -254,7 +254,7 @@ static void gen_step_complete_exception(DisasContext *s)
     gen_ss_advance(s);
     gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
                   default_exception_el(s));
-    s->is_jmp = DISAS_EXC;
+    s->base.jmp_type = DJ_EXC;
 }
 
 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
@@ -869,7 +869,7 @@ static inline void gen_bx_im(DisasContext *s, uint32_t addr)
 {
     TCGv_i32 tmp;
 
-    s->is_jmp = DISAS_JUMP;
+    s->base.jmp_type = DJ_JUMP;
     if (s->thumb != (addr & 1)) {
         tmp = tcg_temp_new_i32();
         tcg_gen_movi_i32(tmp, addr & 1);
@@ -882,7 +882,7 @@ static inline void gen_bx_im(DisasContext *s, uint32_t addr)
 /* Set PC and Thumb state from var.  var is marked as dead.  */
 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
 {
-    s->is_jmp = DISAS_JUMP;
+    s->base.jmp_type = DJ_JUMP;
     tcg_gen_andi_i32(cpu_R[15], var, ~1);
     tcg_gen_andi_i32(var, var, 1);
     store_cpu_field(var, thumb);
@@ -1077,7 +1077,7 @@ static inline void gen_hvc(DisasContext *s, int imm16)
      * as an undefined insn by runtime configuration (ie before
      * the insn really executes).
      */
-    gen_set_pc_im(s, s->pc - 4);
+    gen_set_pc_im(s, s->base.pc_next - 4);
     gen_helper_pre_hvc(cpu_env);
     /* Otherwise we will treat this as a real exception which
      * happens after execution of the insn. (The distinction matters
@@ -1085,8 +1085,8 @@ static inline void gen_hvc(DisasContext *s, int imm16)
      * for single stepping.)
      */
     s->svc_imm = imm16;
-    gen_set_pc_im(s, s->pc);
-    s->is_jmp = DISAS_HVC;
+    gen_set_pc_im(s, s->base.pc_next);
+    s->base.jmp_type = DJ_HVC;
 }
 
 static inline void gen_smc(DisasContext *s)
@@ -1096,12 +1096,12 @@ static inline void gen_smc(DisasContext *s)
      */
     TCGv_i32 tmp;
 
-    gen_set_pc_im(s, s->pc - 4);
+    gen_set_pc_im(s, s->base.pc_next - 4);
     tmp = tcg_const_i32(syn_aa32_smc());
     gen_helper_pre_smc(cpu_env, tmp);
     tcg_temp_free_i32(tmp);
-    gen_set_pc_im(s, s->pc);
-    s->is_jmp = DISAS_SMC;
+    gen_set_pc_im(s, s->base.pc_next);
+    s->base.jmp_type = DJ_SMC;
 }
 
 static inline void
@@ -1118,25 +1118,25 @@ gen_set_condexec (DisasContext *s)
 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
 {
     gen_set_condexec(s);
-    gen_set_pc_im(s, s->pc - offset);
+    gen_set_pc_im(s, s->base.pc_next - offset);
     gen_exception_internal(excp);
-    s->is_jmp = DISAS_JUMP;
+    s->base.jmp_type = DJ_JUMP;
 }
 
 static void gen_exception_insn(DisasContext *s, int offset, int excp,
                                int syn, uint32_t target_el)
 {
     gen_set_condexec(s);
-    gen_set_pc_im(s, s->pc - offset);
+    gen_set_pc_im(s, s->base.pc_next - offset);
     gen_exception(excp, syn, target_el);
-    s->is_jmp = DISAS_JUMP;
+    s->base.jmp_type = DJ_JUMP;
 }
 
 /* Force a TB lookup after an instruction that changes the CPU state.  */
 static inline void gen_lookup_tb(DisasContext *s)
 {
-    tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
-    s->is_jmp = DISAS_JUMP;
+    tcg_gen_movi_i32(cpu_R[15], s->base.pc_next & ~1);
+    s->base.jmp_type = DJ_JUMP;
 }
 
 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
@@ -3964,7 +3964,7 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
                 if (s->thumb && rn == 15) {
                     /* This is actually UNPREDICTABLE */
                     addr = tcg_temp_new_i32();
-                    tcg_gen_movi_i32(addr, s->pc & ~2);
+                    tcg_gen_movi_i32(addr, s->base.pc_next & ~2);
                 } else {
                     addr = load_reg(s, rn);
                 }
@@ -4003,7 +4003,7 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
                 if (s->thumb && rn == 15) {
                     /* This is actually UNPREDICTABLE */
                     addr = tcg_temp_new_i32();
-                    tcg_gen_movi_i32(addr, s->pc & ~2);
+                    tcg_gen_movi_i32(addr, s->base.pc_next & ~2);
                 } else {
                     addr = load_reg(s, rn);
                 }
@@ -4054,8 +4054,8 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
 {
 #ifndef CONFIG_USER_ONLY
-    return (s->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
-           ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
+    return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
+           ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
 #else
     return true;
 #endif
@@ -4066,7 +4066,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
     if (use_goto_tb(s, dest)) {
         tcg_gen_goto_tb(n);
         gen_set_pc_im(s, dest);
-        tcg_gen_exit_tb((uintptr_t)s->tb + n);
+        tcg_gen_exit_tb((uintptr_t)s->base.tb + n);
     } else {
         gen_set_pc_im(s, dest);
         tcg_gen_exit_tb(0);
@@ -4075,14 +4075,14 @@ static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
 
 static inline void gen_jmp (DisasContext *s, uint32_t dest)
 {
-    if (unlikely(s->singlestep_enabled || s->ss_active)) {
+    if (unlikely(s->base.singlestep_enabled || s->ss_active)) {
         /* An indirect jump so that we still trigger the debug exception.  */
         if (s->thumb)
             dest |= 1;
         gen_bx_im(s, dest);
     } else {
         gen_goto_tb(s, 0, dest);
-        s->is_jmp = DISAS_TB_JUMP;
+        s->base.jmp_type = DJ_TB_JUMP;
     }
 }
 
@@ -4325,7 +4325,7 @@ static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
 
     /* Sync state because msr_banked() can raise exceptions */
     gen_set_condexec(s);
-    gen_set_pc_im(s, s->pc - 4);
+    gen_set_pc_im(s, s->base.pc_next - 4);
     tcg_reg = load_reg(s, rn);
     tcg_tgtmode = tcg_const_i32(tgtmode);
     tcg_regno = tcg_const_i32(regno);
@@ -4333,7 +4333,7 @@ static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
     tcg_temp_free_i32(tcg_tgtmode);
     tcg_temp_free_i32(tcg_regno);
     tcg_temp_free_i32(tcg_reg);
-    s->is_jmp = DISAS_UPDATE;
+    s->base.jmp_type = DJ_UPDATE;
 }
 
 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
@@ -4347,7 +4347,7 @@ static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
 
     /* Sync state because mrs_banked() can raise exceptions */
     gen_set_condexec(s);
-    gen_set_pc_im(s, s->pc - 4);
+    gen_set_pc_im(s, s->base.pc_next - 4);
     tcg_reg = tcg_temp_new_i32();
     tcg_tgtmode = tcg_const_i32(tgtmode);
     tcg_regno = tcg_const_i32(regno);
@@ -4355,7 +4355,7 @@ static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
     tcg_temp_free_i32(tcg_tgtmode);
     tcg_temp_free_i32(tcg_regno);
     store_reg(s, rn, tcg_reg);
-    s->is_jmp = DISAS_UPDATE;
+    s->base.jmp_type = DJ_UPDATE;
 }
 
 /* Generate an old-style exception return. Marks pc as dead. */
@@ -4366,7 +4366,7 @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
     tmp = load_cpu_field(spsr);
     gen_helper_cpsr_write_eret(cpu_env, tmp);
     tcg_temp_free_i32(tmp);
-    s->is_jmp = DISAS_JUMP;
+    s->base.jmp_type = DJ_JUMP;
 }
 
 /* Generate a v6 exception return.  Marks both values as dead.  */
@@ -4375,23 +4375,23 @@ static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
     gen_helper_cpsr_write_eret(cpu_env, cpsr);
     tcg_temp_free_i32(cpsr);
     store_reg(s, 15, pc);
-    s->is_jmp = DISAS_JUMP;
+    s->base.jmp_type = DJ_JUMP;
 }
 
 static void gen_nop_hint(DisasContext *s, int val)
 {
     switch (val) {
     case 1: /* yield */
-        gen_set_pc_im(s, s->pc);
-        s->is_jmp = DISAS_YIELD;
+        gen_set_pc_im(s, s->base.pc_next);
+        s->base.jmp_type = DJ_YIELD;
         break;
     case 3: /* wfi */
-        gen_set_pc_im(s, s->pc);
-        s->is_jmp = DISAS_WFI;
+        gen_set_pc_im(s, s->base.pc_next);
+        s->base.jmp_type = DJ_WFI;
         break;
     case 2: /* wfe */
-        gen_set_pc_im(s, s->pc);
-        s->is_jmp = DISAS_WFE;
+        gen_set_pc_im(s, s->base.pc_next);
+        s->base.jmp_type = DJ_WFE;
         break;
     case 4: /* sev */
     case 5: /* sevl */
@@ -7509,7 +7509,7 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
             }
 
             gen_set_condexec(s);
-            gen_set_pc_im(s, s->pc - 4);
+            gen_set_pc_im(s, s->base.pc_next - 4);
             tmpptr = tcg_const_ptr(ri);
             tcg_syn = tcg_const_i32(syndrome);
             tcg_isread = tcg_const_i32(isread);
@@ -7528,14 +7528,14 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
             if (isread) {
                 return 1;
             }
-            gen_set_pc_im(s, s->pc);
-            s->is_jmp = DISAS_WFI;
+            gen_set_pc_im(s, s->base.pc_next);
+            s->base.jmp_type = DJ_WFI;
             return 0;
         default:
             break;
         }
 
-        if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
+        if ((s->base.tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
             gen_io_start();
         }
 
@@ -7626,7 +7626,7 @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
             }
         }
 
-        if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
+        if ((s->base.tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
             /* I/O operations must end the TB here (whether read or write) */
             gen_io_end();
             gen_lookup_tb(s);
@@ -7937,7 +7937,7 @@ static void gen_srs(DisasContext *s,
     tmp = tcg_const_i32(mode);
     /* get_r13_banked() will raise an exception if called from System mode */
     gen_set_condexec(s);
-    gen_set_pc_im(s, s->pc - 4);
+    gen_set_pc_im(s, s->base.pc_next - 4);
     gen_helper_get_r13_banked(addr, cpu_env, tmp);
     tcg_temp_free_i32(tmp);
     switch (amode) {
@@ -7987,7 +7987,7 @@ static void gen_srs(DisasContext *s,
         tcg_temp_free_i32(tmp);
     }
     tcg_temp_free_i32(addr);
-    s->is_jmp = DISAS_UPDATE;
+    s->base.jmp_type = DJ_UPDATE;
 }
 
 static void disas_arm_insn(DisasContext *s, unsigned int insn)
@@ -8071,7 +8071,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
             /* setend */
             if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
                 gen_helper_setend(cpu_env);
-                s->is_jmp = DISAS_UPDATE;
+                s->base.jmp_type = DJ_UPDATE;
             }
             return;
         } else if ((insn & 0x0fffff00) == 0x057ff000) {
@@ -8145,7 +8145,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
             /* branch link and change to thumb (blx <offset>) */
             int32_t offset;
 
-            val = (uint32_t)s->pc;
+            val = (uint32_t)s->base.pc_next;
             tmp = tcg_temp_new_i32();
             tcg_gen_movi_i32(tmp, val);
             store_reg(s, 14, tmp);
@@ -8323,7 +8323,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
             /* branch link/exchange thumb (blx) */
             tmp = load_reg(s, rm);
             tmp2 = tcg_temp_new_i32();
-            tcg_gen_movi_i32(tmp2, s->pc);
+            tcg_gen_movi_i32(tmp2, s->base.pc_next);
             store_reg(s, 14, tmp2);
             gen_bx(s, tmp);
             break;
@@ -9368,7 +9368,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
                             /* store */
                             if (i == 15) {
                                 /* special case: r15 = PC + 8 */
-                                val = (long)s->pc + 4;
+                                val = (long)s->base.pc_next + 4;
                                 tmp = tcg_temp_new_i32();
                                 tcg_gen_movi_i32(tmp, val);
                             } else if (user) {
@@ -9419,7 +9419,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
                     tmp = load_cpu_field(spsr);
                     gen_helper_cpsr_write_eret(cpu_env, tmp);
                     tcg_temp_free_i32(tmp);
-                    s->is_jmp = DISAS_JUMP;
+                    s->base.jmp_type = DJ_JUMP;
                 }
             }
             break;
@@ -9429,7 +9429,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
                 int32_t offset;
 
                 /* branch (and link) */
-                val = (int32_t)s->pc;
+                val = (int32_t)s->base.pc_next;
                 if (insn & (1 << 24)) {
                     tmp = tcg_temp_new_i32();
                     tcg_gen_movi_i32(tmp, val);
@@ -9455,9 +9455,9 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
             break;
         case 0xf:
             /* swi */
-            gen_set_pc_im(s, s->pc);
+            gen_set_pc_im(s, s->base.pc_next);
             s->svc_imm = extract32(insn, 0, 24);
-            s->is_jmp = DISAS_SWI;
+            s->base.jmp_type = DJ_SWI;
             break;
         default:
         illegal_op:
@@ -9581,7 +9581,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
             tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
 
             tmp2 = tcg_temp_new_i32();
-            tcg_gen_movi_i32(tmp2, s->pc | 1);
+            tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
             store_reg(s, 14, tmp2);
             gen_bx(s, tmp);
             return 0;
@@ -9593,24 +9593,24 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
             tcg_gen_addi_i32(tmp, tmp, offset);
 
             tmp2 = tcg_temp_new_i32();
-            tcg_gen_movi_i32(tmp2, s->pc | 1);
+            tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
             store_reg(s, 14, tmp2);
             gen_bx(s, tmp);
             return 0;
         }
-        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
+        if ((s->base.pc_next & ~TARGET_PAGE_MASK) == 0) {
             /* Instruction spans a page boundary.  Implement it as two
                16-bit instructions in case the second half causes an
                prefetch abort.  */
             offset = ((int32_t)insn << 21) >> 9;
-            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
+            tcg_gen_movi_i32(cpu_R[14], s->base.pc_next + 2 + offset);
             return 0;
         }
         /* Fall through to 32-bit decode.  */
     }
 
-    insn = arm_lduw_code(env, s->pc, s->sctlr_b);
-    s->pc += 2;
+    insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
+    s->base.pc_next += 2;
     insn |= (uint32_t)insn_hw1 << 16;
 
     if ((insn & 0xf800e800) != 0xf000e800) {
@@ -9632,7 +9632,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                 /* Load/store doubleword.  */
                 if (rn == 15) {
                     addr = tcg_temp_new_i32();
-                    tcg_gen_movi_i32(addr, s->pc & ~3);
+                    tcg_gen_movi_i32(addr, s->base.pc_next & ~3);
                 } else {
                     addr = load_reg(s, rn);
                 }
@@ -9686,7 +9686,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                 /* Table Branch.  */
                 if (rn == 15) {
                     addr = tcg_temp_new_i32();
-                    tcg_gen_movi_i32(addr, s->pc);
+                    tcg_gen_movi_i32(addr, s->base.pc_next);
                 } else {
                     addr = load_reg(s, rn);
                 }
@@ -9705,7 +9705,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                 }
                 tcg_temp_free_i32(addr);
                 tcg_gen_shli_i32(tmp, tmp, 1);
-                tcg_gen_addi_i32(tmp, tmp, s->pc);
+                tcg_gen_addi_i32(tmp, tmp, s->base.pc_next);
                 store_reg(s, 15, tmp);
             } else {
                 int op2 = (insn >> 6) & 0x3;
@@ -10324,10 +10324,10 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
 
                 if (insn & (1 << 14)) {
                     /* Branch and link.  */
-                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
+                    tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
                 }
 
-                offset += s->pc;
+                offset += s->base.pc_next;
                 if (insn & (1 << 12)) {
                     /* b/bl */
                     gen_jmp(s, offset);
@@ -10523,7 +10523,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                 offset |= (insn & (1 << 11)) << 8;
 
                 /* jump to the offset */
-                gen_jmp(s, s->pc + offset);
+                gen_jmp(s, s->base.pc_next + offset);
             }
         } else {
             /* Data processing immediate.  */
@@ -10624,7 +10624,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
                     } else {
                         /* Add/sub 12-bit immediate.  */
                         if (rn == 15) {
-                            offset = s->pc & ~(uint32_t)3;
+                            offset = s->base.pc_next & ~(uint32_t)3;
                             if (insn & (1 << 23))
                                 offset -= imm;
                             else
@@ -10744,8 +10744,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
         if (rn == 15) {
             addr = tcg_temp_new_i32();
             /* PC relative.  */
-            /* s->pc has already been incremented by 4.  */
-            imm = s->pc & 0xfffffffc;
+            /* s->base.pc_next has already been incremented by 4.  */
+            imm = s->base.pc_next & 0xfffffffc;
             if (insn & (1 << 23))
                 imm += insn & 0xfff;
             else
@@ -10883,8 +10883,8 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
         }
     }
 
-    insn = arm_lduw_code(env, s->pc, s->sctlr_b);
-    s->pc += 2;
+    insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
+    s->base.pc_next += 2;
 
     switch (insn >> 12) {
     case 0: case 1:
@@ -10971,7 +10971,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
         if (insn & (1 << 11)) {
             rd = (insn >> 8) & 7;
             /* load pc-relative.  Bit 1 of PC is ignored.  */
-            val = s->pc + 2 + ((insn & 0xff) * 4);
+            val = s->base.pc_next + 2 + ((insn & 0xff) * 4);
             val &= ~(uint32_t)2;
             addr = tcg_temp_new_i32();
             tcg_gen_movi_i32(addr, val);
@@ -11009,7 +11009,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
                 tmp = load_reg(s, rm);
                 if (insn & (1 << 7)) {
                     ARCH(5);
-                    val = (uint32_t)s->pc | 1;
+                    val = (uint32_t)s->base.pc_next | 1;
                     tmp2 = tcg_temp_new_i32();
                     tcg_gen_movi_i32(tmp2, val);
                     store_reg(s, 14, tmp2);
@@ -11307,7 +11307,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
         } else {
             /* PC. bit 1 is ignored.  */
             tmp = tcg_temp_new_i32();
-            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
+            tcg_gen_movi_i32(tmp, (s->base.pc_next + 2) & ~(uint32_t)2);
         }
         val = (insn & 0xff) * 4;
         tcg_gen_addi_i32(tmp, tmp, val);
@@ -11410,7 +11410,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
                 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
             tcg_temp_free_i32(tmp);
             offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
-            val = (uint32_t)s->pc + 2;
+            val = (uint32_t)s->base.pc_next + 2;
             val += offset;
             gen_jmp(s, val);
             break;
@@ -11456,7 +11456,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
                 ARCH(6);
                 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
                     gen_helper_setend(cpu_env);
-                    s->is_jmp = DISAS_UPDATE;
+                    s->base.jmp_type = DJ_UPDATE;
                 }
                 break;
             case 3:
@@ -11548,9 +11548,9 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
 
         if (cond == 0xf) {
             /* swi */
-            gen_set_pc_im(s, s->pc);
+            gen_set_pc_im(s, s->base.pc_next);
             s->svc_imm = extract32(insn, 0, 8);
-            s->is_jmp = DISAS_SWI;
+            s->base.jmp_type = DJ_SWI;
             break;
         }
         /* generate a conditional jump to next instruction */
@@ -11559,7 +11559,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
         s->condjmp = 1;
 
         /* jump to the offset */
-        val = (uint32_t)s->pc + 2;
+        val = (uint32_t)s->base.pc_next + 2;
         offset = ((int32_t)insn << 24) >> 24;
         val += offset << 1;
         gen_jmp(s, val);
@@ -11572,7 +11572,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
             break;
         }
         /* unconditional branch */
-        val = (uint32_t)s->pc;
+        val = (uint32_t)s->base.pc_next;
         offset = ((int32_t)insn << 21) >> 21;
         val += (offset << 1) + 2;
         gen_jmp(s, val);
@@ -11594,20 +11594,20 @@ undef:
                        default_exception_el(s));
 }
 
-static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
+static bool insn_crosses_page(CPUARMState *env, const DisasContext *s)
 {
     /* Return true if the insn at dc->pc might cross a page boundary.
      * (False positives are OK, false negatives are not.)
      */
     uint16_t insn;
 
-    if ((s->pc & 3) == 0) {
+    if ((s->base.pc_next & 3) == 0) {
         /* At a 4-aligned address we can't be crossing a page */
         return false;
     }
 
     /* This must be a Thumb insn */
-    insn = arm_lduw_code(env, s->pc, s->sctlr_b);
+    insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
 
     if ((insn >> 11) >= 0x1d) {
         /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
@@ -11623,35 +11623,107 @@ static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
     return false;
 }
 
-/* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
-{
-    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;
-    int num_insns;
-    int max_insns;
-    bool end_of_page;
+static const char *cpu_mode_names[16] = {
+  "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
+  "???", "???", "hyp", "und", "???", "???", "???", "sys"
+};
 
-    /* generate intermediate code */
+void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+    int i;
+    uint32_t psr;
+    const char *ns_status;
 
-    /* The A64 decoder has its own top level loop, because it doesn't need
-     * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
-     */
-    if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
-        gen_intermediate_code_a64(arm_cpu, tb);
+    if (is_a64(env)) {
+        aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
         return;
     }
 
-    pc_start = tb->pc;
+    for(i=0;i<16;i++) {
+        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
+        if ((i % 4) == 3)
+            cpu_fprintf(f, "\n");
+        else
+            cpu_fprintf(f, " ");
+    }
+    psr = cpsr_read(env);
+
+    if (arm_feature(env, ARM_FEATURE_EL3) &&
+        (psr & CPSR_M) != ARM_CPU_MODE_MON) {
+        ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
+    } else {
+        ns_status = "";
+    }
 
-    dc->tb = tb;
+    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
+                psr,
+                psr & (1 << 31) ? 'N' : '-',
+                psr & (1 << 30) ? 'Z' : '-',
+                psr & (1 << 29) ? 'C' : '-',
+                psr & (1 << 28) ? 'V' : '-',
+                psr & CPSR_T ? 'T' : 'A',
+                ns_status,
+                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
 
-    dc->is_jmp = DISAS_NEXT;
-    dc->pc = pc_start;
-    dc->singlestep_enabled = cpu->singlestep_enabled;
+    if (flags & CPU_DUMP_FPU) {
+        int numvfpregs = 0;
+        if (arm_feature(env, ARM_FEATURE_VFP)) {
+            numvfpregs += 16;
+        }
+        if (arm_feature(env, ARM_FEATURE_VFP3)) {
+            numvfpregs += 16;
+        }
+        for (i = 0; i < numvfpregs; i++) {
+            uint64_t v = float64_val(env->vfp.regs[i]);
+            cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
+                        i * 2, (uint32_t)v,
+                        i * 2 + 1, (uint32_t)(v >> 32),
+                        i, v);
+        }
+        cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
+    }
+}
+
+void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
+                          target_ulong *data)
+{
+    if (is_a64(env)) {
+        env->pc = data[0];
+        env->condexec_bits = 0;
+    } else {
+        env->regs[15] = data[0];
+        env->condexec_bits = data[1];
+    }
+}
+
+
+
+/* Use separate top-level templates for each architecture */
+#define gen_intermediate_code gen_intermediate_code_arm
+#include "translate-all_template.h"
+#undef gen_intermediate_code
+
+#if !defined(TARGET_AARCH64)
+void gen_intermediate_code_aarch64(CPUState *cpu, struct TranslationBlock *tb)
+{
+}
+#endif
+
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
+{
+    if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
+        gen_intermediate_code_aarch64(cpu, tb);
+    } else {
+        gen_intermediate_code_arm(cpu, tb);
+    }
+}
+
+static void gen_intermediate_code_target_init_disas_context(
+    DisasContext * restrict dc, CPUARMState * restrict env)
+{
     dc->condjmp = 0;
 
     dc->aarch64 = 0;
@@ -11659,24 +11731,24 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
      * there is no secure EL1, so we route exceptions to EL3.
      */
     dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
-                               !arm_el_is_aa64(env, 3);
-    dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
-    dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
-    dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
-    dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
-    dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
-    dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
+        !arm_el_is_aa64(env, 3);
+    dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
+    dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
+    dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
+    dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
+    dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
+    dc->mmu_idx = ARM_TBFLAG_MMUIDX(dc->base.tb->flags);
     dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
 #if !defined(CONFIG_USER_ONLY)
     dc->user = (dc->current_el == 0);
 #endif
-    dc->ns = ARM_TBFLAG_NS(tb->flags);
-    dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
-    dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
-    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 = arm_cpu->cp_regs;
+    dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
+    dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
+    dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
+    dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
+    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
+    dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
+    dc->cp_regs = arm_env_get_cpu(env)->cp_regs;
     dc->features = env->features;
 
     /* Single step state. The code-generation logic here is:
@@ -11694,11 +11766,18 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
      *   emit code to generate a software step exception
      *   end the TB
      */
-    dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
-    dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
+    dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
+    dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
     dc->is_ldex = false;
     dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
 
+    dc->next_page_start =
+        (dc->base.pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
+}
+
+static void gen_intermediate_code_target_init_globals(
+    DisasContext * restrict dc, CPUARMState * restrict env)
+{
     cpu_F0s = tcg_temp_new_i32();
     cpu_F1s = tcg_temp_new_i32();
     cpu_F0d = tcg_temp_new_i64();
@@ -11707,20 +11786,11 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
     cpu_V1 = cpu_F1d;
     /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
     cpu_M0 = tcg_temp_new_i64();
-    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
-    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;
-    }
-
-    gen_tb_start(tb);
-
-    tcg_clear_temp_count();
+}
 
+static void gen_intermediate_code_target_tb_start(
+    DisasContext * restrict dc, CPUARMState * restrict env)
+{
     /* A note on handling of the condexec (IT) bits:
      *
      * We want to avoid the overhead of having to write the updated condexec
@@ -11751,118 +11821,129 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
      * middle of a TB.
      */
 
-    /* Reset the conditional execution bits immediately. This avoids
-       complications trying to do it at the end of the block.  */
-    if (dc->condexec_mask || dc->condexec_cond)
-      {
+    /*
+     * Reset the conditional execution bits immediately. This avoids
+     * complications trying to do it at the end of the block.
+     */
+    if (dc->condexec_mask || dc->condexec_cond) {
         TCGv_i32 tmp = tcg_temp_new_i32();
         tcg_gen_movi_i32(tmp, 0);
         store_cpu_field(tmp, condexec_bits);
-      }
-    do {
-        tcg_gen_insn_start(dc->pc,
-                           (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
-                           0);
-        num_insns++;
+    }
+}
+
+static void gen_intermediate_code_target_insn_start(
+    DisasContext * restrict dc, CPUARMState * restrict env)
+{
+    tcg_gen_insn_start(dc->base.pc_next,
+                       (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
+                       0);
+
 
 #ifdef CONFIG_USER_ONLY
-        /* Intercept jump to the magic kernel page.  */
-        if (dc->pc >= 0xffff0000) {
-            /* We always get here via a jump, so know we are not in a
-               conditional execution block.  */
-            gen_exception_internal(EXCP_KERNEL_TRAP);
-            dc->is_jmp = DISAS_EXC;
-            break;
-        }
+    /* Intercept jump to the magic kernel page.  */
+    if (dc->base.pc_next >= 0xffff0000) {
+        /* We always get here via a jump, so know we are not in a
+           conditional execution block.  */
+        gen_exception_internal(EXCP_KERNEL_TRAP);
+        dc->base.jmp_type = DJ_EXC;
+    }
 #else
-        if (dc->pc >= 0xfffffff0 && arm_dc_feature(dc, ARM_FEATURE_M)) {
-            /* We always get here via a jump, so know we are not in a
-               conditional execution block.  */
-            gen_exception_internal(EXCP_EXCEPTION_EXIT);
-            dc->is_jmp = DISAS_EXC;
-            break;
-        }
+    if (dc->base.pc_next >= 0xfffffff0 && arm_dc_feature(dc, ARM_FEATURE_M)) {
+        /* We always get here via a jump, so know we are not in a
+           conditional execution block.  */
+        gen_exception_internal(EXCP_EXCEPTION_EXIT);
+        dc->base.jmp_type = DJ_EXC;
+    }
 #endif
+}
 
-        if (unlikely(!QTAILQ_EMPTY(&cpu->breakpoints))) {
-            CPUBreakpoint *bp;
-            QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
-                if (bp->pc == dc->pc) {
-                    if (bp->flags & BP_CPU) {
-                        gen_set_condexec(dc);
-                        gen_set_pc_im(dc, dc->pc);
-                        gen_helper_check_breakpoints(cpu_env);
-                        /* End the TB early; it's likely not going to be executed */
-                        dc->is_jmp = DISAS_UPDATE;
-                    } else {
-                        gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
-                        /* 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.  */
-                        /* TODO: Advance PC by correct instruction length to
-                         * avoid disassembler error messages */
-                        dc->pc += 2;
-                        goto done_generating;
-                    }
-                    break;
-                }
-            }
-        }
-
-        if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
-            gen_io_start();
-        }
-
-        if (dc->ss_active && !dc->pstate_ss) {
-            /* Singlestep state is Active-pending.
-             * If we're in this state at the start of a TB then either
-             *  a) we just took an exception to an EL which is being debugged
-             *     and this is the first insn in the exception handler
-             *  b) debug exceptions were masked and we just unmasked them
-             *     without changing EL (eg by clearing PSTATE.D)
-             * In either case we're going to take a swstep exception in the
-             * "did not step an insn" case, and so the syndrome ISV and EX
-             * bits should be zero.
-             */
-            assert(num_insns == 1);
-            gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
-                          default_exception_el(dc));
-            goto done_generating;
-        }
+static BreakpointHitType gen_intermediate_code_target_breakpoint_hit(
+    DisasContext * restrict dc, CPUARMState * restrict env,
+    const CPUBreakpoint * restrict bp)
+{
+    if (bp->flags & BP_CPU) {
+        gen_set_condexec(dc);
+        gen_set_pc_im(dc, dc->base.pc_next);
+        gen_helper_check_breakpoints(cpu_env);
+        /* End the TB early; it's likely not going to be executed */
+        dc->base.jmp_type = DJ_UPDATE;
+        return BH_HIT_INSN;
+    } else {
+        gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
+        /* 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.  */
+        /* TODO: Advance PC by correct instruction length to avoid
+         * disassembler error messages */
+        dc->base.pc_next += 2;
+        return BH_HIT_TB;
+    }
+}
+
+static target_ulong gen_intermediate_code_target_disas_insn(
+    DisasContext * restrict dc, CPUArchState * restrict env)
+{
+    if (dc->ss_active && !dc->pstate_ss) {
+        /* Singlestep state is Active-pending.
+         * If we're in this state at the start of a TB then either
+         *  a) we just took an exception to an EL which is being debugged
+         *     and this is the first insn in the exception handler
+         *  b) debug exceptions were masked and we just unmasked them
+         *     without changing EL (eg by clearing PSTATE.D)
+         * In either case we're going to take a swstep exception in the
+         * "did not step an insn" case, and so the syndrome ISV and EX
+         * bits should be zero.
+         */
+        assert(dc->base.num_insns == 1);
+        gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
+                      default_exception_el(dc));
+        dc->base.jmp_type = DJ_SKIP;
+        return dc->base.pc_next;
+    }
 
-        if (dc->thumb) {
-            disas_thumb_insn(env, dc);
-            if (dc->condexec_mask) {
-                dc->condexec_cond = (dc->condexec_cond & 0xe)
-                                   | ((dc->condexec_mask >> 4) & 1);
-                dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
-                if (dc->condexec_mask == 0) {
-                    dc->condexec_cond = 0;
-                }
+    if (dc->thumb) {
+        disas_thumb_insn(env, dc);
+        if (dc->condexec_mask) {
+            dc->condexec_cond = (dc->condexec_cond & 0xe)
+                | ((dc->condexec_mask >> 4) & 1);
+            dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
+            if (dc->condexec_mask == 0) {
+                dc->condexec_cond = 0;
             }
-        } else {
-            unsigned int insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
-            dc->pc += 4;
-            disas_arm_insn(dc, insn);
         }
+    } else {
+        unsigned int insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
+        dc->base.pc_next += 4;
+        disas_arm_insn(dc, insn);
+    }
 
-        if (dc->condjmp && !dc->is_jmp) {
-            gen_set_label(dc->condlabel);
-            dc->condjmp = 0;
-        }
+    if (dc->condjmp && !dc->base.jmp_type) {
+        gen_set_label(dc->condlabel);
+        dc->condjmp = 0;
+    }
 
-        if (tcg_check_temp_count()) {
-            fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
-                    dc->pc);
-        }
+    return dc->base.pc_next;
+}
 
-        /* Translation stops when a conditional branch is encountered.
-         * Otherwise the subsequent code could get translated several times.
-         * Also stop translation when a page boundary is reached.  This
-         * ensures prefetch aborts occur at the right place.  */
+static DisasJumpType gen_intermediate_code_target_stop_check(
+    DisasContext * restrict dc, CPUARMState * restrict env)
+{
+    /* Translation stops when a conditional branch is encountered.
+     * Otherwise the subsequent code could get translated several times.
+     * Also stop translation when a page boundary is reached.  This
+     * ensures prefetch aborts occur at the right place.  */
 
+    if (dc->ss_active) {
+        return DJ_SS;
+    } else if ((dc->base.pc_next >= dc->next_page_start - 3)
+               && insn_crosses_page(env, dc)) {
+        /*
+         * Generic code already checked if the next insn starts in a new
+         * page.
+         */
         /* We want to stop the TB if the next insn starts in a new page,
          * or if it spans between this page and the next. This means that
          * if we're looking at the last halfword in the page we need to
@@ -11872,48 +11953,53 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
          * in it at the end of this page (which would execute correctly
          * but isn't very efficient).
          */
-        end_of_page = (dc->pc >= next_page_start) ||
-            ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc));
+        return DJ_PAGE_CROSS;
+    } else {
+        return dc->base.jmp_type;
+    }
+}
 
-    } while (!dc->is_jmp && !tcg_op_buf_full() &&
-             !cpu->singlestep_enabled &&
-             !singlestep &&
-             !dc->ss_active &&
-             !end_of_page &&
-             num_insns < max_insns);
+static void gen_intermediate_code_target_stop(
+    DisasContext * restrict dc, CPUARMState * restrict env)
+{
+    /* Cast because target-specific values are not in generic enum */
+    unsigned int jt = (unsigned int)dc->base.jmp_type;
 
-    if (tb->cflags & CF_LAST_IO) {
-        if (dc->condjmp) {
-            /* FIXME:  This can theoretically happen with self-modifying
-               code.  */
-            cpu_abort(cpu, "IO on conditional branch instruction");
-        }
-        gen_io_end();
+    if (jt == DJ_SKIP) {
+        return;
+    }
+
+    if ((dc->base.tb->cflags & CF_LAST_IO) && dc->condjmp) {
+        /* FIXME: This can theoretically happen with self-modifying code. */
+        cpu_abort(ENV_GET_CPU(env), "IO on conditional branch instruction");
     }
 
     /* 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(cpu->singlestep_enabled || dc->ss_active)) {
+    if (unlikely(dc->base.singlestep_enabled || dc->ss_active)) {
         /* Unconditional and "condition passed" instruction codepath. */
         gen_set_condexec(dc);
-        switch (dc->is_jmp) {
-        case DISAS_SWI:
+
+        /* Cast because we have values outside generic enum */
+        switch(jt) {
+        case DJ_SWI:
             gen_ss_advance(dc);
             gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
                           default_exception_el(dc));
             break;
-        case DISAS_HVC:
+        case DJ_HVC:
             gen_ss_advance(dc);
             gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
             break;
-        case DISAS_SMC:
+        case DJ_SMC:
             gen_ss_advance(dc);
             gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
             break;
-        case DISAS_NEXT:
-        case DISAS_UPDATE:
-            gen_set_pc_im(dc, dc->pc);
+        case DJ_NEXT:
+        case DJ_TOO_MANY:               /* target set DJ_NEXT */
+        case DJ_UPDATE:
+            gen_set_pc_im(dc, dc->base.pc_next);
             /* fall through */
         default:
             if (dc->ss_active) {
@@ -11924,11 +12010,12 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
                 gen_exception_internal(EXCP_DEBUG);
             }
         }
+
         if (dc->condjmp) {
             /* "Condition failed" instruction codepath. */
             gen_set_label(dc->condlabel);
             gen_set_condexec(dc);
-            gen_set_pc_im(dc, dc->pc);
+            gen_set_pc_im(dc, dc->base.pc_next);
             if (dc->ss_active) {
                 gen_step_complete_exception(dc);
             } else {
@@ -11945,144 +12032,59 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
            Hardware breakpoints have already been handled and skip this code.
          */
         gen_set_condexec(dc);
-        switch(dc->is_jmp) {
-        case DISAS_NEXT:
-            gen_goto_tb(dc, 1, dc->pc);
+
+        switch (jt) {
+        case DJ_NEXT:
+        case DJ_TOO_MANY:               /* target set DJ_NEXT */
+            gen_goto_tb(dc, 1, dc->base.pc_next);
             break;
-        case DISAS_UPDATE:
-            gen_set_pc_im(dc, dc->pc);
+        case DJ_UPDATE:
+            gen_set_pc_im(dc, dc->base.pc_next);
             /* fall through */
-        case DISAS_JUMP:
+        case DJ_JUMP:
         default:
             /* indicate that the hash table must be used to find the next TB */
             tcg_gen_exit_tb(0);
             break;
-        case DISAS_TB_JUMP:
+        case DJ_TB_JUMP:
             /* nothing more to generate */
             break;
-        case DISAS_WFI:
+        case DJ_WFI:
             gen_helper_wfi(cpu_env);
             /* The helper doesn't necessarily throw an exception, but we
              * must go back to the main loop to check for interrupts anyway.
              */
             tcg_gen_exit_tb(0);
             break;
-        case DISAS_WFE:
+        case DJ_WFE:
             gen_helper_wfe(cpu_env);
             break;
-        case DISAS_YIELD:
+        case DJ_YIELD:
             gen_helper_yield(cpu_env);
             break;
-        case DISAS_SWI:
+        case DJ_SWI:
             gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
                           default_exception_el(dc));
             break;
-        case DISAS_HVC:
+        case DJ_HVC:
             gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
             break;
-        case DISAS_SMC:
+        case DJ_SMC:
             gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
             break;
         }
+
         if (dc->condjmp) {
             gen_set_label(dc->condlabel);
             gen_set_condexec(dc);
-            gen_goto_tb(dc, 1, dc->pc);
+            gen_goto_tb(dc, 1, dc->base.pc_next);
             dc->condjmp = 0;
         }
     }
-
-done_generating:
-    gen_tb_end(tb, num_insns);
-
-#ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
-        qemu_log_in_addr_range(pc_start)) {
-        qemu_log("----------------\n");
-        qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(cpu, pc_start, dc->pc - pc_start,
-                         dc->thumb | (dc->sctlr_b << 1));
-        qemu_log("\n");
-    }
-#endif
-    tb->size = dc->pc - pc_start;
-    tb->icount = num_insns;
-}
-
-static const char *cpu_mode_names[16] = {
-  "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
-  "???", "???", "hyp", "und", "???", "???", "???", "sys"
-};
-
-void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-                        int flags)
-{
-    ARMCPU *cpu = ARM_CPU(cs);
-    CPUARMState *env = &cpu->env;
-    int i;
-    uint32_t psr;
-    const char *ns_status;
-
-    if (is_a64(env)) {
-        aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
-        return;
-    }
-
-    for(i=0;i<16;i++) {
-        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
-        if ((i % 4) == 3)
-            cpu_fprintf(f, "\n");
-        else
-            cpu_fprintf(f, " ");
-    }
-    psr = cpsr_read(env);
-
-    if (arm_feature(env, ARM_FEATURE_EL3) &&
-        (psr & CPSR_M) != ARM_CPU_MODE_MON) {
-        ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
-    } else {
-        ns_status = "";
-    }
-
-    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
-                psr,
-                psr & (1 << 31) ? 'N' : '-',
-                psr & (1 << 30) ? 'Z' : '-',
-                psr & (1 << 29) ? 'C' : '-',
-                psr & (1 << 28) ? 'V' : '-',
-                psr & CPSR_T ? 'T' : 'A',
-                ns_status,
-                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
-
-    if (flags & CPU_DUMP_FPU) {
-        int numvfpregs = 0;
-        if (arm_feature(env, ARM_FEATURE_VFP)) {
-            numvfpregs += 16;
-        }
-        if (arm_feature(env, ARM_FEATURE_VFP3)) {
-            numvfpregs += 16;
-        }
-        for (i = 0; i < numvfpregs; i++) {
-            uint64_t v = float64_val(env->vfp.regs[i]);
-            cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
-                        i * 2, (uint32_t)v,
-                        i * 2 + 1, (uint32_t)(v >> 32),
-                        i, v);
-        }
-        cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
-    }
 }
 
-void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
-                          target_ulong *data)
+static int gen_intermediate_code_target_get_disas_flags(
+    const DisasContext *dc)
 {
-    if (is_a64(env)) {
-        env->pc = data[0];
-        env->condexec_bits = 0;
-        env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
-    } else {
-        env->regs[15] = data[0];
-        env->condexec_bits = data[1];
-        env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
-    }
+    return dc->thumb | (dc->sctlr_b << 1);
 }
diff --git a/target-arm/translate.h b/target-arm/translate.h
index 602763c..57001d2 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -1,11 +1,15 @@
 #ifndef TARGET_ARM_TRANSLATE_H
 #define TARGET_ARM_TRANSLATE_H
 
+#include "exec/translate-all_template.h"
+
+
 /* internal defines */
 typedef struct DisasContext {
-    target_ulong pc;
+    DisasContextBase base;
+
+    target_ulong next_page_start;
     uint32_t insn;
-    int is_jmp;
     /* Nonzero if this instruction has been conditionally skipped.  */
     int condjmp;
     /* The label that will be jumped to when the instruction is skipped.  */
@@ -13,8 +17,6 @@ typedef struct DisasContext {
     /* Thumb-2 conditional execution bits.  */
     int condexec_mask;
     int condexec_cond;
-    struct TranslationBlock *tb;
-    int singlestep_enabled;
     int thumb;
     int sctlr_b;
     TCGMemOp be_data;
@@ -106,31 +108,45 @@ static inline int default_exception_el(DisasContext *s)
             ? 3 : MAX(1, s->current_el);
 }
 
-/* target-specific extra values for is_jmp */
-/* TODO: rename as DJ_* when transitioning this target to generic translation */
+/* Target-specific values for DisasContextBase::jmp_type */
+#include "exec/translate-all_template.h"
+#define DJ_JUMP    (DJ_TARGET+0)
+#define DJ_UPDATE  (DJ_TARGET+1)
+#define DJ_TB_JUMP (DJ_TARGET+2)
 /* These instructions trap after executing, so the A32/T32 decoder must
  * defer them until after the conditional execution state has been updated.
  * WFI also needs special handling when single-stepping.
  */
-#define DISAS_WFI DISAS_TARGET + 0
-#define DISAS_SWI DISAS_TARGET + 1
+#define DJ_WFI     (DJ_TARGET+3)
+#define DJ_SWI     (DJ_TARGET+4)
 /* For instructions which unconditionally cause an exception we can skip
  * emitting unreachable code at the end of the TB in the A64 decoder
  */
-#define DISAS_EXC DISAS_TARGET + 2
+#define DJ_EXC     (DJ_TARGET+5)
 /* WFE */
-#define DISAS_WFE DISAS_TARGET + 3
-#define DISAS_HVC DISAS_TARGET + 4
-#define DISAS_SMC DISAS_TARGET + 5
-#define DISAS_YIELD DISAS_TARGET + 6
+#define DJ_WFE     (DJ_TARGET+6)
+#define DJ_HVC     (DJ_TARGET+7)
+#define DJ_SMC     (DJ_TARGET+8)
+#define DJ_YIELD   (DJ_TARGET+9)
+#define DJ_SS      (DJ_TARGET+10)
+#define DJ_PAGE_CROSS (DJ_TARGET+11)
+#define DJ_SKIP    (DJ_TARGET+12)
+
+void gen_intermediate_code_arm(CPUState *cpu, struct TranslationBlock *tb);
+void gen_intermediate_code_aarch64(CPUState *cpu, struct TranslationBlock *tb);
 
 #ifdef TARGET_AARCH64
+void init_tmp_a64_array(DisasContext *s);
 void a64_translate_init(void);
 void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb);
 void gen_a64_set_pc_im(uint64_t val);
 void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
                             fprintf_function cpu_fprintf, int flags);
 #else
+static inline void init_tmp_a64_array(DisasContext *s)
+{
+}
+
 static inline void a64_translate_init(void)
 {
 }

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

* Re: [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework
  2016-09-09 13:03 [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework Lluís Vilanova
                   ` (5 preceding siblings ...)
  2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 6/6] target: [tcg, arm] " Lluís Vilanova
@ 2016-09-12  3:56 ` no-reply
  2016-09-12  5:05 ` no-reply
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: no-reply @ 2016-09-12  3:56 UTC (permalink / raw)
  To: vilanova; +Cc: famz, qemu-devel, pbonzini, crosthwaite.peter, rth

Hi,

Your series failed automatic build test. Please find the testing commands and
their output below. If you have docker installed, you can probably reproduce it
locally.

Type: series
Message-id: 147342618684.13303.1583142856242164602.stgit@fimbulvetr.bsc.es
Subject: [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework

=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
make J=8 docker-test-quick@centos6
make J=8 docker-test-mingw@fedora
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/147342618684.13303.1583142856242164602.stgit@fimbulvetr.bsc.es -> patchew/147342618684.13303.1583142856242164602.stgit@fimbulvetr.bsc.es
 * [new tag]         patchew/1473426607-10516-1-git-send-email-maxime.coquelin@redhat.com -> patchew/1473426607-10516-1-git-send-email-maxime.coquelin@redhat.com
Switched to a new branch 'test'
ec3c1db target: [tcg, arm] Port to generic translation framework
19005fc target: [tcg, i386] Port to generic translation framework
e068b67 target: [tcg] Redefine DISAS_* onto the generic translation framework (DJ_*)
003b3c3 target: [tcg] Add generic translation framework
8b3b57a queue: Add macro for incremental traversal
216c91c Pass generic CPUState to gen_intermediate_code()

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '65cc4d2748a2c2e6f27f1cf39e07a5dbabd80ebf'
  BUILD centos6
  ARCHIVE qemu.tgz
  ARCHIVE dtc.tgz
  COPY RUNNER
  RUN test-quick in centos6
No C++ compiler available; disabling C++ specific optional code
Install prefix    /tmp/qemu-test/src/tests/docker/install
BIOS directory    /tmp/qemu-test/src/tests/docker/install/share/qemu
binary directory  /tmp/qemu-test/src/tests/docker/install/bin
library directory /tmp/qemu-test/src/tests/docker/install/lib
module directory  /tmp/qemu-test/src/tests/docker/install/lib/qemu
libexec directory /tmp/qemu-test/src/tests/docker/install/libexec
include directory /tmp/qemu-test/src/tests/docker/install/include
config directory  /tmp/qemu-test/src/tests/docker/install/etc
local state directory   /tmp/qemu-test/src/tests/docker/install/var
Manual directory  /tmp/qemu-test/src/tests/docker/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path       /tmp/qemu-test/src
C compiler        cc
Host C compiler   cc
C++ compiler      
Objective-C compiler cc
ARFLAGS           rv
CFLAGS            -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -g 
QEMU_CFLAGS       -I/usr/include/pixman-1    -fPIE -DPIE -m64 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common  -Wendif-labels -Wmissing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-all
LDFLAGS           -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g 
make              make
install           install
python            python -B
smbd              /usr/sbin/smbd
module support    no
host CPU          x86_64
host big endian   no
target list       x86_64-softmmu aarch64-softmmu
tcg debug enabled no
gprof enabled     no
sparse enabled    no
strip binaries    yes
profiler          no
static build      no
pixman            system
SDL support       yes (1.2.14)
GTK support       no 
GTK GL support    no
VTE support       no 
TLS priority      NORMAL
GNUTLS support    no
GNUTLS rnd        no
libgcrypt         no
libgcrypt kdf     no
nettle            no 
nettle kdf        no
libtasn1          no
curses support    no
virgl support     no
curl support      no
mingw32 support   no
Audio drivers     oss
Block whitelist (rw) 
Block whitelist (ro) 
VirtFS support    no
VNC support       yes
VNC SASL support  no
VNC JPEG support  no
VNC PNG support   no
xen support       no
brlapi support    no
bluez  support    no
Documentation     no
PIE               yes
vde support       no
netmap support    no
Linux AIO support no
ATTR/XATTR support yes
Install blobs     yes
KVM support       yes
RDMA support      no
TCG interpreter   no
fdt support       yes
preadv support    yes
fdatasync         yes
madvise           yes
posix_madvise     yes
uuid support      no
libcap-ng support no
vhost-net support yes
vhost-scsi support yes
Trace backends    log
spice support     no 
rbd support       no
xfsctl support    no
smartcard support no
libusb            no
usb net redir     no
OpenGL support    no
OpenGL dmabufs    no
libiscsi support  no
libnfs support    no
build guest agent yes
QGA VSS support   no
QGA w32 disk info no
QGA MSI support   no
seccomp support   no
coroutine backend ucontext
coroutine pool    yes
GlusterFS support no
Archipelago support no
gcov              gcov
gcov enabled      no
TPM support       yes
libssh2 support   no
TPM passthrough   yes
QOM debugging     yes
vhdx              no
lzo support       no
snappy support    no
bzip2 support     no
NUMA host support no
tcmalloc support  no
jemalloc support  no
avx2 optimization no
  GEN   x86_64-softmmu/config-devices.mak.tmp
  GEN   aarch64-softmmu/config-devices.mak.tmp
  GEN   config-host.h
  GEN   qemu-options.def
  GEN   qmp-commands.h
  GEN   qapi-types.h
  GEN   qapi-visit.h
  GEN   qapi-event.h
  GEN   x86_64-softmmu/config-devices.mak
  GEN   aarch64-softmmu/config-devices.mak
  GEN   qmp-introspect.h
  GEN   tests/test-qapi-types.h
  GEN   tests/test-qapi-visit.h
  GEN   tests/test-qmp-commands.h
  GEN   tests/test-qapi-event.h
  GEN   tests/test-qmp-introspect.h
  GEN   config-all-devices.mak
  GEN   trace/generated-events.h
  GEN   trace/generated-tracers.h
  GEN   trace/generated-tcg-tracers.h
  GEN   trace/generated-helpers-wrappers.h
  GEN   trace/generated-helpers.h
  CC    tests/qemu-iotests/socket_scm_helper.o
  GEN   qga/qapi-generated/qga-qapi-types.h
  GEN   qga/qapi-generated/qga-qapi-visit.h
  GEN   qga/qapi-generated/qga-qmp-commands.h
  GEN   qga/qapi-generated/qga-qapi-types.c
  GEN   qga/qapi-generated/qga-qapi-visit.c
  GEN   qga/qapi-generated/qga-qmp-marshal.c
  GEN   qmp-introspect.c
  GEN   qapi-types.c
  GEN   qapi-visit.c
  GEN   qapi-event.c
  CC    qapi/qapi-visit-core.o
  CC    qapi/qapi-dealloc-visitor.o
  CC    qapi/qmp-input-visitor.o
  CC    qapi/qmp-output-visitor.o
  CC    qapi/qmp-registry.o
  CC    qapi/qmp-dispatch.o
  CC    qapi/string-input-visitor.o
  CC    qapi/string-output-visitor.o
  CC    qapi/opts-visitor.o
  CC    qapi/qapi-clone-visitor.o
  CC    qapi/qmp-event.o
  CC    qapi/qapi-util.o
  CC    qobject/qnull.o
  CC    qobject/qint.o
  CC    qobject/qstring.o
  CC    qobject/qdict.o
  CC    qobject/qlist.o
  CC    qobject/qfloat.o
  CC    qobject/qbool.o
  CC    qobject/qjson.o
  CC    qobject/qobject.o
  CC    qobject/json-lexer.o
  CC    qobject/json-streamer.o
  CC    qobject/json-parser.o
  GEN   trace/generated-events.c
  CC    trace/control.o
  CC    trace/qmp.o
  CC    util/osdep.o
  CC    util/cutils.o
  CC    util/unicode.o
  CC    util/qemu-timer-common.o
  CC    util/compatfd.o
  CC    util/event_notifier-posix.o
  CC    util/mmap-alloc.o
  CC    util/oslib-posix.o
  CC    util/qemu-openpty.o
  CC    util/qemu-thread-posix.o
  CC    util/memfd.o
  CC    util/envlist.o
  CC    util/path.o
  CC    util/module.o
  CC    util/bitmap.o
  CC    util/hbitmap.o
  CC    util/bitops.o
  CC    util/fifo8.o
  CC    util/acl.o
  CC    util/error.o
  CC    util/qemu-error.o
  CC    util/id.o
  CC    util/iov.o
  CC    util/qemu-config.o
  CC    util/qemu-sockets.o
  CC    util/uri.o
  CC    util/notify.o
  CC    util/qemu-option.o
  CC    util/qemu-progress.o
  CC    util/hexdump.o
  CC    util/crc32c.o
  CC    util/throttle.o
  CC    util/getauxval.o
  CC    util/readline.o
  CC    util/rfifolock.o
  CC    util/rcu.o
  CC    util/qemu-coroutine.o
  CC    util/qemu-coroutine-lock.o
  CC    util/qemu-coroutine-io.o
  CC    util/qemu-coroutine-sleep.o
  CC    util/coroutine-ucontext.o
  CC    util/buffer.o
  CC    util/timed-average.o
  CC    util/base64.o
  CC    util/log.o
  CC    util/qdist.o
  CC    util/qht.o
  CC    util/range.o
  CC    crypto/pbkdf-stub.o
  CC    stubs/arch-query-cpu-def.o
  CC    stubs/arch-query-cpu-model-expansion.o
/tmp/qemu-test/src/util/qht.c: In function ‘qht_reset_size’:
/tmp/qemu-test/src/util/qht.c:413: warning: ‘new’ may be used uninitialized in this function
  CC    stubs/arch-query-cpu-model-comparison.o
  CC    stubs/arch-query-cpu-model-baseline.o
  CC    stubs/bdrv-next-monitor-owned.o
  CC    stubs/blk-commit-all.o
  CC    stubs/blockdev-close-all-bdrv-states.o
  CC    stubs/clock-warp.o
  CC    stubs/cpu-get-clock.o
  CC    stubs/cpu-get-icount.o
  CC    stubs/dump.o
  CC    stubs/fdset-add-fd.o
  CC    stubs/fdset-find-fd.o
  CC    stubs/fdset-get-fd.o
  CC    stubs/fdset-remove-fd.o
  CC    stubs/gdbstub.o
  CC    stubs/get-fd.o
  CC    stubs/get-next-serial.o
  CC    stubs/get-vm-name.o
  CC    stubs/iothread-lock.o
  CC    stubs/is-daemonized.o
  CC    stubs/machine-init-done.o
  CC    stubs/migr-blocker.o
  CC    stubs/mon-is-qmp.o
  CC    stubs/mon-printf.o
  CC    stubs/monitor-init.o
  CC    stubs/notify-event.o
  CC    stubs/qtest.o
  CC    stubs/replay.o
  CC    stubs/replay-user.o
  CC    stubs/reset.o
  CC    stubs/runstate-check.o
  CC    stubs/set-fd-handler.o
  CC    stubs/slirp.o
  CC    stubs/sysbus.o
  CC    stubs/trace-control.o
  CC    stubs/uuid.o
  CC    stubs/vm-stop.o
  CC    stubs/vmstate.o
  CC    stubs/cpus.o
  CC    stubs/kvm.o
  CC    stubs/qmp_pc_dimm_device_list.o
  CC    stubs/target-monitor-defs.o
  CC    stubs/target-get-monitor-def.o
  CC    stubs/vhost.o
  CC    stubs/iohandler.o
  CC    stubs/smbios_type_38.o
  CC    stubs/ipmi.o
  CC    stubs/pc_madt_cpu_entry.o
  CC    contrib/ivshmem-client/ivshmem-client.o
  CC    contrib/ivshmem-client/main.o
  CC    contrib/ivshmem-server/ivshmem-server.o
  CC    contrib/ivshmem-server/main.o
  CC    qemu-nbd.o
  CC    async.o
  CC    thread-pool.o
  CC    block.o
  CC    blockjob.o
  CC    main-loop.o
  CC    iohandler.o
  CC    qemu-timer.o
  CC    aio-posix.o
  CC    qemu-io-cmds.o
  CC    block/raw_bsd.o
  CC    block/qcow.o
  CC    block/vdi.o
  CC    block/vmdk.o
  CC    block/cloop.o
  CC    block/bochs.o
  CC    block/vpc.o
  CC    block/vvfat.o
  CC    block/qcow2.o
  CC    block/qcow2-refcount.o
  CC    block/qcow2-cluster.o
  CC    block/qcow2-snapshot.o
  CC    block/qcow2-cache.o
  CC    block/qed.o
  CC    block/qed-gencb.o
  CC    block/qed-l2-cache.o
  CC    block/qed-table.o
  CC    block/qed-cluster.o
  CC    block/qed-check.o
  CC    block/quorum.o
  CC    block/parallels.o
  CC    block/blkdebug.o
  CC    block/blkverify.o
  CC    block/blkreplay.o
  CC    block/block-backend.o
  CC    block/snapshot.o
  CC    block/qapi.o
  CC    block/raw-posix.o
  CC    block/null.o
  CC    block/mirror.o
  CC    block/commit.o
  CC    block/io.o
  CC    block/throttle-groups.o
  CC    block/nbd.o
  CC    block/nbd-client.o
  CC    block/sheepdog.o
  CC    block/accounting.o
  CC    block/dirty-bitmap.o
  CC    block/write-threshold.o
  CC    block/crypto.o
  CC    nbd/server.o
  CC    nbd/client.o
  CC    nbd/common.o
  CC    block/dmg.o
  CC    crypto/init.o
  CC    crypto/hash.o
  CC    crypto/hash-glib.o
  CC    crypto/aes.o
  CC    crypto/desrfb.o
  CC    crypto/cipher.o
  CC    crypto/tlscreds.o
  CC    crypto/tlscredsanon.o
  CC    crypto/tlscredsx509.o
  CC    crypto/tlssession.o
  CC    crypto/secret.o
  CC    crypto/random-platform.o
  CC    crypto/pbkdf.o
  CC    crypto/ivgen.o
  CC    crypto/ivgen-essiv.o
  CC    crypto/ivgen-plain.o
  CC    crypto/ivgen-plain64.o
  CC    crypto/afsplit.o
  CC    crypto/xts.o
  CC    crypto/block.o
  CC    crypto/block-qcow.o
  CC    crypto/block-luks.o
  CC    io/channel.o
  CC    io/channel-buffer.o
  CC    io/channel-command.o
  CC    io/channel-file.o
  CC    io/channel-socket.o
  CC    io/channel-tls.o
  CC    io/channel-watch.o
  CC    io/channel-websock.o
  CC    io/channel-util.o
  CC    io/task.o
  CC    qom/object.o
  CC    qom/container.o
  CC    qom/qom-qobject.o
  CC    qom/object_interfaces.o
  GEN   qemu-img-cmds.h
  CC    qemu-io.o
  CC    qemu-bridge-helper.o
  CC    blockdev.o
  CC    blockdev-nbd.o
  CC    iothread.o
  CC    qdev-monitor.o
  CC    device-hotplug.o
  CC    os-posix.o
  CC    qemu-char.o
  CC    page_cache.o
  CC    accel.o
  CC    bt-host.o
  CC    bt-vhci.o
  CC    dma-helpers.o
  CC    vl.o
  CC    tpm.o
  CC    device_tree.o
  GEN   qmp-marshal.c
  CC    qmp.o
  CC    hmp.o
  CC    tcg-runtime.o
  CC    audio/audio.o
  CC    audio/noaudio.o
  CC    audio/wavaudio.o
  CC    audio/mixeng.o
  CC    audio/sdlaudio.o
  CC    audio/ossaudio.o
  CC    audio/wavcapture.o
  CC    backends/rng.o
  CC    backends/rng-egd.o
  CC    backends/rng-random.o
  CC    backends/msmouse.o
  CC    backends/testdev.o
  CC    backends/tpm.o
  CC    backends/hostmem.o
  CC    backends/hostmem-ram.o
  CC    backends/hostmem-file.o
  CC    block/stream.o
  CC    block/backup.o
  CC    disas/arm.o
  CC    disas/i386.o
  CC    fsdev/qemu-fsdev-dummy.o
  CC    fsdev/qemu-fsdev-opts.o
  CC    hw/acpi/core.o
  CC    hw/acpi/piix4.o
  CC    hw/acpi/pcihp.o
  CC    hw/acpi/ich9.o
  CC    hw/acpi/tco.o
  CC    hw/acpi/cpu_hotplug.o
  CC    hw/acpi/memory_hotplug.o
  CC    hw/acpi/memory_hotplug_acpi_table.o
  CC    hw/acpi/cpu.o
  CC    hw/acpi/acpi_interface.o
  CC    hw/acpi/bios-linker-loader.o
  CC    hw/acpi/aml-build.o
  CC    hw/acpi/ipmi.o
  CC    hw/audio/sb16.o
  CC    hw/audio/es1370.o
  CC    hw/audio/ac97.o
  CC    hw/audio/fmopl.o
  CC    hw/audio/adlib.o
  CC    hw/audio/gus.o
  CC    hw/audio/gusemu_hal.o
  CC    hw/audio/gusemu_mixer.o
  CC    hw/audio/cs4231a.o
  CC    hw/audio/intel-hda.o
  CC    hw/audio/hda-codec.o
  CC    hw/audio/pcspk.o
  CC    hw/audio/wm8750.o
  CC    hw/audio/pl041.o
  CC    hw/audio/lm4549.o
  CC    hw/audio/marvell_88w8618.o
  CC    hw/block/block.o
  CC    hw/block/cdrom.o
  CC    hw/block/hd-geometry.o
  CC    hw/block/fdc.o
  CC    hw/block/m25p80.o
  CC    hw/block/pflash_cfi01.o
  CC    hw/block/nand.o
  CC    hw/block/pflash_cfi02.o
  CC    hw/block/ecc.o
  CC    hw/block/onenand.o
  CC    hw/block/nvme.o
  CC    hw/bt/core.o
  CC    hw/bt/l2cap.o
  CC    hw/bt/sdp.o
  CC    hw/bt/hci.o
  CC    hw/bt/hid.o
  CC    hw/bt/hci-csr.o
  CC    hw/char/ipoctal232.o
  CC    hw/char/parallel.o
  CC    hw/char/pl011.o
  CC    hw/char/serial.o
  CC    hw/char/serial-isa.o
  CC    hw/char/serial-pci.o
  CC    hw/char/virtio-console.o
  CC    hw/char/cadence_uart.o
  CC    hw/char/debugcon.o
  CC    hw/char/imx_serial.o
  CC    hw/core/qdev.o
  CC    hw/core/qdev-properties.o
  CC    hw/core/bus.o
  CC    hw/core/fw-path-provider.o
  CC    hw/core/irq.o
  CC    hw/core/hotplug.o
  CC    hw/core/ptimer.o
  CC    hw/core/sysbus.o
  CC    hw/core/machine.o
  CC    hw/core/null-machine.o
  CC    hw/core/loader.o
  CC    hw/core/qdev-properties-system.o
  CC    hw/core/register.o
  CC    hw/core/platform-bus.o
  CC    hw/display/ads7846.o
  CC    hw/display/cirrus_vga.o
  CC    hw/display/pl110.o
  CC    hw/display/ssd0303.o
  CC    hw/display/ssd0323.o
  CC    hw/display/vga-pci.o
  CC    hw/display/vga-isa.o
  CC    hw/display/vmware_vga.o
  CC    hw/display/blizzard.o
  CC    hw/display/exynos4210_fimd.o
  CC    hw/display/framebuffer.o
  CC    hw/display/tc6393xb.o
  CC    hw/dma/pl080.o
  CC    hw/dma/pl330.o
  CC    hw/dma/i8257.o
  CC    hw/dma/xlnx-zynq-devcfg.o
  CC    hw/gpio/max7310.o
  CC    hw/gpio/pl061.o
  CC    hw/gpio/zaurus.o
  CC    hw/gpio/gpio_key.o
  CC    hw/i2c/core.o
  CC    hw/i2c/smbus.o
  CC    hw/i2c/smbus_eeprom.o
  CC    hw/i2c/i2c-ddc.o
  CC    hw/i2c/versatile_i2c.o
  CC    hw/i2c/smbus_ich9.o
  CC    hw/i2c/pm_smbus.o
  CC    hw/i2c/bitbang_i2c.o
  CC    hw/i2c/exynos4210_i2c.o
  CC    hw/i2c/imx_i2c.o
  CC    hw/i2c/aspeed_i2c.o
  CC    hw/ide/core.o
  CC    hw/ide/atapi.o
  CC    hw/ide/qdev.o
  CC    hw/ide/pci.o
  CC    hw/ide/isa.o
  CC    hw/ide/piix.o
  CC    hw/ide/microdrive.o
  CC    hw/ide/ahci.o
  CC    hw/ide/ich.o
  CC    hw/input/hid.o
  CC    hw/input/lm832x.o
  CC    hw/input/pckbd.o
  CC    hw/input/pl050.o
  CC    hw/input/ps2.o
  CC    hw/input/stellaris_input.o
  CC    hw/input/tsc2005.o
  CC    hw/input/vmmouse.o
  CC    hw/input/virtio-input.o
  CC    hw/input/virtio-input-hid.o
  CC    hw/input/virtio-input-host.o
  CC    hw/intc/i8259_common.o
  CC    hw/intc/i8259.o
  CC    hw/intc/pl190.o
  CC    hw/intc/imx_avic.o
  CC    hw/intc/realview_gic.o
  CC    hw/intc/ioapic_common.o
  CC    hw/intc/arm_gic_common.o
  CC    hw/intc/arm_gic.o
  CC    hw/intc/arm_gicv2m.o
  CC    hw/intc/arm_gicv3_common.o
  CC    hw/intc/arm_gicv3.o
  CC    hw/intc/arm_gicv3_dist.o
  CC    hw/intc/arm_gicv3_redist.o
  CC    hw/ipack/ipack.o
  CC    hw/ipack/tpci200.o
  CC    hw/ipmi/ipmi.o
  CC    hw/ipmi/ipmi_bmc_sim.o
  CC    hw/ipmi/ipmi_bmc_extern.o
  CC    hw/ipmi/isa_ipmi_kcs.o
  CC    hw/ipmi/isa_ipmi_bt.o
  CC    hw/isa/isa-bus.o
  CC    hw/isa/apm.o
  CC    hw/mem/pc-dimm.o
  CC    hw/mem/nvdimm.o
  CC    hw/misc/applesmc.o
  CC    hw/misc/max111x.o
  CC    hw/misc/tmp105.o
  CC    hw/misc/debugexit.o
  CC    hw/misc/sga.o
  CC    hw/misc/pc-testdev.o
  CC    hw/misc/pci-testdev.o
  CC    hw/misc/arm_l2x0.o
  CC    hw/misc/arm_integrator_debug.o
  CC    hw/misc/a9scu.o
  CC    hw/misc/arm11scu.o
  CC    hw/net/ne2000.o
  CC    hw/net/eepro100.o
  CC    hw/net/pcnet-pci.o
  CC    hw/net/pcnet.o
  CC    hw/net/e1000.o
  CC    hw/net/e1000x_common.o
  CC    hw/net/net_tx_pkt.o
  CC    hw/net/net_rx_pkt.o
  CC    hw/net/e1000e.o
  CC    hw/net/e1000e_core.o
  CC    hw/net/rtl8139.o
  CC    hw/net/vmxnet3.o
  CC    hw/net/smc91c111.o
  CC    hw/net/lan9118.o
  CC    hw/net/ne2000-isa.o
  CC    hw/net/xgmac.o
  CC    hw/net/allwinner_emac.o
  CC    hw/net/imx_fec.o
  CC    hw/net/cadence_gem.o
  CC    hw/net/stellaris_enet.o
  CC    hw/net/rocker/rocker.o
  CC    hw/net/rocker/rocker_fp.o
  CC    hw/net/rocker/rocker_desc.o
  CC    hw/net/rocker/rocker_world.o
  CC    hw/net/rocker/rocker_of_dpa.o
  CC    hw/nvram/eeprom93xx.o
  CC    hw/nvram/fw_cfg.o
  CC    hw/pci-bridge/pci_bridge_dev.o
  CC    hw/pci-bridge/pci_expander_bridge.o
  CC    hw/pci-bridge/xio3130_upstream.o
  CC    hw/pci-bridge/xio3130_downstream.o
  CC    hw/pci-bridge/ioh3420.o
  CC    hw/pci-bridge/i82801b11.o
  CC    hw/pci-host/pam.o
  CC    hw/pci-host/versatile.o
  CC    hw/pci-host/piix.o
  CC    hw/pci-host/q35.o
  CC    hw/pci-host/gpex.o
  CC    hw/pci/pci.o
  CC    hw/pci/pci_bridge.o
  CC    hw/pci/msix.o
  CC    hw/pci/msi.o
  CC    hw/pci/shpc.o
  CC    hw/pci/slotid_cap.o
/tmp/qemu-test/src/hw/nvram/fw_cfg.c: In function ‘fw_cfg_dma_transfer’:
/tmp/qemu-test/src/hw/nvram/fw_cfg.c:330: warning: ‘read’ may be used uninitialized in this function
  CC    hw/pci/pci_host.o
  CC    hw/pci/pcie_host.o
  CC    hw/pci/pcie.o
  CC    hw/pci/pcie_aer.o
  CC    hw/pci/pcie_port.o
  CC    hw/pci/pci-stub.o
  CC    hw/pcmcia/pcmcia.o
  CC    hw/scsi/scsi-disk.o
  CC    hw/scsi/scsi-generic.o
  CC    hw/scsi/scsi-bus.o
  CC    hw/scsi/lsi53c895a.o
  CC    hw/scsi/mptsas.o
  CC    hw/scsi/mptconfig.o
  CC    hw/scsi/mptendian.o
  CC    hw/scsi/megasas.o
  CC    hw/scsi/vmw_pvscsi.o
  CC    hw/scsi/esp.o
  CC    hw/scsi/esp-pci.o
  CC    hw/sd/pl181.o
  CC    hw/sd/ssi-sd.o
  CC    hw/sd/sd.o
  CC    hw/sd/core.o
  CC    hw/sd/sdhci.o
  CC    hw/smbios/smbios.o
  CC    hw/smbios/smbios_type_38.o
  CC    hw/ssi/pl022.o
  CC    hw/ssi/ssi.o
  CC    hw/ssi/xilinx_spips.o
  CC    hw/ssi/aspeed_smc.o
  CC    hw/timer/arm_timer.o
  CC    hw/timer/arm_mptimer.o
  CC    hw/timer/a9gtimer.o
  CC    hw/timer/cadence_ttc.o
  CC    hw/timer/ds1338.o
  CC    hw/timer/hpet.o
  CC    hw/timer/i8254_common.o
  CC    hw/timer/i8254.o
  CC    hw/timer/pl031.o
  CC    hw/timer/twl92230.o
  CC    hw/timer/imx_epit.o
  CC    hw/timer/imx_gpt.o
  CC    hw/timer/stm32f2xx_timer.o
  CC    hw/timer/aspeed_timer.o
  CC    hw/tpm/tpm_tis.o
  CC    hw/tpm/tpm_passthrough.o
  CC    hw/tpm/tpm_util.o
  CC    hw/usb/core.o
  CC    hw/usb/combined-packet.o
  CC    hw/usb/bus.o
  CC    hw/usb/libhw.o
  CC    hw/usb/desc.o
  CC    hw/usb/desc-msos.o
  CC    hw/usb/hcd-uhci.o
  CC    hw/usb/hcd-ohci.o
  CC    hw/usb/hcd-ehci.o
  CC    hw/usb/hcd-ehci-pci.o
  CC    hw/usb/hcd-ehci-sysbus.o
  CC    hw/usb/hcd-xhci.o
  CC    hw/usb/hcd-musb.o
  CC    hw/usb/dev-hub.o
  CC    hw/usb/dev-hid.o
  CC    hw/usb/dev-wacom.o
  CC    hw/usb/dev-storage.o
  CC    hw/usb/dev-uas.o
  CC    hw/usb/dev-audio.o
  CC    hw/usb/dev-serial.o
  CC    hw/usb/dev-network.o
  CC    hw/usb/dev-bluetooth.o
  CC    hw/usb/dev-smartcard-reader.o
  CC    hw/usb/dev-mtp.o
  CC    hw/usb/host-stub.o
  CC    hw/virtio/virtio-rng.o
  CC    hw/virtio/virtio-pci.o
  CC    hw/virtio/virtio-bus.o
  CC    hw/virtio/virtio-mmio.o
  CC    hw/watchdog/watchdog.o
  CC    hw/watchdog/wdt_i6300esb.o
  CC    hw/watchdog/wdt_ib700.o
  CC    migration/migration.o
  CC    migration/socket.o
  CC    migration/fd.o
  CC    migration/exec.o
  CC    migration/tls.o
  CC    migration/vmstate.o
  CC    migration/qemu-file.o
  CC    migration/qemu-file-channel.o
  CC    migration/xbzrle.o
  CC    migration/postcopy-ram.o
  CC    migration/qjson.o
  CC    migration/block.o
  CC    net/net.o
  CC    net/queue.o
  CC    net/checksum.o
  CC    net/util.o
  CC    net/hub.o
  CC    net/socket.o
  CC    net/dump.o
  CC    net/eth.o
  CC    net/l2tpv3.o
  CC    net/tap.o
  CC    net/vhost-user.o
  CC    net/tap-linux.o
  CC    net/slirp.o
  CC    net/filter.o
  CC    net/filter-buffer.o
  CC    net/filter-mirror.o
  CC    qom/cpu.o
  CC    replay/replay.o
  CC    replay/replay-internal.o
  CC    replay/replay-events.o
  CC    replay/replay-time.o
/tmp/qemu-test/src/replay/replay-internal.c: In function ‘replay_put_array’:
/tmp/qemu-test/src/replay/replay-internal.c:68: warning: ignoring return value of ‘fwrite’, declared with attribute warn_unused_result
  CC    replay/replay-input.o
  CC    replay/replay-char.o
  CC    slirp/cksum.o
  CC    slirp/if.o
  CC    slirp/ip_icmp.o
  CC    slirp/ip6_icmp.o
  CC    slirp/ip6_input.o
  CC    slirp/ip6_output.o
  CC    slirp/ip_input.o
  CC    slirp/ip_output.o
  CC    slirp/dnssearch.o
  CC    slirp/dhcpv6.o
  CC    slirp/slirp.o
  CC    slirp/mbuf.o
  CC    slirp/misc.o
  CC    slirp/sbuf.o
  CC    slirp/socket.o
  CC    slirp/tcp_input.o
  CC    slirp/tcp_output.o
  CC    slirp/tcp_subr.o
  CC    slirp/tcp_timer.o
  CC    slirp/udp.o
  CC    slirp/udp6.o
  CC    slirp/bootp.o
  CC    slirp/tftp.o
  CC    slirp/arp_table.o
/tmp/qemu-test/src/slirp/tcp_input.c: In function ‘tcp_input’:
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_p’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_len’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_tos’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_id’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_off’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_ttl’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_sum’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_src.s_addr’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:219: warning: ‘save_ip.ip_dst.s_addr’ may be used uninitialized in this function
/tmp/qemu-test/src/slirp/tcp_input.c:220: warning: ‘save_ip6.ip_nh’ may be used uninitialized in this function
  CC    slirp/ndp_table.o
  CC    ui/keymaps.o
  CC    ui/console.o
  CC    ui/cursor.o
  CC    ui/qemu-pixman.o
  CC    ui/input.o
  CC    ui/input-keymap.o
  CC    ui/input-legacy.o
  CC    ui/input-linux.o
  CC    ui/sdl.o
  CC    ui/sdl_zoom.o
  CC    ui/x_keymap.o
  CC    ui/vnc.o
  CC    ui/vnc-enc-zlib.o
  CC    ui/vnc-enc-hextile.o
  CC    ui/vnc-enc-tight.o
  CC    ui/vnc-palette.o
  CC    ui/vnc-enc-zrle.o
  CC    ui/vnc-auth-vencrypt.o
  CC    ui/vnc-ws.o
  CC    ui/vnc-jobs.o
  LINK  tests/qemu-iotests/socket_scm_helper
  CC    qga/commands.o
  AS    optionrom/multiboot.o
  CC    qga/guest-agent-command-state.o
  CC    qga/main.o
  AS    optionrom/linuxboot.o
  CC    optionrom/linuxboot_dma.o
cc: unrecognized option '-no-integrated-as'
cc: unrecognized option '-no-integrated-as'
  AS    optionrom/kvmvapic.o
  CC    qga/commands-posix.o
  Building optionrom/multiboot.img
  Building optionrom/linuxboot.img
  Building optionrom/linuxboot_dma.img
  Building optionrom/kvmvapic.img
  Building optionrom/multiboot.raw
  Building optionrom/linuxboot.raw
  Building optionrom/linuxboot_dma.raw
  Building optionrom/kvmvapic.raw
  Signing optionrom/multiboot.bin
  Signing optionrom/linuxboot.bin
  Signing optionrom/linuxboot_dma.bin
  CC    qga/channel-posix.o
  Signing optionrom/kvmvapic.bin
  CC    qga/qapi-generated/qga-qapi-types.o
  CC    qga/qapi-generated/qga-qapi-visit.o
  CC    qga/qapi-generated/qga-qmp-marshal.o
  CC    qmp-introspect.o
  CC    qapi-types.o
  CC    qapi-visit.o
  CC    qapi-event.o
  AR    libqemustub.a
  CC    qemu-img.o
  CC    qmp-marshal.o
  CC    trace/generated-events.o
  AR    libqemuutil.a
  LINK  qemu-ga
  LINK  ivshmem-client
  LINK  ivshmem-server
  LINK  qemu-nbd
  LINK  qemu-io
  LINK  qemu-bridge-helper
  LINK  qemu-img
  GEN   x86_64-softmmu/hmp-commands.h
  GEN   x86_64-softmmu/hmp-commands-info.h
  GEN   x86_64-softmmu/qmp-commands-old.h
  GEN   x86_64-softmmu/config-target.h
  GEN   aarch64-softmmu/hmp-commands.h
  GEN   aarch64-softmmu/qmp-commands-old.h
  GEN   aarch64-softmmu/hmp-commands-info.h
  GEN   aarch64-softmmu/config-target.h
  CC    x86_64-softmmu/exec.o
  CC    x86_64-softmmu/translate-all.o
  CC    x86_64-softmmu/cpu-exec.o
  CC    x86_64-softmmu/tcg/tcg.o
  CC    x86_64-softmmu/translate-common.o
  CC    x86_64-softmmu/cpu-exec-common.o
  CC    x86_64-softmmu/tcg/tcg-op.o
  CC    aarch64-softmmu/exec.o
  CC    x86_64-softmmu/tcg/optimize.o
  CC    x86_64-softmmu/tcg/tcg-common.o
  CC    x86_64-softmmu/fpu/softfloat.o
  CC    x86_64-softmmu/disas.o
  CC    x86_64-softmmu/arch_init.o
  CC    x86_64-softmmu/cpus.o
  CC    x86_64-softmmu/monitor.o
  CC    x86_64-softmmu/gdbstub.o
  CC    x86_64-softmmu/balloon.o
  CC    aarch64-softmmu/translate-all.o
  CC    x86_64-softmmu/ioport.o
  CC    x86_64-softmmu/numa.o
  CC    x86_64-softmmu/qtest.o
  CC    x86_64-softmmu/bootdevice.o
  CC    x86_64-softmmu/kvm-all.o
  CC    x86_64-softmmu/memory.o
  CC    aarch64-softmmu/cpu-exec.o
  CC    x86_64-softmmu/cputlb.o
  CC    x86_64-softmmu/memory_mapping.o
  CC    aarch64-softmmu/translate-common.o
  CC    x86_64-softmmu/dump.o
  CC    aarch64-softmmu/cpu-exec-common.o
  CC    aarch64-softmmu/tcg/tcg.o
  CC    x86_64-softmmu/migration/ram.o
  CC    aarch64-softmmu/tcg/tcg-op.o
  CC    x86_64-softmmu/migration/savevm.o
  CC    aarch64-softmmu/tcg/optimize.o
  CC    aarch64-softmmu/tcg/tcg-common.o
  CC    x86_64-softmmu/xen-common-stub.o
  CC    aarch64-softmmu/fpu/softfloat.o
  CC    aarch64-softmmu/disas.o
  CC    x86_64-softmmu/xen-hvm-stub.o
  CC    x86_64-softmmu/hw/acpi/nvdimm.o
  CC    x86_64-softmmu/hw/block/virtio-blk.o
  GEN   aarch64-softmmu/gdbstub-xml.c
  CC    aarch64-softmmu/kvm-stub.o
  CC    aarch64-softmmu/arch_init.o
  CC    x86_64-softmmu/hw/block/dataplane/virtio-blk.o
  CC    aarch64-softmmu/cpus.o
  CC    x86_64-softmmu/hw/char/virtio-serial-bus.o
  CC    x86_64-softmmu/hw/core/nmi.o
  CC    aarch64-softmmu/monitor.o
  CC    x86_64-softmmu/hw/cpu/core.o
  CC    aarch64-softmmu/gdbstub.o
  CC    aarch64-softmmu/balloon.o
  CC    aarch64-softmmu/ioport.o
  CC    x86_64-softmmu/hw/display/vga.o
  CC    aarch64-softmmu/numa.o
  CC    aarch64-softmmu/qtest.o
  CC    x86_64-softmmu/hw/display/virtio-gpu.o
  CC    aarch64-softmmu/bootdevice.o
  CC    x86_64-softmmu/hw/display/virtio-gpu-3d.o
  CC    aarch64-softmmu/memory.o
  CC    aarch64-softmmu/cputlb.o
  CC    aarch64-softmmu/memory_mapping.o
  CC    aarch64-softmmu/dump.o
  CC    x86_64-softmmu/hw/display/virtio-gpu-pci.o
  CC    aarch64-softmmu/migration/ram.o
  CC    x86_64-softmmu/hw/display/virtio-vga.o
  CC    aarch64-softmmu/migration/savevm.o
  CC    aarch64-softmmu/xen-common-stub.o
  CC    x86_64-softmmu/hw/intc/apic.o
  CC    x86_64-softmmu/hw/intc/apic_common.o
  CC    x86_64-softmmu/hw/intc/ioapic.o
  CC    x86_64-softmmu/hw/isa/lpc_ich9.o
  CC    aarch64-softmmu/xen-hvm-stub.o
  CC    x86_64-softmmu/hw/misc/vmport.o
  CC    aarch64-softmmu/hw/block/virtio-blk.o
  CC    x86_64-softmmu/hw/misc/ivshmem.o
  CC    x86_64-softmmu/hw/misc/pvpanic.o
  CC    aarch64-softmmu/hw/block/dataplane/virtio-blk.o
  CC    aarch64-softmmu/hw/char/exynos4210_uart.o
  CC    aarch64-softmmu/hw/char/omap_uart.o
  CC    x86_64-softmmu/hw/misc/edu.o
  CC    aarch64-softmmu/hw/char/digic-uart.o
  CC    x86_64-softmmu/hw/misc/hyperv_testdev.o
  CC    aarch64-softmmu/hw/char/stm32f2xx_usart.o
  CC    x86_64-softmmu/hw/net/virtio-net.o
  CC    x86_64-softmmu/hw/net/vhost_net.o
  CC    aarch64-softmmu/hw/char/bcm2835_aux.o
  CC    x86_64-softmmu/hw/scsi/virtio-scsi.o
  CC    aarch64-softmmu/hw/char/virtio-serial-bus.o
  CC    x86_64-softmmu/hw/scsi/virtio-scsi-dataplane.o
  CC    x86_64-softmmu/hw/scsi/vhost-scsi.o
  CC    x86_64-softmmu/hw/timer/mc146818rtc.o
  CC    aarch64-softmmu/hw/core/nmi.o
  CC    aarch64-softmmu/hw/cpu/arm11mpcore.o
  CC    x86_64-softmmu/hw/vfio/common.o
  CC    x86_64-softmmu/hw/vfio/pci.o
  CC    x86_64-softmmu/hw/vfio/pci-quirks.o
  CC    x86_64-softmmu/hw/vfio/platform.o
  CC    aarch64-softmmu/hw/cpu/realview_mpcore.o
  CC    x86_64-softmmu/hw/vfio/calxeda-xgmac.o
  CC    aarch64-softmmu/hw/cpu/a9mpcore.o
  CC    aarch64-softmmu/hw/cpu/a15mpcore.o
  CC    x86_64-softmmu/hw/vfio/amd-xgbe.o
  CC    aarch64-softmmu/hw/cpu/core.o
  CC    x86_64-softmmu/hw/vfio/spapr.o
  CC    aarch64-softmmu/hw/display/omap_dss.o
  CC    aarch64-softmmu/hw/display/omap_lcdc.o
  CC    aarch64-softmmu/hw/display/pxa2xx_lcd.o
  CC    x86_64-softmmu/hw/virtio/virtio.o
  CC    aarch64-softmmu/hw/display/bcm2835_fb.o
  CC    x86_64-softmmu/hw/virtio/virtio-balloon.o
  CC    aarch64-softmmu/hw/display/vga.o
  CC    aarch64-softmmu/hw/display/virtio-gpu.o
  CC    aarch64-softmmu/hw/display/virtio-gpu-3d.o
  CC    x86_64-softmmu/hw/virtio/vhost.o
  CC    aarch64-softmmu/hw/display/virtio-gpu-pci.o
  CC    x86_64-softmmu/hw/virtio/vhost-backend.o
  CC    aarch64-softmmu/hw/display/dpcd.o
  CC    x86_64-softmmu/hw/virtio/vhost-user.o
  CC    aarch64-softmmu/hw/display/xlnx_dp.o
  CC    aarch64-softmmu/hw/dma/xlnx_dpdma.o
  CC    aarch64-softmmu/hw/dma/omap_dma.o
  CC    aarch64-softmmu/hw/dma/soc_dma.o
  CC    x86_64-softmmu/hw/i386/multiboot.o
  CC    x86_64-softmmu/hw/i386/pc.o
  CC    aarch64-softmmu/hw/dma/pxa2xx_dma.o
  CC    aarch64-softmmu/hw/dma/bcm2835_dma.o
  CC    aarch64-softmmu/hw/gpio/omap_gpio.o
  CC    x86_64-softmmu/hw/i386/pc_piix.o
  CC    aarch64-softmmu/hw/gpio/imx_gpio.o
  CC    aarch64-softmmu/hw/i2c/omap_i2c.o
  CC    aarch64-softmmu/hw/input/pxa2xx_keypad.o
  CC    x86_64-softmmu/hw/i386/pc_q35.o
  CC    x86_64-softmmu/hw/i386/pc_sysfw.o
  CC    aarch64-softmmu/hw/input/tsc210x.o
  CC    aarch64-softmmu/hw/intc/armv7m_nvic.o
  CC    x86_64-softmmu/hw/i386/x86-iommu.o
  CC    aarch64-softmmu/hw/intc/exynos4210_gic.o
  CC    x86_64-softmmu/hw/i386/intel_iommu.o
/tmp/qemu-test/src/hw/i386/pc_piix.c: In function ‘igd_passthrough_isa_bridge_create’:
/tmp/qemu-test/src/hw/i386/pc_piix.c:1036: warning: ‘pch_rev_id’ may be used uninitialized in this function
  CC    x86_64-softmmu/hw/i386/kvmvapic.o
  CC    x86_64-softmmu/hw/i386/acpi-build.o
  CC    x86_64-softmmu/hw/i386/pci-assign-load-rom.o
  CC    aarch64-softmmu/hw/intc/exynos4210_combiner.o
  CC    aarch64-softmmu/hw/intc/omap_intc.o
  CC    aarch64-softmmu/hw/intc/bcm2835_ic.o
  CC    x86_64-softmmu/hw/i386/kvm/clock.o
  CC    x86_64-softmmu/hw/i386/kvm/apic.o
  CC    x86_64-softmmu/hw/i386/kvm/i8259.o
  CC    x86_64-softmmu/hw/i386/kvm/ioapic.o
  CC    x86_64-softmmu/hw/i386/kvm/i8254.o
  CC    x86_64-softmmu/hw/i386/kvm/pci-assign.o
  CC    aarch64-softmmu/hw/intc/bcm2836_control.o
  CC    x86_64-softmmu/target-i386/translate.o
  CC    x86_64-softmmu/target-i386/helper.o
/tmp/qemu-test/src/hw/i386/acpi-build.c: In function ‘build_append_pci_bus_devices’:
/tmp/qemu-test/src/hw/i386/acpi-build.c:471: warning: ‘notify_method’ may be used uninitialized in this function
  CC    x86_64-softmmu/target-i386/cpu.o
  CC    x86_64-softmmu/target-i386/bpt_helper.o
  CC    aarch64-softmmu/hw/intc/allwinner-a10-pic.o
  CC    x86_64-softmmu/target-i386/excp_helper.o
  CC    x86_64-softmmu/target-i386/fpu_helper.o
  CC    aarch64-softmmu/hw/intc/aspeed_vic.o
  CC    x86_64-softmmu/target-i386/cc_helper.o
  CC    aarch64-softmmu/hw/intc/arm_gicv3_cpuif.o
In file included from /tmp/qemu-test/src/target-i386/translate.c:148:
/tmp/qemu-test/src/translate-all_template.h:26: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:29: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:32: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:35: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:38: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:42: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:45: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:48: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h: In function ‘gen_intermediate_code’:
/tmp/qemu-test/src/translate-all_template.h:75: warning: implicit declaration of function ‘gen_intermediate_code_target_init_disas_context’
/tmp/qemu-test/src/translate-all_template.h:75: warning: nested extern declaration of ‘gen_intermediate_code_target_init_disas_context’
/tmp/qemu-test/src/translate-all_template.h:78: warning: implicit declaration of function ‘gen_intermediate_code_target_init_globals’
/tmp/qemu-test/src/translate-all_template.h:78: warning: nested extern declaration of ‘gen_intermediate_code_target_init_globals’
/tmp/qemu-test/src/translate-all_template.h:95: warning: implicit declaration of function ‘gen_intermediate_code_target_tb_start’
/tmp/qemu-test/src/translate-all_template.h:95: warning: nested extern declaration of ‘gen_intermediate_code_target_tb_start’
/tmp/qemu-test/src/translate-all_template.h:101: warning: implicit declaration of function ‘gen_intermediate_code_target_insn_start’
/tmp/qemu-test/src/translate-all_template.h:101: warning: nested extern declaration of ‘gen_intermediate_code_target_insn_start’
/tmp/qemu-test/src/translate-all_template.h:113: warning: implicit declaration of function ‘gen_intermediate_code_target_breakpoint_hit’
/tmp/qemu-test/src/translate-all_template.h:113: warning: nested extern declaration of ‘gen_intermediate_code_target_breakpoint_hit’
/tmp/qemu-test/src/translate-all_template.h:134: warning: implicit declaration of function ‘gen_intermediate_code_target_disas_insn’
/tmp/qemu-test/src/translate-all_template.h:134: warning: nested extern declaration of ‘gen_intermediate_code_target_disas_insn’
/tmp/qemu-test/src/translate-all_template.h:146: warning: implicit declaration of function ‘gen_intermediate_code_target_stop_check’
/tmp/qemu-test/src/translate-all_template.h:146: warning: nested extern declaration of ‘gen_intermediate_code_target_stop_check’
In file included from /tmp/qemu-test/src/target-i386/translate.c:148:
/tmp/qemu-test/src/translate-all_template.h:174: warning: implicit declaration of function ‘gen_intermediate_code_target_stop’
/tmp/qemu-test/src/translate-all_template.h:174: warning: nested extern declaration of ‘gen_intermediate_code_target_stop’
/tmp/qemu-test/src/target-i386/translate.c: At top level:
/tmp/qemu-test/src/target-i386/translate.c:4345: error: expected ‘;’, ‘,’ or ‘)’ before ‘s’
/tmp/qemu-test/src/target-i386/translate.c:8210: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/target-i386/translate.c:8266: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/target-i386/translate.c:8283: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/target-i386/translate.c:8288: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/target-i386/translate.c:8294: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/target-i386/translate.c:8313: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/target-i386/translate.c:8338: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
make[1]: *** [target-i386/translate.o] Error 1
make[1]: *** Waiting for unfinished jobs....
  CC    aarch64-softmmu/hw/misc/ivshmem.o
  CC    aarch64-softmmu/hw/misc/arm_sysctl.o
  CC    aarch64-softmmu/hw/misc/cbus.o
  CC    aarch64-softmmu/hw/misc/exynos4210_pmu.o
  CC    aarch64-softmmu/hw/misc/imx_ccm.o
  CC    aarch64-softmmu/hw/misc/imx31_ccm.o
  CC    aarch64-softmmu/hw/misc/imx25_ccm.o
  CC    aarch64-softmmu/hw/misc/imx6_ccm.o
  CC    aarch64-softmmu/hw/misc/imx6_src.o
  CC    aarch64-softmmu/hw/misc/mst_fpga.o
  CC    aarch64-softmmu/hw/misc/omap_clk.o
  CC    aarch64-softmmu/hw/misc/omap_gpmc.o
  CC    aarch64-softmmu/hw/misc/omap_l4.o
  CC    aarch64-softmmu/hw/misc/omap_sdrc.o
  CC    aarch64-softmmu/hw/misc/omap_tap.o
  CC    aarch64-softmmu/hw/misc/bcm2835_mbox.o
  CC    aarch64-softmmu/hw/misc/bcm2835_property.o
  CC    aarch64-softmmu/hw/misc/zynq_slcr.o
  CC    aarch64-softmmu/hw/misc/zynq-xadc.o
  CC    aarch64-softmmu/hw/misc/stm32f2xx_syscfg.o
  CC    aarch64-softmmu/hw/misc/edu.o
  CC    aarch64-softmmu/hw/misc/auxbus.o
  CC    aarch64-softmmu/hw/misc/aspeed_scu.o
  CC    aarch64-softmmu/hw/misc/aspeed_sdmc.o
  CC    aarch64-softmmu/hw/net/virtio-net.o
  CC    aarch64-softmmu/hw/net/vhost_net.o
  CC    aarch64-softmmu/hw/pcmcia/pxa2xx.o
  CC    aarch64-softmmu/hw/scsi/virtio-scsi.o
  CC    aarch64-softmmu/hw/scsi/virtio-scsi-dataplane.o
  CC    aarch64-softmmu/hw/scsi/vhost-scsi.o
  CC    aarch64-softmmu/hw/sd/omap_mmc.o
  CC    aarch64-softmmu/hw/sd/pxa2xx_mmci.o
  CC    aarch64-softmmu/hw/ssi/omap_spi.o
  CC    aarch64-softmmu/hw/ssi/imx_spi.o
  CC    aarch64-softmmu/hw/timer/exynos4210_mct.o
  CC    aarch64-softmmu/hw/timer/exynos4210_pwm.o
  CC    aarch64-softmmu/hw/timer/exynos4210_rtc.o
  CC    aarch64-softmmu/hw/timer/omap_gptimer.o
  CC    aarch64-softmmu/hw/timer/omap_synctimer.o
  CC    aarch64-softmmu/hw/timer/pxa2xx_timer.o
  CC    aarch64-softmmu/hw/timer/digic-timer.o
  CC    aarch64-softmmu/hw/timer/allwinner-a10-pit.o
  CC    aarch64-softmmu/hw/usb/tusb6010.o
  CC    aarch64-softmmu/hw/vfio/common.o
  CC    aarch64-softmmu/hw/vfio/pci.o
  CC    aarch64-softmmu/hw/vfio/pci-quirks.o
  CC    aarch64-softmmu/hw/vfio/platform.o
  CC    aarch64-softmmu/hw/vfio/calxeda-xgmac.o
  CC    aarch64-softmmu/hw/vfio/amd-xgbe.o
  CC    aarch64-softmmu/hw/vfio/spapr.o
  CC    aarch64-softmmu/hw/virtio/virtio.o
  CC    aarch64-softmmu/hw/virtio/virtio-balloon.o
make: *** [subdir-x86_64-softmmu] Error 2
make: *** Waiting for unfinished jobs....
  CC    aarch64-softmmu/hw/virtio/vhost.o
  CC    aarch64-softmmu/hw/virtio/vhost-backend.o
  CC    aarch64-softmmu/hw/virtio/vhost-user.o
  CC    aarch64-softmmu/hw/arm/boot.o
  CC    aarch64-softmmu/hw/arm/collie.o
  CC    aarch64-softmmu/hw/arm/exynos4_boards.o
  CC    aarch64-softmmu/hw/arm/gumstix.o
  CC    aarch64-softmmu/hw/arm/highbank.o
  CC    aarch64-softmmu/hw/arm/digic_boards.o
  CC    aarch64-softmmu/hw/arm/integratorcp.o
  CC    aarch64-softmmu/hw/arm/mainstone.o
  CC    aarch64-softmmu/hw/arm/musicpal.o
  CC    aarch64-softmmu/hw/arm/nseries.o
  CC    aarch64-softmmu/hw/arm/omap_sx1.o
  CC    aarch64-softmmu/hw/arm/palm.o
  CC    aarch64-softmmu/hw/arm/realview.o
  CC    aarch64-softmmu/hw/arm/spitz.o
  CC    aarch64-softmmu/hw/arm/stellaris.o
  CC    aarch64-softmmu/hw/arm/tosa.o
  CC    aarch64-softmmu/hw/arm/versatilepb.o
  CC    aarch64-softmmu/hw/arm/vexpress.o
  CC    aarch64-softmmu/hw/arm/virt.o
  CC    aarch64-softmmu/hw/arm/xilinx_zynq.o
  CC    aarch64-softmmu/hw/arm/z2.o
  CC    aarch64-softmmu/hw/arm/virt-acpi-build.o
  CC    aarch64-softmmu/hw/arm/netduino2.o
  CC    aarch64-softmmu/hw/arm/sysbus-fdt.o
  CC    aarch64-softmmu/hw/arm/armv7m.o
  CC    aarch64-softmmu/hw/arm/exynos4210.o
  CC    aarch64-softmmu/hw/arm/pxa2xx.o
  CC    aarch64-softmmu/hw/arm/pxa2xx_gpio.o
  CC    aarch64-softmmu/hw/arm/pxa2xx_pic.o
  CC    aarch64-softmmu/hw/arm/digic.o
  CC    aarch64-softmmu/hw/arm/omap1.o
  CC    aarch64-softmmu/hw/arm/omap2.o
  CC    aarch64-softmmu/hw/arm/strongarm.o
  CC    aarch64-softmmu/hw/arm/allwinner-a10.o
  CC    aarch64-softmmu/hw/arm/cubieboard.o
  CC    aarch64-softmmu/hw/arm/bcm2835_peripherals.o
  CC    aarch64-softmmu/hw/arm/bcm2836.o
  CC    aarch64-softmmu/hw/arm/raspi.o
  CC    aarch64-softmmu/hw/arm/stm32f205_soc.o
  CC    aarch64-softmmu/hw/arm/xlnx-zynqmp.o
  CC    aarch64-softmmu/hw/arm/xlnx-ep108.o
  CC    aarch64-softmmu/hw/arm/fsl-imx25.o
  CC    aarch64-softmmu/hw/arm/imx25_pdk.o
  CC    aarch64-softmmu/hw/arm/fsl-imx31.o
  CC    aarch64-softmmu/hw/arm/kzm.o
  CC    aarch64-softmmu/hw/arm/fsl-imx6.o
  CC    aarch64-softmmu/hw/arm/sabrelite.o
  CC    aarch64-softmmu/hw/arm/ast2400.o
  CC    aarch64-softmmu/hw/arm/palmetto-bmc.o
  CC    aarch64-softmmu/target-arm/arm-semi.o
  CC    aarch64-softmmu/target-arm/machine.o
  CC    aarch64-softmmu/target-arm/psci.o
  CC    aarch64-softmmu/target-arm/arch_dump.o
  CC    aarch64-softmmu/target-arm/monitor.o
  CC    aarch64-softmmu/target-arm/kvm-stub.o
  CC    aarch64-softmmu/target-arm/translate.o
  CC    aarch64-softmmu/target-arm/op_helper.o
  CC    aarch64-softmmu/target-arm/helper.o
  CC    aarch64-softmmu/target-arm/cpu.o
  CC    aarch64-softmmu/target-arm/neon_helper.o
  CC    aarch64-softmmu/target-arm/iwmmxt_helper.o
  CC    aarch64-softmmu/target-arm/gdbstub.o
  CC    aarch64-softmmu/target-arm/cpu64.o
In file included from /tmp/qemu-test/src/target-arm/translate.c:11707:
/tmp/qemu-test/src/translate-all_template.h:26: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:29: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:32: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:35: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:38: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:42: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:45: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h:48: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/translate-all_template.h: In function ‘gen_intermediate_code_arm’:
/tmp/qemu-test/src/translate-all_template.h:75: warning: implicit declaration of function ‘gen_intermediate_code_target_init_disas_context’
/tmp/qemu-test/src/translate-all_template.h:75: warning: nested extern declaration of ‘gen_intermediate_code_target_init_disas_context’
/tmp/qemu-test/src/translate-all_template.h:78: warning: implicit declaration of function ‘gen_intermediate_code_target_init_globals’
/tmp/qemu-test/src/translate-all_template.h:78: warning: nested extern declaration of ‘gen_intermediate_code_target_init_globals’
/tmp/qemu-test/src/translate-all_template.h:95: warning: implicit declaration of function ‘gen_intermediate_code_target_tb_start’
/tmp/qemu-test/src/translate-all_template.h:95: warning: nested extern declaration of ‘gen_intermediate_code_target_tb_start’
/tmp/qemu-test/src/translate-all_template.h:101: warning: implicit declaration of function ‘gen_intermediate_code_target_insn_start’
/tmp/qemu-test/src/translate-all_template.h:101: warning: nested extern declaration of ‘gen_intermediate_code_target_insn_start’
/tmp/qemu-test/src/translate-all_template.h:113: warning: implicit declaration of function ‘gen_intermediate_code_target_breakpoint_hit’
/tmp/qemu-test/src/translate-all_template.h:113: warning: nested extern declaration of ‘gen_intermediate_code_target_breakpoint_hit’
/tmp/qemu-test/src/translate-all_template.h:134: warning: implicit declaration of function ‘gen_intermediate_code_target_disas_insn’
/tmp/qemu-test/src/translate-all_template.h:134: warning: nested extern declaration of ‘gen_intermediate_code_target_disas_insn’
/tmp/qemu-test/src/translate-all_template.h:146: warning: implicit declaration of function ‘gen_intermediate_code_target_stop_check’
/tmp/qemu-test/src/translate-all_template.h:146: warning: nested extern declaration of ‘gen_intermediate_code_target_stop_check’
In file included from /tmp/qemu-test/src/target-arm/translate.c:11707:
/tmp/qemu-test/src/translate-all_template.h:174: warning: implicit declaration of function ‘gen_intermediate_code_target_stop’
/tmp/qemu-test/src/translate-all_template.h:174: warning: nested extern declaration of ‘gen_intermediate_code_target_stop’
/tmp/qemu-test/src/target-arm/translate.c: At top level:
/tmp/qemu-test/src/target-arm/translate.c:11725: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/target-arm/translate.c:11779: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/target-arm/translate.c:11792: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/target-arm/translate.c:11836: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/target-arm/translate.c:11862: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/target-arm/translate.c:11887: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/target-arm/translate.c:11932: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
/tmp/qemu-test/src/target-arm/translate.c:11963: error: expected ‘;’, ‘,’ or ‘)’ before ‘dc’
make[1]: *** [target-arm/translate.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [subdir-aarch64-softmmu] Error 2
tests/docker/Makefile.include:107: recipe for target 'docker-run-test-quick@centos6' failed
make: *** [docker-run-test-quick@centos6] Error 1
=== OUTPUT END ===

Test command exited with code: 2


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

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

* Re: [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework
  2016-09-09 13:03 [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework Lluís Vilanova
                   ` (6 preceding siblings ...)
  2016-09-12  3:56 ` [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic " no-reply
@ 2016-09-12  5:05 ` no-reply
  2016-09-13 16:09 ` Lluís Vilanova
  2016-09-26 16:23 ` Lluís Vilanova
  9 siblings, 0 replies; 15+ messages in thread
From: no-reply @ 2016-09-12  5:05 UTC (permalink / raw)
  To: vilanova; +Cc: famz, qemu-devel, pbonzini, crosthwaite.peter, rth

Hi,

Your series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 147342618684.13303.1583142856242164602.stgit@fimbulvetr.bsc.es
Subject: [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git show --no-patch --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
ec3c1db target: [tcg, arm] Port to generic translation framework
19005fc target: [tcg, i386] Port to generic translation framework
e068b67 target: [tcg] Redefine DISAS_* onto the generic translation framework (DJ_*)
003b3c3 target: [tcg] Add generic translation framework
8b3b57a queue: Add macro for incremental traversal
216c91c Pass generic CPUState to gen_intermediate_code()

=== OUTPUT BEGIN ===
Checking PATCH 1/6: Pass generic CPUState to gen_intermediate_code()...
ERROR: "foo * bar" should be "foo *bar"
#840: FILE: target-sh4/translate.c:1832:
+    CPUSH4State * env = cpu->env_ptr;

ERROR: "foo * bar" should be "foo *bar"
#902: FILE: target-sparc/translate.c:5569:
+    CPUSPARCState * env = cpu->env_ptr;

total: 2 errors, 0 warnings, 937 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 2/6: queue: Add macro for incremental traversal...
Checking PATCH 3/6: target: [tcg] Add generic translation framework...
ERROR: open brace '{' following enum go on the same line
#64: FILE: include/exec/translate-all_template.h:34:
+typedef enum BreakpointHitType
+{

ERROR: open brace '{' following enum go on the same line
#79: FILE: include/exec/translate-all_template.h:49:
+typedef enum DisasJumpType
+{

ERROR: open brace '{' following struct go on the same line
#97: FILE: include/exec/translate-all_template.h:67:
+typedef struct DisasContextBase
+{

ERROR: line over 90 characters
#116: FILE: include/qom/cpu.h:852:
+static inline CPUBreakpoint *cpu_breakpoint_get(CPUState *cpu, vaddr pc, CPUBreakpoint *bp)

ERROR: "foo * bar" should be "foo *bar"
#170: FILE: translate-all_template.h:26:
+    DisasContext * restrict dc, CPUArchState * restrict env);

ERROR: "foo * bar" should be "foo *bar"
#173: FILE: translate-all_template.h:29:
+    DisasContext * restrict dc, CPUArchState * restrict env);

ERROR: "foo * bar" should be "foo *bar"
#176: FILE: translate-all_template.h:32:
+    DisasContext * restrict dc, CPUArchState * restrict env);

ERROR: "foo * bar" should be "foo *bar"
#179: FILE: translate-all_template.h:35:
+    DisasContext * restrict dc, CPUArchState * restrict env);

ERROR: "foo * bar" should be "foo *bar"
#182: FILE: translate-all_template.h:38:
+    DisasContext * restrict dc, CPUArchState * restrict env,

ERROR: "foo * bar" should be "foo *bar"
#183: FILE: translate-all_template.h:39:
+    const CPUBreakpoint * restrict bp);

ERROR: "foo * bar" should be "foo *bar"
#186: FILE: translate-all_template.h:42:
+    DisasContext * restrict dc, CPUArchState * restrict env);

ERROR: "foo * bar" should be "foo *bar"
#189: FILE: translate-all_template.h:45:
+    DisasContext * restrict dc, CPUArchState * restrict env);

ERROR: "foo * bar" should be "foo *bar"
#192: FILE: translate-all_template.h:48:
+    DisasContext * restrict dc, CPUArchState * restrict env);

ERROR: line over 90 characters
#257: FILE: translate-all_template.h:113:
+                BreakpointHitType bh = gen_intermediate_code_target_breakpoint_hit(dc, env, bp);

WARNING: line over 80 characters
#334: FILE: translate-all_template.h:190:
+        log_target_disas(cpu, dc->base.pc_first, dc->base.pc_next - dc->base.pc_first,

total: 14 errors, 1 warnings, 311 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 4/6: target: [tcg] Redefine DISAS_* onto the generic translation framework (DJ_*)...
ERROR: spaces required around that '+' (ctx:VxV)
#31: FILE: include/exec/exec-all.h:42:
+#define DISAS_JUMP    (DJ_TARGET+0)     /* only pc was modified dynamically */
                                 ^

ERROR: spaces required around that '+' (ctx:VxV)
#32: FILE: include/exec/exec-all.h:43:
+#define DISAS_UPDATE  (DJ_TARGET+1)     /* cpu state was modified dynamically */
                                 ^

ERROR: spaces required around that '+' (ctx:VxV)
#33: FILE: include/exec/exec-all.h:44:
+#define DISAS_TB_JUMP (DJ_TARGET+2)     /* only pc was modified statically */
                                 ^

ERROR: spaces required around that '+' (ctx:VxV)
#34: FILE: include/exec/exec-all.h:45:
+#define DISAS_TARGET  (DJ_TARGET+3)     /* base for target-specific values */
                                 ^

ERROR: Macros with complex values should be enclosed in parenthesis
#53: FILE: target-arm/translate.h:115:
+#define DISAS_WFI DISAS_TARGET + 0

ERROR: Macros with complex values should be enclosed in parenthesis
#54: FILE: target-arm/translate.h:116:
+#define DISAS_SWI DISAS_TARGET + 1

ERROR: Macros with complex values should be enclosed in parenthesis
#59: FILE: target-arm/translate.h:120:
+#define DISAS_EXC DISAS_TARGET + 2

ERROR: Macros with complex values should be enclosed in parenthesis
#65: FILE: target-arm/translate.h:122:
+#define DISAS_WFE DISAS_TARGET + 3

ERROR: Macros with complex values should be enclosed in parenthesis
#66: FILE: target-arm/translate.h:123:
+#define DISAS_HVC DISAS_TARGET + 4

ERROR: Macros with complex values should be enclosed in parenthesis
#67: FILE: target-arm/translate.h:124:
+#define DISAS_SMC DISAS_TARGET + 5

ERROR: Macros with complex values should be enclosed in parenthesis
#68: FILE: target-arm/translate.h:125:
+#define DISAS_YIELD DISAS_TARGET + 6

ERROR: Macros with complex values should be enclosed in parenthesis
#82: FILE: target-cris/translate.c:54:
+#define DISAS_SWI DISAS_TARGET + 0

ERROR: Macros with complex values should be enclosed in parenthesis
#96: FILE: target-m68k/translate.c:145:
+#define DISAS_JUMP_NEXT DISAS_TARGET + 0

ERROR: Macros with complex values should be enclosed in parenthesis
#110: FILE: target-s390x/translate.c:78:
+#define DISAS_EXCP DISAS_TARGET + 0

ERROR: Macros with complex values should be enclosed in parenthesis
#126: FILE: target-unicore32/translate.c:51:
+#define DISAS_SYSCALL DISAS_TARGET + 0

total: 15 errors, 0 warnings, 84 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 5/6: target: [tcg, i386] Port to generic translation framework...
ERROR: spaces required around that '+' (ctx:VxV)
#21: FILE: target-i386/translate.c:73:
+#define DJ_JUMP (DJ_TARGET+0)           /* end of block due to call/jump */
                           ^

ERROR: spaces required around that '+' (ctx:VxV)
#22: FILE: target-i386/translate.c:74:
+#define DJ_MISC (DJ_TARGET+1)           /* some other reason */
                           ^

ERROR: open brace '{' following struct go on the same line
#34: FILE: target-i386/translate.c:103:
+typedef struct DisasContext
+{

ERROR: "foo * bar" should be "foo *bar"
#214: FILE: target-i386/translate.c:4345:
+    DisasContext * restrict s, CPUX86State * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#432: FILE: target-i386/translate.c:8210:
+    DisasContext * restrict dc, CPUX86State * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#482: FILE: target-i386/translate.c:8266:
+    DisasContext * restrict dc, CPUX86State * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#504: FILE: target-i386/translate.c:8283:
+    DisasContext * restrict dc, CPUX86State * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#529: FILE: target-i386/translate.c:8288:
+    DisasContext * restrict dc, CPUX86State * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#577: FILE: target-i386/translate.c:8294:
+    DisasContext * restrict dc, CPUX86State * restrict env,

ERROR: "foo * bar" should be "foo *bar"
#578: FILE: target-i386/translate.c:8295:
+    const CPUBreakpoint * restrict bp)

ERROR: "foo * bar" should be "foo *bar"
#615: FILE: target-i386/translate.c:8313:
+    DisasContext * restrict dc, CPUX86State * restrict env)

WARNING: line over 80 characters
#630: FILE: target-i386/translate.c:8328:
+               != ((dc->base.pc_next + TARGET_MAX_INSN_SIZE - 1) & TARGET_PAGE_MASK)) {

ERROR: "foo * bar" should be "foo *bar"
#643: FILE: target-i386/translate.c:8338:
+    DisasContext * restrict dc, CPUX86State * restrict env)

total: 12 errors, 1 warnings, 616 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 6/6: target: [tcg, arm] Port to generic translation framework...
WARNING: line over 80 characters
#52: FILE: target-arm/translate-a64.c:274:
+    if (s->base.singlestep_enabled || s->ss_active || (s->base.tb->cflags & CF_LAST_IO)) {

WARNING: line over 80 characters
#94: FILE: target-arm/translate-a64.c:337:
+                      __FILE__, __LINE__, insn, s->base.pc_next - 4);              \

ERROR: externs should be avoided in .c files
#316: FILE: target-arm/translate-a64.c:11079:
+void disas_a64_insn(CPUARMState *env, DisasContext *s);

ERROR: "foo * bar" should be "foo *bar"
#355: FILE: target-arm/translate-a64.c:11131:
+    DisasContext * restrict dc, CPUArchState * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#442: FILE: target-arm/translate-a64.c:11184:
+    DisasContext * restrict dc, CPUArchState * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#450: FILE: target-arm/translate-a64.c:11189:
+    DisasContext * restrict dc, CPUArchState * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#472: FILE: target-arm/translate-a64.c:11194:
+    DisasContext * restrict dc, CPUArchState * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#479: FILE: target-arm/translate-a64.c:11201:
+    DisasContext * restrict dc, CPUArchState * restrict env,

ERROR: "foo * bar" should be "foo *bar"
#480: FILE: target-arm/translate-a64.c:11202:
+    const CPUBreakpoint * restrict bp)

ERROR: "foo * bar" should be "foo *bar"
#501: FILE: target-arm/translate-a64.c:11223:
+    DisasContext * restrict dc, CPUArchState * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#544: FILE: target-arm/translate-a64.c:11247:
+    DisasContext * restrict dc, CPUArchState * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#561: FILE: target-arm/translate-a64.c:11262:
+    DisasContext * restrict dc, CPUArchState * restrict env)

WARNING: line over 80 characters
#807: FILE: target-arm/translate.c:4058:
+           ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);

ERROR: spaces required around that '=' (ctx:VxV)
#1292: FILE: target-arm/translate.c:11645:
+    for(i=0;i<16;i++) {
          ^

ERROR: space required after that ';' (ctx:VxV)
#1292: FILE: target-arm/translate.c:11645:
+    for(i=0;i<16;i++) {
            ^

ERROR: spaces required around that '<' (ctx:VxV)
#1292: FILE: target-arm/translate.c:11645:
+    for(i=0;i<16;i++) {
              ^

ERROR: space required after that ';' (ctx:VxV)
#1292: FILE: target-arm/translate.c:11645:
+    for(i=0;i<16;i++) {
                 ^

ERROR: space required before the open parenthesis '('
#1292: FILE: target-arm/translate.c:11645:
+    for(i=0;i<16;i++) {

ERROR: braces {} are necessary for all arms of this statement
#1294: FILE: target-arm/translate.c:11647:
+        if ((i % 4) == 3)
[...]
+        else
[...]

ERROR: "foo * bar" should be "foo *bar"
#1376: FILE: target-arm/translate.c:11725:
+    DisasContext * restrict dc, CPUARMState * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#1436: FILE: target-arm/translate.c:11779:
+    DisasContext * restrict dc, CPUARMState * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#1461: FILE: target-arm/translate.c:11792:
+    DisasContext * restrict dc, CPUARMState * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#1492: FILE: target-arm/translate.c:11836:
+    DisasContext * restrict dc, CPUARMState * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#1580: FILE: target-arm/translate.c:11862:
+    DisasContext * restrict dc, CPUARMState * restrict env,

ERROR: "foo * bar" should be "foo *bar"
#1581: FILE: target-arm/translate.c:11863:
+    const CPUBreakpoint * restrict bp)

ERROR: "foo * bar" should be "foo *bar"
#1605: FILE: target-arm/translate.c:11887:
+    DisasContext * restrict dc, CPUArchState * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#1675: FILE: target-arm/translate.c:11932:
+    DisasContext * restrict dc, CPUARMState * restrict env)

ERROR: "foo * bar" should be "foo *bar"
#1712: FILE: target-arm/translate.c:11963:
+    DisasContext * restrict dc, CPUARMState * restrict env)

ERROR: space required before the open parenthesis '('
#1744: FILE: target-arm/translate.c:11985:
+        switch(jt) {

ERROR: spaces required around that '+' (ctx:VxV)
#1988: FILE: target-arm/translate.h:113:
+#define DJ_JUMP    (DJ_TARGET+0)
                              ^

ERROR: spaces required around that '+' (ctx:VxV)
#1989: FILE: target-arm/translate.h:114:
+#define DJ_UPDATE  (DJ_TARGET+1)
                              ^

ERROR: spaces required around that '+' (ctx:VxV)
#1990: FILE: target-arm/translate.h:115:
+#define DJ_TB_JUMP (DJ_TARGET+2)
                              ^

ERROR: spaces required around that '+' (ctx:VxV)
#1997: FILE: target-arm/translate.h:120:
+#define DJ_WFI     (DJ_TARGET+3)
                              ^

ERROR: spaces required around that '+' (ctx:VxV)
#1998: FILE: target-arm/translate.h:121:
+#define DJ_SWI     (DJ_TARGET+4)
                              ^

ERROR: spaces required around that '+' (ctx:VxV)
#2003: FILE: target-arm/translate.h:125:
+#define DJ_EXC     (DJ_TARGET+5)
                              ^

ERROR: spaces required around that '+' (ctx:VxV)
#2009: FILE: target-arm/translate.h:127:
+#define DJ_WFE     (DJ_TARGET+6)
                              ^

ERROR: spaces required around that '+' (ctx:VxV)
#2010: FILE: target-arm/translate.h:128:
+#define DJ_HVC     (DJ_TARGET+7)
                              ^

ERROR: spaces required around that '+' (ctx:VxV)
#2011: FILE: target-arm/translate.h:129:
+#define DJ_SMC     (DJ_TARGET+8)
                              ^

ERROR: spaces required around that '+' (ctx:VxV)
#2012: FILE: target-arm/translate.h:130:
+#define DJ_YIELD   (DJ_TARGET+9)
                              ^

ERROR: spaces required around that '+' (ctx:VxV)
#2013: FILE: target-arm/translate.h:131:
+#define DJ_SS      (DJ_TARGET+10)
                              ^

ERROR: spaces required around that '+' (ctx:VxV)
#2014: FILE: target-arm/translate.h:132:
+#define DJ_PAGE_CROSS (DJ_TARGET+11)
                                 ^

ERROR: spaces required around that '+' (ctx:VxV)
#2015: FILE: target-arm/translate.h:133:
+#define DJ_SKIP    (DJ_TARGET+12)
                              ^

total: 39 errors, 3 warnings, 1920 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

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

* Re: [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework
  2016-09-09 13:03 [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework Lluís Vilanova
                   ` (7 preceding siblings ...)
  2016-09-12  5:05 ` no-reply
@ 2016-09-13 16:09 ` Lluís Vilanova
  2016-09-26 16:23 ` Lluís Vilanova
  9 siblings, 0 replies; 15+ messages in thread
From: Lluís Vilanova @ 2016-09-13 16:09 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Peter Crosthwaite, Richard Henderson, Stefan Hajnoczi

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.

I should have changed the series cover (not just the changelog) to say ARM and
AARCH64 are also ported.

Even if useful in itself (it uncovered TCG register leaks in i386), this is also
a stepping stone to a later series that adds guest BBL and instruction traces.


Cheers,
  Lluis

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

* Re: [Qemu-devel] [PATCH v2 1/6] Pass generic CPUState to gen_intermediate_code()
  2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 1/6] Pass generic CPUState to gen_intermediate_code() Lluís Vilanova
@ 2016-09-16 23:01   ` Richard Henderson
  2016-09-19 12:14     ` Lluís Vilanova
  0 siblings, 1 reply; 15+ messages in thread
From: Richard Henderson @ 2016-09-16 23:01 UTC (permalink / raw)
  To: Lluís Vilanova, qemu-devel
  Cc: Peter Maydell, Guan Xuetao, Eduardo Habkost, Peter Crosthwaite,
	Jia Liu, Anthony Green, Mark Cave-Ayland, Alexander Graf,
	Bastian Koppelmann, Max Filippov, Michael Walle, open list:ARM,
	open list:PowerPC, Artyom Tarasenko, Edgar E. Iglesias,
	Paolo Bonzini, David Gibson, Leon Alrae, Aurelien Jarno

On 09/09/2016 06:03 AM, Lluís Vilanova wrote:
> -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;

Why the variable renames?  I.e. why CPUState *cpu instead of CPUState *cs?


r~

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

* Re: [Qemu-devel] [PATCH v2 1/6] Pass generic CPUState to gen_intermediate_code()
  2016-09-16 23:01   ` Richard Henderson
@ 2016-09-19 12:14     ` Lluís Vilanova
  0 siblings, 0 replies; 15+ messages in thread
From: Lluís Vilanova @ 2016-09-19 12:14 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel, Peter Maydell, Eduardo Habkost, Peter Crosthwaite,
	Bastian Koppelmann, Anthony Green, Mark Cave-Ayland,
	Alexander Graf, Max Filippov, Michael Walle, open list:ARM,
	open list:PowerPC, Aurelien Jarno, David Gibson, Paolo Bonzini,
	Edgar E. Iglesias, Guan Xuetao, Leon Alrae, Artyom Tarasenko,
	Jia Liu

Richard Henderson writes:

> On 09/09/2016 06:03 AM, Lluís Vilanova wrote:
>> -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;

> Why the variable renames?  I.e. why CPUState *cpu instead of CPUState *cs?

It's the naming convention used on almost all other generic code in QEMU.

Cheers,
  Lluis

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

* Re: [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework
  2016-09-09 13:03 [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework Lluís Vilanova
                   ` (8 preceding siblings ...)
  2016-09-13 16:09 ` Lluís Vilanova
@ 2016-09-26 16:23 ` Lluís Vilanova
  2017-01-27 17:12   ` Alex Bennée
  9 siblings, 1 reply; 15+ messages in thread
From: Lluís Vilanova @ 2016-09-26 16:23 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.

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

> Changes in v2
> =============

> * Port ARM and AARCH64 targets.
> * Fold single-stepping checks into "max_insns" [Richard Henderson].
> * Move instruction start marks to target code [Richard Henderson].
> * Add target hook for TB start.
> * Check for TCG temporary leaks.
> * Move instruction disassembly into a target hook.
> * Make breakpoint_hit() return an enum to accomodate target's needs (ARM).
[...]

I'm not sure if I CC'd the appropriate people, but I'd like to know if this
seems like the proper approach to generalizing the main disassembly loop.

Every time someone updates a target it becomes a little cumbersome to keep this
type of patches in synch (for now, only in i386 and arm).


Thanks,
  Lluis

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

* Re: [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework
  2016-09-26 16:23 ` Lluís Vilanova
@ 2017-01-27 17:12   ` Alex Bennée
  2017-01-29 12:27     ` Lluís Vilanova
  0 siblings, 1 reply; 15+ messages in thread
From: Alex Bennée @ 2017-01-27 17:12 UTC (permalink / raw)
  To: Lluís Vilanova
  Cc: qemu-devel, Paolo Bonzini, Richard Henderson, Peter Crosthwaite


Lluís Vilanova <vilanova@ac.upc.edu> writes:

> 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.
>
>> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
>> ---
>
>> Changes in v2
>> =============
>
>> * Port ARM and AARCH64 targets.
>> * Fold single-stepping checks into "max_insns" [Richard Henderson].
>> * Move instruction start marks to target code [Richard Henderson].
>> * Add target hook for TB start.
>> * Check for TCG temporary leaks.
>> * Move instruction disassembly into a target hook.
>> * Make breakpoint_hit() return an enum to accomodate target's needs (ARM).
> [...]
>
> I'm not sure if I CC'd the appropriate people, but I'd like to know if this
> seems like the proper approach to generalizing the main disassembly
> loop.
>
> Every time someone updates a target it becomes a little cumbersome to keep this
> type of patches in synch (for now, only in i386 and arm).

I'm sorry this has been in my review queue so long that it no longer
applies cleanly. However feel free to add me on the next iteration.

My only general comment is I think there is a bit too much churn in the
per-arch changes from re-names that aren't really needed. Aside from
that it would be useful to have an example of something that can be done
more easily in the generic run-loop as part of the series. Otherwise I
find the churn hard to justify.

>
>
> Thanks,
>   Lluis


--
Alex Bennée

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

* Re: [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework
  2017-01-27 17:12   ` Alex Bennée
@ 2017-01-29 12:27     ` Lluís Vilanova
  0 siblings, 0 replies; 15+ messages in thread
From: Lluís Vilanova @ 2017-01-29 12:27 UTC (permalink / raw)
  To: Alex Bennée
  Cc: Paolo Bonzini, Peter Crosthwaite, qemu-devel, Richard Henderson

Alex Bennée writes:

> Lluís Vilanova <vilanova@ac.upc.edu> writes:

>> 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.
>> 
>>> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
>>> ---
>> 
>>> Changes in v2
>>> =============
>> 
>>> * Port ARM and AARCH64 targets.
>>> * Fold single-stepping checks into "max_insns" [Richard Henderson].
>>> * Move instruction start marks to target code [Richard Henderson].
>>> * Add target hook for TB start.
>>> * Check for TCG temporary leaks.
>>> * Move instruction disassembly into a target hook.
>>> * Make breakpoint_hit() return an enum to accomodate target's needs (ARM).
>> [...]
>> 
>> I'm not sure if I CC'd the appropriate people, but I'd like to know if this
>> seems like the proper approach to generalizing the main disassembly
>> loop.
>> 
>> Every time someone updates a target it becomes a little cumbersome to keep this
>> type of patches in synch (for now, only in i386 and arm).

> I'm sorry this has been in my review queue so long that it no longer
> applies cleanly. However feel free to add me on the next iteration.

Will do.


> My only general comment is I think there is a bit too much churn in the
> per-arch changes from re-names that aren't really needed. Aside from
> that it would be useful to have an example of something that can be done
> more easily in the generic run-loop as part of the series. Otherwise I
> find the churn hard to justify.

For one, it's easier to keep all main loops in synch. I've found in previous
versions that some main loops perform some of the operations in a different
order (like the order between gen_io_start() and breakpoint checks; might be
synced now, I haven't checked again).

The most prominent example I have is a later series adding support to trace what
code the guest executes on all targets (raising an event before and another
after each instruction/bbl).


Cheers,
  Lluis

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

end of thread, other threads:[~2017-01-29 12:27 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-09 13:03 [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic translation framework Lluís Vilanova
2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 1/6] Pass generic CPUState to gen_intermediate_code() Lluís Vilanova
2016-09-16 23:01   ` Richard Henderson
2016-09-19 12:14     ` Lluís Vilanova
2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 2/6] queue: Add macro for incremental traversal Lluís Vilanova
2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 3/6] target: [tcg] Add generic translation framework Lluís Vilanova
2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 4/6] target: [tcg] Redefine DISAS_* onto the generic translation framework (DJ_*) Lluís Vilanova
2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 5/6] target: [tcg, i386] Port to generic translation framework Lluís Vilanova
2016-09-09 13:03 ` [Qemu-devel] [PATCH v2 6/6] target: [tcg, arm] " Lluís Vilanova
2016-09-12  3:56 ` [Qemu-devel] [RFC PATCH v2 0/6] translate: [tcg] Generic " no-reply
2016-09-12  5:05 ` no-reply
2016-09-13 16:09 ` Lluís Vilanova
2016-09-26 16:23 ` Lluís Vilanova
2017-01-27 17:12   ` Alex Bennée
2017-01-29 12:27     ` 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.