qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-arm] [PATCH v9 26/26] target: [tcg, arm] Port to generic translati


From: Lluís Vilanova
Subject: [Qemu-arm] [PATCH v9 26/26] target: [tcg, arm] Port to generic translation framework
Date: Sun, 25 Jun 2017 13:28:39 +0300
User-agent: StGit/0.17.1-dirty

Signed-off-by: Lluís Vilanova <address@hidden>
---
 target/arm/translate-a64.c |  110 ++++++-------------------------------------
 target/arm/translate.c     |  112 +++++++-------------------------------------
 target/arm/translate.h     |    6 +-
 3 files changed, 36 insertions(+), 192 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 97e8bda230..59c5d58dd1 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11387,6 +11387,9 @@ static void aarch64_trblock_tb_stop(DisasContextBase 
*db, CPUState *cpu)
             break;
         }
     }
+
+    /* Functions above can change dc->pc, so re-align db->pc_next */
+    db->pc_next = dc->pc;
 }
 
 static int aarch64_trblock_disas_flags(const DisasContextBase *db)
@@ -11396,102 +11399,17 @@ static int aarch64_trblock_disas_flags(const 
DisasContextBase *db)
     return 4 | (bswap_code(dc->sctlr_b) ? 2 : 0);
 }
 
-void gen_intermediate_code_a64(DisasContextBase *db, ARMCPU *cpu,
+static TranslatorOps aarch64_translator_ops = {
+    .init_disas_context = aarch64_trblock_init_disas_context,
+    .insn_start = aarch64_trblock_insn_start,
+    .breakpoint_check = aarch64_trblock_breakpoint_check,
+    .disas_insn = aarch64_trblock_disas_insn,
+    .tb_stop = aarch64_trblock_tb_stop,
+    .disas_flags = aarch64_trblock_disas_flags,
+};
+
+void gen_intermediate_code_a64(DisasContextBase *db, CPUState *cpu,
                                TranslationBlock *tb)
 {
-    CPUState *cs = CPU(cpu);
-    DisasContext *dc = container_of(db, DisasContext, base);
-    int max_insns;
-    CPUBreakpoint *bp;
-
-    db->tb = tb;
-    db->pc_first = tb->pc;
-    db->pc_next = db->pc_first;
-    db->is_jmp = DISAS_NEXT;
-    db->num_insns = 0;
-    db->singlestep_enabled = cs->singlestep_enabled;
-    aarch64_trblock_init_disas_context(db, cs);
-
-    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, cpu_env);
-
-    tcg_clear_temp_count();
-
-    do {
-        db->num_insns++;
-        aarch64_trblock_insn_start(db, cs);
-
-        bp = NULL;
-        do {
-            bp = cpu_breakpoint_get(cs, db->pc_next, bp);
-            if (unlikely(bp)) {
-                BreakpointCheckType bp_check =
-                    aarch64_trblock_breakpoint_check(db, cs, bp);
-                if (bp_check == BC_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 {
-                    goto done_generating;
-                }
-            }
-        } while (bp != NULL);
-
-        if (db->num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
-            gen_io_start(cpu_env);
-        }
-
-        db->pc_next = aarch64_trblock_disas_insn(db, cs);
-
-        if (tcg_check_temp_count()) {
-            fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
-                    dc->pc);
-        }
-
-        if (!db->is_jmp && (tcg_op_buf_full() || cs->singlestep_enabled ||
-                            singlestep || db->num_insns >= max_insns)) {
-            db->is_jmp = DJ_TOO_MANY;
-        }
-
-        /* 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 (!db->is_jmp);
-
-    aarch64_trblock_tb_stop(db, cs);
-
-    if (tb->cflags & CF_LAST_IO) {
-        gen_io_end(cpu_env);
-    }
-
-done_generating:
-    gen_tb_end(tb, db->num_insns);
-
-#ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
-        qemu_log_in_addr_range(db->pc_first)) {
-        int disas_flags = aarch64_trblock_disas_flags(db);
-        qemu_log_lock();
-        qemu_log("----------------\n");
-        qemu_log("IN: %s\n", lookup_symbol(db->pc_first));
-        log_target_disas(cs, db->pc_first, dc->pc - db->pc_first,
-                         disas_flags);
-        qemu_log("\n");
-        qemu_log_unlock();
-    }
-#endif
-    tb->size = dc->pc - db->pc_first;
-    tb->icount = db->num_insns;
+    translate_block(&aarch64_translator_ops, db, cpu, &cpu_env, tb);
 }
diff --git a/target/arm/translate.c b/target/arm/translate.c
index d87328602a..d9a7d870cb 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -12177,6 +12177,9 @@ static void arm_trblock_tb_stop(DisasContextBase *db, 
CPUState *cpu)
             gen_goto_tb(dc, 1, dc->pc);
         }
     }
+
+    /* Functions above can change dc->pc, so re-align db->pc_next */
+    db->pc_next = dc->pc;
 }
 
 static int arm_trblock_disas_flags(const DisasContextBase *db)
@@ -12186,15 +12189,24 @@ static int arm_trblock_disas_flags(const 
DisasContextBase *db)
     return dc->thumb | (dc->sctlr_b << 1);
 }
 
