[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v9 26/26] target: [tcg, arm] Port to generic transla
From: |
Lluís Vilanova |
Subject: |
[Qemu-devel] [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)
{
}
- [Qemu-devel] [PATCH v9 18/26] target: [tcg, arm] Port to init_disas_context, (continued)
- [Qemu-devel] [PATCH v9 18/26] target: [tcg, arm] Port to init_disas_context, Lluís Vilanova, 2017/06/25
- [Qemu-devel] [PATCH v9 19/26] target: [tcg, arm] Port to init_globals, Lluís Vilanova, 2017/06/25
- [Qemu-devel] [PATCH v9 20/26] target: [tcg,arm] Port to tb_start, Lluís Vilanova, 2017/06/25
- [Qemu-devel] [PATCH v9 21/26] target: [tcg, arm] Port to insn_start, Lluís Vilanova, 2017/06/25
- [Qemu-devel] [PATCH v9 22/26] target: [tcg, arm] Port to breakpoint_check, Lluís Vilanova, 2017/06/25
- [Qemu-devel] [PATCH v9 23/26] target: [tcg, arm] Port to disas_insn, Lluís Vilanova, 2017/06/25
- [Qemu-devel] [PATCH v9 24/26] target: [tcg,arm] Port to tb_stop, Lluís Vilanova, 2017/06/25
- [Qemu-devel] [PATCH v9 25/26] target: [tcg, arm] Port to disas_flags, Lluís Vilanova, 2017/06/25
- [Qemu-devel] [PATCH v9 26/26] target: [tcg, arm] Port to generic translation framework,
Lluís Vilanova <=
- Re: [Qemu-devel] [RFC PATCH v9 00/26] translate: [tcg] Generic translation framework, Alex Bennée, 2017/06/26
- Re: [Qemu-devel] [RFC PATCH v9 00/26] translate: [tcg] Generic translation framework, Eric Blake, 2017/06/26