+static TranslatorOps arm_translator_ops = {
+    .init_disas_context = arm_trblock_init_disas_context,
+    .init_globals = arm_trblock_init_globals,
+    .tb_start = arm_trblock_tb_start,
+    .insn_start = arm_trblock_insn_start,
+    .breakpoint_check = arm_trblock_breakpoint_check,
+    .disas_insn = arm_trblock_disas_insn,
+    .tb_stop = arm_trblock_tb_stop,
+    .disas_flags = arm_trblock_disas_flags,
+};
+
+#include "qemu/error-report.h"
+
 /* 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;
     DisasContextBase *db = &dc->base;
-    int max_insns;
-    CPUBreakpoint *bp;
 
     /* generate intermediate code */
 
@@ -12202,97 +12214,11 @@ void gen_intermediate_code(CPUState *cpu, 
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(db, arm_cpu, tb);
+        gen_intermediate_code_a64(db, cpu, tb);
         return;
+    } else {
+        translate_block(&arm_translator_ops, db, cpu, &cpu_env, tb);
     }
-
-    db->tb = tb;
-    db->pc_first = tb->pc;
-    db->pc_next = db->pc_first;
-    db->is_jmp = DISAS_NEXT;
-    db->num_insns = 0;
-    db->singlestep_enabled = cpu->singlestep_enabled;
-    arm_trblock_init_disas_context(db, cpu);
-
-
-    arm_trblock_init_globals(db, cpu);
-    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, cpu_env);
-
-    tcg_clear_temp_count();
-    arm_trblock_tb_start(db, cpu);
-
-    do {
-        db->num_insns++;
-        arm_trblock_insn_start(db, cpu);
-
-        bp = NULL;
-        do {
-            bp = cpu_breakpoint_get(cpu, db->pc_next, bp);
-            if (unlikely(bp)) {
-                BreakpointCheckType bp_check = arm_trblock_breakpoint_check(
-                    db, cpu, bp);
-                if (bp_check == BC_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 {
-                    goto done_generating;
-                }
-            }
-        } while (bp != NULL);
-
-        if (db->num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
-            gen_io_start(cpu_env);
-        }
-
-        db->pc_next = arm_trblock_disas_insn(db, cpu);
-
-        if (tcg_check_temp_count()) {
-            fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
-                    dc->pc);
-        }
-
-        if (!db->is_jmp && (tcg_op_buf_full() || singlestep ||
-                            db->num_insns >= max_insns)) {
-            db->is_jmp = DJ_TOO_MANY;
-        }
-    } while (!db->is_jmp);
-
-    arm_trblock_tb_stop(db, cpu);
-
-    if (tb->cflags & CF_LAST_IO) {
-        gen_io_end(cpu_env);
-    }
-
-done_generating:
-    gen_tb_end(tb, db->num_insns);
-
-#ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
-        qemu_log_in_addr_range(db->pc_first)) {
-        int disas_flags = arm_trblock_disas_flags(db);
-        qemu_log_lock();
-        qemu_log("----------------\n");
-        qemu_log("IN: %s\n", lookup_symbol(db->pc_first));
-        log_target_disas(cpu, db->pc_first, dc->pc - db->pc_first,
-                         disas_flags);
-        qemu_log("\n");
-        qemu_log_unlock();
-    }
-#endif
-    tb->size = dc->pc - db->pc_first;
-    tb->icount = db->num_insns;
 }
 
 static const char *cpu_mode_names[16] = {
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 43e8b555e3..0e60d4d771 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -152,7 +152,7 @@ static void disas_set_insn_syndrome(DisasContext *s, 
uint32_t syn)
 
 #ifdef TARGET_AARCH64
 void a64_translate_init(void);
-void gen_intermediate_code_a64(DisasContextBase *db, ARMCPU *cpu,
+void gen_intermediate_code_a64(DisasContextBase *db, CPUState *cpu,
                                TranslationBlock *tb);
 void gen_a64_set_pc_im(uint64_t val);
 void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
@@ -162,8 +162,8 @@ static inline void a64_translate_init(void)
 {
 }
 
-static inline void gen_intermediate_code_a64(DisasContextBase *db, ARMCPU *cpu,
-                                             TranslationBlock *tb)
+static inline void gen_intermediate_code_a64(
+    DisasContextBase *db, CPUState *cpu, TranslationBlock *tb)
 {
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]