* [PATCH 0/9] target/cris: Convert to TranslatorOps
@ 2021-06-20 4:21 Richard Henderson
2021-06-20 4:21 ` [PATCH 1/9] target/cris: Add DisasContextBase to DisasContext Richard Henderson
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: Richard Henderson @ 2021-06-20 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
I've reached a point where *all* targets must use the translator loop.
Do that, plus some other obvious cleanups.
r~
Richard Henderson (9):
target/cris: Add DisasContextBase to DisasContext
target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN
target/cris: Mark exceptions as DISAS_NORETURN
target/cris: Remove DISAS_SWI
target/cris: Convert to TranslatorOps
target/cris: Mark helper_raise_exception noreturn
target/cris: Mark static arrays const
target/cris: Use movcond for t_gen_cc_jmp
target/cris: Use tcg_gen_lookup_and_goto_ptr
target/cris/helper.h | 2 +-
target/cris/translate.c | 373 +++++++++++++++++---------------
target/cris/translate_v10.c.inc | 11 +-
3 files changed, 210 insertions(+), 176 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/9] target/cris: Add DisasContextBase to DisasContext
2021-06-20 4:21 [PATCH 0/9] target/cris: Convert to TranslatorOps Richard Henderson
@ 2021-06-20 4:21 ` Richard Henderson
2021-06-20 4:21 ` [PATCH 2/9] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN Richard Henderson
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2021-06-20 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
Migrate the is_jmp, tb and singlestep_enabled fields
from DisasContext into the base.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/translate.c | 49 +++++++++++++++++----------------
target/cris/translate_v10.c.inc | 4 +--
2 files changed, 27 insertions(+), 26 deletions(-)
diff --git a/target/cris/translate.c b/target/cris/translate.c
index 6dd5a267a6..bed7a7ed10 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -85,6 +85,8 @@ static TCGv env_pc;
/* This is the state at translation time. */
typedef struct DisasContext {
+ DisasContextBase base;
+
CRISCPU *cpu;
target_ulong pc, ppc;
@@ -121,7 +123,6 @@ typedef struct DisasContext {
int clear_locked_irq; /* Clear the irq lockout. */
int cpustate_changed;
unsigned int tb_flags; /* tb dependent flags. */
- int is_jmp;
#define JMP_NOJMP 0
#define JMP_DIRECT 1
@@ -131,9 +132,6 @@ typedef struct DisasContext {
uint32_t jmp_pc;
int delayed_branch;
-
- TranslationBlock *tb;
- int singlestep_enabled;
} DisasContext;
static void gen_BUG(DisasContext *dc, const char *file, int line)
@@ -531,7 +529,7 @@ static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
{
#ifndef CONFIG_USER_ONLY
- return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
+ return (dc->base.pc_first & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
(dc->ppc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
#else
return true;
@@ -543,7 +541,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
if (use_goto_tb(dc, dest)) {
tcg_gen_goto_tb(n);
tcg_gen_movi_tl(env_pc, dest);
- tcg_gen_exit_tb(dc->tb, n);
+ tcg_gen_exit_tb(dc->base.tb, n);
} else {
tcg_gen_movi_tl(env_pc, dest);
tcg_gen_exit_tb(NULL, 0);
@@ -2037,14 +2035,14 @@ static int dec_setclrf(CPUCRISState *env, DisasContext *dc)
/* Break the TB if any of the SPI flag changes. */
if (flags & (P_FLAG | S_FLAG)) {
tcg_gen_movi_tl(env_pc, dc->pc + 2);
- dc->is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_UPDATE;
dc->cpustate_changed = 1;
}
/* For the I flag, only act on posedge. */
if ((flags & I_FLAG)) {
tcg_gen_movi_tl(env_pc, dc->pc + 2);
- dc->is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_UPDATE;
dc->cpustate_changed = 1;
}
@@ -2886,14 +2884,14 @@ static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
LOG_DIS("rfe\n");
cris_evaluate_flags(dc);
gen_helper_rfe(cpu_env);
- dc->is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_UPDATE;
break;
case 5:
/* rfn. */
LOG_DIS("rfn\n");
cris_evaluate_flags(dc);
gen_helper_rfn(cpu_env);
- dc->is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_UPDATE;
break;
case 6:
LOG_DIS("break %d\n", dc->op1);
@@ -2904,7 +2902,7 @@ static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
/* Breaks start at 16 in the exception vector. */
t_gen_movi_env_TN(trap_vector, dc->op1 + 16);
t_gen_raise_exception(EXCP_BREAK);
- dc->is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_UPDATE;
break;
default:
printf("op2=%x\n", dc->op2);
@@ -3146,13 +3144,16 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
* delayslot, like in real hw.
*/
pc_start = tb->pc & ~1;
- dc->cpu = env_archcpu(env);
- dc->tb = tb;
- dc->is_jmp = DISAS_NEXT;
+ dc->base.tb = tb;
+ dc->base.pc_first = pc_start;
+ dc->base.pc_next = pc_start;
+ dc->base.is_jmp = DISAS_NEXT;
+ dc->base.singlestep_enabled = cs->singlestep_enabled;
+
+ dc->cpu = env_archcpu(env);
dc->ppc = pc_start;
dc->pc = pc_start;
- dc->singlestep_enabled = cs->singlestep_enabled;
dc->flags_uptodate = 1;
dc->flagx_known = 1;
dc->flags_x = tb->flags & X_FLAG;
@@ -3189,7 +3190,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
cris_evaluate_flags(dc);
tcg_gen_movi_tl(env_pc, dc->pc);
t_gen_raise_exception(EXCP_DEBUG);
- dc->is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_UPDATE;
/* 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
@@ -3242,18 +3243,18 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
gen_goto_tb(dc, 1, dc->jmp_pc);
gen_set_label(l1);
gen_goto_tb(dc, 0, dc->pc);
- dc->is_jmp = DISAS_TB_JUMP;
+ dc->base.is_jmp = DISAS_TB_JUMP;
dc->jmp = JMP_NOJMP;
} else if (dc->jmp == JMP_DIRECT) {
cris_evaluate_flags(dc);
gen_goto_tb(dc, 0, dc->jmp_pc);
- dc->is_jmp = DISAS_TB_JUMP;
+ dc->base.is_jmp = DISAS_TB_JUMP;
dc->jmp = JMP_NOJMP;
} else {
TCGv c = tcg_const_tl(dc->pc);
t_gen_cc_jmp(env_btarget, c);
tcg_temp_free(c);
- dc->is_jmp = DISAS_JUMP;
+ dc->base.is_jmp = DISAS_JUMP;
}
break;
}
@@ -3264,7 +3265,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
if (!(tb->pc & 1) && cs->singlestep_enabled) {
break;
}
- } while (!dc->is_jmp && !dc->cpustate_changed
+ } while (!dc->base.is_jmp && !dc->cpustate_changed
&& !tcg_op_buf_full()
&& !singlestep
&& (dc->pc - page_start < TARGET_PAGE_SIZE)
@@ -3277,10 +3278,10 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
npc = dc->pc;
/* Force an update if the per-tb cpu state has changed. */
- if (dc->is_jmp == DISAS_NEXT
+ if (dc->base.is_jmp == DISAS_NEXT
&& (dc->cpustate_changed || !dc->flagx_known
|| (dc->flags_x != (tb->flags & X_FLAG)))) {
- dc->is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_UPDATE;
tcg_gen_movi_tl(env_pc, npc);
}
/* Broken branch+delayslot sequence. */
@@ -3293,12 +3294,12 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
cris_evaluate_flags(dc);
if (unlikely(cs->singlestep_enabled)) {
- if (dc->is_jmp == DISAS_NEXT) {
+ if (dc->base.is_jmp == DISAS_NEXT) {
tcg_gen_movi_tl(env_pc, npc);
}
t_gen_raise_exception(EXCP_DEBUG);
} else {
- switch (dc->is_jmp) {
+ switch (dc->base.is_jmp) {
case DISAS_NEXT:
gen_goto_tb(dc, 1, npc);
break;
diff --git a/target/cris/translate_v10.c.inc b/target/cris/translate_v10.c.inc
index f7cd67be37..dd44a7eb97 100644
--- a/target/cris/translate_v10.c.inc
+++ b/target/cris/translate_v10.c.inc
@@ -1169,7 +1169,7 @@ static unsigned int dec10_ind(CPUCRISState *env, DisasContext *dc)
t_gen_mov_env_TN(trap_vector, c);
tcg_temp_free(c);
t_gen_raise_exception(EXCP_BREAK);
- dc->is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_UPDATE;
return insn_len;
}
LOG_DIS("%d: jump.%d %d r%d r%d\n", __LINE__, size,
@@ -1277,7 +1277,7 @@ static unsigned int crisv10_decoder(CPUCRISState *env, DisasContext *dc)
if (dc->clear_prefix && dc->tb_flags & PFIX_FLAG) {
dc->tb_flags &= ~PFIX_FLAG;
tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~PFIX_FLAG);
- if (dc->tb_flags != dc->tb->flags) {
+ if (dc->tb_flags != dc->base.tb->flags) {
dc->cpustate_changed = 1;
}
}
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/9] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN
2021-06-20 4:21 [PATCH 0/9] target/cris: Convert to TranslatorOps Richard Henderson
2021-06-20 4:21 ` [PATCH 1/9] target/cris: Add DisasContextBase to DisasContext Richard Henderson
@ 2021-06-20 4:21 ` Richard Henderson
2021-06-20 4:21 ` [PATCH 3/9] target/cris: Mark exceptions as DISAS_NORETURN Richard Henderson
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2021-06-20 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
The only semantic of DISAS_TB_JUMP is that we've done goto_tb,
which is the same as DISAS_NORETURN -- we've exited the tb.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/translate.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/target/cris/translate.c b/target/cris/translate.c
index bed7a7ed10..2ff4319dd1 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -55,7 +55,6 @@
/* is_jmp field values */
#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
#define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
#define DISAS_SWI DISAS_TARGET_3
/* Used by the decoder. */
@@ -3243,12 +3242,12 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
gen_goto_tb(dc, 1, dc->jmp_pc);
gen_set_label(l1);
gen_goto_tb(dc, 0, dc->pc);
- dc->base.is_jmp = DISAS_TB_JUMP;
+ dc->base.is_jmp = DISAS_NORETURN;
dc->jmp = JMP_NOJMP;
} else if (dc->jmp == JMP_DIRECT) {
cris_evaluate_flags(dc);
gen_goto_tb(dc, 0, dc->jmp_pc);
- dc->base.is_jmp = DISAS_TB_JUMP;
+ dc->base.is_jmp = DISAS_NORETURN;
dc->jmp = JMP_NOJMP;
} else {
TCGv c = tcg_const_tl(dc->pc);
@@ -3311,7 +3310,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
tcg_gen_exit_tb(NULL, 0);
break;
case DISAS_SWI:
- case DISAS_TB_JUMP:
+ case DISAS_NORETURN:
/* nothing more to generate */
break;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/9] target/cris: Mark exceptions as DISAS_NORETURN
2021-06-20 4:21 [PATCH 0/9] target/cris: Convert to TranslatorOps Richard Henderson
2021-06-20 4:21 ` [PATCH 1/9] target/cris: Add DisasContextBase to DisasContext Richard Henderson
2021-06-20 4:21 ` [PATCH 2/9] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN Richard Henderson
@ 2021-06-20 4:21 ` Richard Henderson
2021-06-20 4:21 ` [PATCH 4/9] target/cris: Remove DISAS_SWI Richard Henderson
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2021-06-20 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
After we've raised the exception, we have left the TB.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/translate.c | 5 +++--
target/cris/translate_v10.c.inc | 3 ++-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/target/cris/translate.c b/target/cris/translate.c
index 2ff4319dd1..f8b574b0b6 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -2874,6 +2874,7 @@ static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
-offsetof(CRISCPU, env) + offsetof(CPUState, halted));
tcg_gen_movi_tl(env_pc, dc->pc + 2);
t_gen_raise_exception(EXCP_HLT);
+ dc->base.is_jmp = DISAS_NORETURN;
return 2;
}
@@ -2901,7 +2902,7 @@ static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
/* Breaks start at 16 in the exception vector. */
t_gen_movi_env_TN(trap_vector, dc->op1 + 16);
t_gen_raise_exception(EXCP_BREAK);
- dc->base.is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_NORETURN;
break;
default:
printf("op2=%x\n", dc->op2);
@@ -3189,7 +3190,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
cris_evaluate_flags(dc);
tcg_gen_movi_tl(env_pc, dc->pc);
t_gen_raise_exception(EXCP_DEBUG);
- dc->base.is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_NORETURN;
/* 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
diff --git a/target/cris/translate_v10.c.inc b/target/cris/translate_v10.c.inc
index dd44a7eb97..0ba2aca96f 100644
--- a/target/cris/translate_v10.c.inc
+++ b/target/cris/translate_v10.c.inc
@@ -61,6 +61,7 @@ static inline void cris_illegal_insn(DisasContext *dc)
{
qemu_log_mask(LOG_GUEST_ERROR, "illegal insn at pc=%x\n", dc->pc);
t_gen_raise_exception(EXCP_BREAK);
+ dc->base.is_jmp = DISAS_NORETURN;
}
static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val,
@@ -1169,7 +1170,7 @@ static unsigned int dec10_ind(CPUCRISState *env, DisasContext *dc)
t_gen_mov_env_TN(trap_vector, c);
tcg_temp_free(c);
t_gen_raise_exception(EXCP_BREAK);
- dc->base.is_jmp = DISAS_UPDATE;
+ dc->base.is_jmp = DISAS_NORETURN;
return insn_len;
}
LOG_DIS("%d: jump.%d %d r%d r%d\n", __LINE__, size,
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/9] target/cris: Remove DISAS_SWI
2021-06-20 4:21 [PATCH 0/9] target/cris: Convert to TranslatorOps Richard Henderson
` (2 preceding siblings ...)
2021-06-20 4:21 ` [PATCH 3/9] target/cris: Mark exceptions as DISAS_NORETURN Richard Henderson
@ 2021-06-20 4:21 ` Richard Henderson
2021-06-20 4:21 ` [PATCH 5/9] target/cris: Convert to TranslatorOps Richard Henderson
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2021-06-20 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
This value is unused.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/translate.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/target/cris/translate.c b/target/cris/translate.c
index f8b574b0b6..24dbae6d58 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -55,7 +55,6 @@
/* is_jmp field values */
#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
#define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */
-#define DISAS_SWI DISAS_TARGET_3
/* Used by the decoder. */
#define EXTRACT_FIELD(src, start, end) \
@@ -3310,7 +3309,6 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
to find the next TB */
tcg_gen_exit_tb(NULL, 0);
break;
- case DISAS_SWI:
case DISAS_NORETURN:
/* nothing more to generate */
break;
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/9] target/cris: Convert to TranslatorOps
2021-06-20 4:21 [PATCH 0/9] target/cris: Convert to TranslatorOps Richard Henderson
` (3 preceding siblings ...)
2021-06-20 4:21 ` [PATCH 4/9] target/cris: Remove DISAS_SWI Richard Henderson
@ 2021-06-20 4:21 ` Richard Henderson
2021-06-20 4:21 ` [PATCH 6/9] target/cris: Mark helper_raise_exception noreturn Richard Henderson
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2021-06-20 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/translate.c | 320 ++++++++++++++++++++++------------------
1 file changed, 177 insertions(+), 143 deletions(-)
diff --git a/target/cris/translate.c b/target/cris/translate.c
index 24dbae6d58..8c24053f5e 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -3119,17 +3119,11 @@ static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
*
*/
-/* generate intermediate code for basic block 'tb'. */
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+static void cris_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
{
+ DisasContext *dc = container_of(dcbase, DisasContext, base);
CPUCRISState *env = cs->env_ptr;
- uint32_t pc_start;
- unsigned int insn_len;
- struct DisasContext ctx;
- struct DisasContext *dc = &ctx;
- uint32_t page_start;
- target_ulong npc;
- int num_insns;
+ uint32_t tb_flags;
if (env->pregs[PR_VR] == 32) {
dc->decoder = crisv32_decoder;
@@ -3139,23 +3133,21 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
dc->clear_locked_irq = 1;
}
- /* Odd PC indicates that branch is rexecuting due to exception in the
+ /*
+ * Odd PC indicates that branch is rexecuting due to exception in the
* delayslot, like in real hw.
*/
- pc_start = tb->pc & ~1;
-
- dc->base.tb = tb;
- dc->base.pc_first = pc_start;
- dc->base.pc_next = pc_start;
- dc->base.is_jmp = DISAS_NEXT;
- dc->base.singlestep_enabled = cs->singlestep_enabled;
+ dc->base.pc_first &= ~1;
+ dc->base.pc_next &= ~1;
dc->cpu = env_archcpu(env);
- dc->ppc = pc_start;
- dc->pc = pc_start;
+ dc->ppc = dc->base.pc_next;
+ dc->pc = dc->base.pc_next;
dc->flags_uptodate = 1;
dc->flagx_known = 1;
- dc->flags_x = tb->flags & X_FLAG;
+ tb_flags = dc->base.tb->flags;
+ dc->tb_flags = tb_flags & (S_FLAG | P_FLAG | U_FLAG | X_FLAG | PFIX_FLAG);
+ dc->flags_x = tb_flags & X_FLAG;
dc->cc_x_uptodate = 0;
dc->cc_mask = 0;
dc->update_cc = 0;
@@ -3165,9 +3157,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
dc->cc_size_uptodate = -1;
/* Decode TB flags. */
- dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
- | X_FLAG | PFIX_FLAG);
- dc->delayed_branch = !!(tb->flags & 7);
+ dc->delayed_branch = !!(tb_flags & 7);
if (dc->delayed_branch) {
dc->jmp = JMP_INDIRECT;
} else {
@@ -3176,113 +3166,146 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
dc->cpustate_changed = 0;
- page_start = pc_start & TARGET_PAGE_MASK;
- num_insns = 0;
+ if ((dc->base.singlestep_enabled || singlestep)
+ && dc->base.max_insns > 1) {
+ /* If re-executing a branch, execute both. */
+ dc->base.max_insns = 1 + (dc->base.tb->pc & 1);
+ }
+}
- gen_tb_start(tb);
- do {
- tcg_gen_insn_start(dc->delayed_branch == 1
- ? dc->ppc | 1 : dc->pc);
- num_insns++;
+static void cris_tr_tb_start(DisasContextBase *db, CPUState *cpu)
+{
+}
- if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
- cris_evaluate_flags(dc);
- tcg_gen_movi_tl(env_pc, dc->pc);
- t_gen_raise_exception(EXCP_DEBUG);
- dc->base.is_jmp = DISAS_NORETURN;
- /* 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 += 2;
- break;
- }
+static void cris_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
+{
+ DisasContext *dc = container_of(dcbase, DisasContext, base);
- /* Pretty disas. */
- LOG_DIS("%8.8x:\t", dc->pc);
+ tcg_gen_insn_start(dc->delayed_branch == 1 ? dc->ppc | 1 : dc->pc);
+}
- if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
- gen_io_start();
- }
- dc->clear_x = 1;
+static bool cris_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
+ const CPUBreakpoint *bp)
+{
+ DisasContext *dc = container_of(dcbase, DisasContext, base);
- insn_len = dc->decoder(env, dc);
- dc->ppc = dc->pc;
- dc->pc += insn_len;
- if (dc->clear_x) {
- cris_clear_x_flag(dc);
- }
+ cris_evaluate_flags(dc);
+ tcg_gen_movi_tl(env_pc, dc->pc);
+ t_gen_raise_exception(EXCP_DEBUG);
+ dc->base.is_jmp = DISAS_NORETURN;
+ /*
+ * 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 += 2;
+ return true;
+}
- /* Check for delayed branches here. If we do it before
- actually generating any host code, the simulator will just
- loop doing nothing for on this program location. */
- if (dc->delayed_branch) {
- dc->delayed_branch--;
- if (dc->delayed_branch == 0) {
- if (tb->flags & 7) {
- t_gen_movi_env_TN(dslot, 0);
- }
- if (dc->cpustate_changed || !dc->flagx_known
- || (dc->flags_x != (tb->flags & X_FLAG))) {
- cris_store_direct_jmp(dc);
- }
+static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
+{
+ DisasContext *dc = container_of(dcbase, DisasContext, base);
+ CPUCRISState *env = cs->env_ptr;
+ unsigned int insn_len;
- if (dc->clear_locked_irq) {
- dc->clear_locked_irq = 0;
- t_gen_movi_env_TN(locked_irq, 0);
- }
+ /* Pretty disas. */
+ LOG_DIS("%8.8x:\t", dc->pc);
- if (dc->jmp == JMP_DIRECT_CC) {
- TCGLabel *l1 = gen_new_label();
- cris_evaluate_flags(dc);
+ dc->clear_x = 1;
- /* Conditional jmp. */
- tcg_gen_brcondi_tl(TCG_COND_EQ,
- env_btaken, 0, l1);
- gen_goto_tb(dc, 1, dc->jmp_pc);
- gen_set_label(l1);
- gen_goto_tb(dc, 0, dc->pc);
- dc->base.is_jmp = DISAS_NORETURN;
- dc->jmp = JMP_NOJMP;
- } else if (dc->jmp == JMP_DIRECT) {
- cris_evaluate_flags(dc);
- gen_goto_tb(dc, 0, dc->jmp_pc);
- dc->base.is_jmp = DISAS_NORETURN;
- dc->jmp = JMP_NOJMP;
- } else {
- TCGv c = tcg_const_tl(dc->pc);
- t_gen_cc_jmp(env_btarget, c);
- tcg_temp_free(c);
- dc->base.is_jmp = DISAS_JUMP;
- }
- break;
+ insn_len = dc->decoder(env, dc);
+ dc->ppc = dc->pc;
+ dc->pc += insn_len;
+ dc->base.pc_next += insn_len;
+
+ if (dc->clear_x) {
+ cris_clear_x_flag(dc);
+ }
+
+ /*
+ * Check for delayed branches here. If we do it before
+ * actually generating any host code, the simulator will just
+ * loop doing nothing for on this program location.
+ */
+ if (dc->delayed_branch) {
+ dc->delayed_branch--;
+ if (dc->delayed_branch == 0) {
+ if (dc->base.tb->flags & 7) {
+ t_gen_movi_env_TN(dslot, 0);
+ }
+
+ if (dc->cpustate_changed
+ || !dc->flagx_known
+ || (dc->flags_x != (dc->base.tb->flags & X_FLAG))) {
+ cris_store_direct_jmp(dc);
+ }
+
+ if (dc->clear_locked_irq) {
+ dc->clear_locked_irq = 0;
+ t_gen_movi_env_TN(locked_irq, 0);
+ }
+
+ if (dc->jmp == JMP_DIRECT_CC) {
+ TCGLabel *l1 = gen_new_label();
+ cris_evaluate_flags(dc);
+
+ /* Conditional jmp. */
+ tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
+ gen_goto_tb(dc, 1, dc->jmp_pc);
+ gen_set_label(l1);
+ gen_goto_tb(dc, 0, dc->pc);
+ dc->base.is_jmp = DISAS_NORETURN;
+ dc->jmp = JMP_NOJMP;
+ } else if (dc->jmp == JMP_DIRECT) {
+ cris_evaluate_flags(dc);
+ gen_goto_tb(dc, 0, dc->jmp_pc);
+ dc->base.is_jmp = DISAS_NORETURN;
+ dc->jmp = JMP_NOJMP;
+ } else {
+ TCGv c = tcg_const_tl(dc->pc);
+ t_gen_cc_jmp(env_btarget, c);
+ tcg_temp_free(c);
+ dc->base.is_jmp = DISAS_JUMP;
}
}
+ }
- /* If we are rexecuting a branch due to exceptions on
- delay slots don't break. */
- if (!(tb->pc & 1) && cs->singlestep_enabled) {
- break;
- }
- } while (!dc->base.is_jmp && !dc->cpustate_changed
- && !tcg_op_buf_full()
- && !singlestep
- && (dc->pc - page_start < TARGET_PAGE_SIZE)
- && num_insns < max_insns);
+ /* Force an update if the per-tb cpu state has changed. */
+ if (dc->base.is_jmp == DISAS_NEXT
+ && (dc->cpustate_changed
+ || !dc->flagx_known
+ || (dc->flags_x != (dc->base.tb->flags & X_FLAG)))) {
+ dc->base.is_jmp = DISAS_UPDATE;
+ tcg_gen_movi_tl(env_pc, dc->pc);
+ }
+
+ /*
+ * FIXME: Only the first insn in the TB should cross a page boundary.
+ * If we can detect the length of the next insn easily, we should.
+ * In the meantime, simply stop when we do cross.
+ */
+ if (dc->base.is_jmp == DISAS_NEXT
+ && ((dc->pc ^ dc->base.pc_first) & TARGET_PAGE_MASK) != 0) {
+ dc->base.is_jmp = DISAS_TOO_MANY;
+ }
+}
+
+static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
+{
+ DisasContext *dc = container_of(dcbase, DisasContext, base);
+ target_ulong npc = dc->pc;
+
+ if (dc->base.is_jmp == DISAS_NORETURN) {
+ /* If we have a broken branch+delayslot sequence, it's too late. */
+ assert(dc->delayed_branch != 1);
+ return;
+ }
if (dc->clear_locked_irq) {
t_gen_movi_env_TN(locked_irq, 0);
}
- npc = dc->pc;
-
- /* Force an update if the per-tb cpu state has changed. */
- if (dc->base.is_jmp == DISAS_NEXT
- && (dc->cpustate_changed || !dc->flagx_known
- || (dc->flags_x != (tb->flags & X_FLAG)))) {
- dc->base.is_jmp = DISAS_UPDATE;
- tcg_gen_movi_tl(env_pc, npc);
- }
/* Broken branch+delayslot sequence. */
if (dc->delayed_branch == 1) {
/* Set env->dslot to the size of the branch insn. */
@@ -3292,45 +3315,56 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
cris_evaluate_flags(dc);
- if (unlikely(cs->singlestep_enabled)) {
- if (dc->base.is_jmp == DISAS_NEXT) {
- tcg_gen_movi_tl(env_pc, npc);
- }
- t_gen_raise_exception(EXCP_DEBUG);
- } else {
+ if (unlikely(dc->base.singlestep_enabled)) {
switch (dc->base.is_jmp) {
- case DISAS_NEXT:
- gen_goto_tb(dc, 1, npc);
- break;
- default:
+ case DISAS_TOO_MANY:
+ tcg_gen_movi_tl(env_pc, npc);
+ /* fall through */
case DISAS_JUMP:
case DISAS_UPDATE:
- /* indicate that the hash table must be used
- to find the next TB */
+ t_gen_raise_exception(EXCP_DEBUG);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ } else {
+ switch (dc->base.is_jmp) {
+ case DISAS_TOO_MANY:
+ gen_goto_tb(dc, 1, npc);
+ break;
+ case DISAS_JUMP:
+ case DISAS_UPDATE:
+ /* indicate that the hash table must be used to find the next TB */
tcg_gen_exit_tb(NULL, 0);
break;
- case DISAS_NORETURN:
- /* nothing more to generate */
- break;
+ default:
+ g_assert_not_reached();
}
}
- gen_tb_end(tb, num_insns);
+}
- tb->size = dc->pc - pc_start;
- tb->icount = num_insns;
-
-#ifdef DEBUG_DISAS
-#if !DISAS_CRIS
- if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
- && qemu_log_in_addr_range(pc_start)) {
- FILE *logfile = qemu_log_lock();
- qemu_log("--------------\n");
- qemu_log("IN: %s\n", lookup_symbol(pc_start));
- log_target_disas(cs, pc_start, dc->pc - pc_start);
- qemu_log_unlock(logfile);
+static void cris_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
+{
+ if (!DISAS_CRIS) {
+ qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
+ log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
}
-#endif
-#endif
+}
+
+static const TranslatorOps cris_tr_ops = {
+ .init_disas_context = cris_tr_init_disas_context,
+ .tb_start = cris_tr_tb_start,
+ .insn_start = cris_tr_insn_start,
+ .breakpoint_check = cris_tr_breakpoint_check,
+ .translate_insn = cris_tr_translate_insn,
+ .tb_stop = cris_tr_tb_stop,
+ .disas_log = cris_tr_disas_log,
+};
+
+void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
+{
+ DisasContext dc;
+ translator_loop(&cris_tr_ops, &dc.base, cs, tb, max_insns);
}
void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags)
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/9] target/cris: Mark helper_raise_exception noreturn
2021-06-20 4:21 [PATCH 0/9] target/cris: Convert to TranslatorOps Richard Henderson
` (4 preceding siblings ...)
2021-06-20 4:21 ` [PATCH 5/9] target/cris: Convert to TranslatorOps Richard Henderson
@ 2021-06-20 4:21 ` Richard Henderson
2021-06-20 4:21 ` [PATCH 7/9] target/cris: Mark static arrays const Richard Henderson
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2021-06-20 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/helper.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/cris/helper.h b/target/cris/helper.h
index 20d21c4358..3abf608682 100644
--- a/target/cris/helper.h
+++ b/target/cris/helper.h
@@ -1,4 +1,4 @@
-DEF_HELPER_2(raise_exception, void, env, i32)
+DEF_HELPER_2(raise_exception, noreturn, env, i32)
DEF_HELPER_2(tlb_flush_pid, void, env, i32)
DEF_HELPER_2(spc_write, void, env, i32)
DEF_HELPER_1(rfe, void, env)
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 7/9] target/cris: Mark static arrays const
2021-06-20 4:21 [PATCH 0/9] target/cris: Convert to TranslatorOps Richard Henderson
` (5 preceding siblings ...)
2021-06-20 4:21 ` [PATCH 6/9] target/cris: Mark helper_raise_exception noreturn Richard Henderson
@ 2021-06-20 4:21 ` Richard Henderson
2021-06-20 4:21 ` [PATCH 8/9] target/cris: Use movcond for t_gen_cc_jmp Richard Henderson
2021-06-20 4:21 ` [PATCH 9/9] target/cris: Use tcg_gen_lookup_and_goto_ptr Richard Henderson
8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2021-06-20 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/translate.c | 19 ++++++++++---------
target/cris/translate_v10.c.inc | 6 +++---
2 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/target/cris/translate.c b/target/cris/translate.c
index 8c24053f5e..3515c21b7b 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -137,14 +137,15 @@ static void gen_BUG(DisasContext *dc, const char *file, int line)
cpu_abort(CPU(dc->cpu), "%s:%d pc=%x\n", file, line, dc->pc);
}
-static const char *regnames_v32[] =
+static const char * const regnames_v32[] =
{
"$r0", "$r1", "$r2", "$r3",
"$r4", "$r5", "$r6", "$r7",
"$r8", "$r9", "$r10", "$r11",
"$r12", "$r13", "$sp", "$acr",
};
-static const char *pregnames_v32[] =
+
+static const char * const pregnames_v32[] =
{
"$bz", "$vr", "$pid", "$srs",
"$wz", "$exs", "$eda", "$mof",
@@ -153,7 +154,7 @@ static const char *pregnames_v32[] =
};
/* We need this table to handle preg-moves with implicit width. */
-static int preg_sizes[] = {
+static const int preg_sizes[] = {
1, /* bz. */
1, /* vr. */
4, /* pid. */
@@ -475,9 +476,9 @@ static inline void t_gen_swapw(TCGv d, TCGv s)
((T0 >> 5) & 0x02020202) |
((T0 >> 7) & 0x01010101));
*/
-static inline void t_gen_swapr(TCGv d, TCGv s)
+static void t_gen_swapr(TCGv d, TCGv s)
{
- struct {
+ static const struct {
int shift; /* LSL when positive, LSR when negative. */
uint32_t mask;
} bitrev[] = {
@@ -1284,7 +1285,7 @@ static int dec_prep_alu_m(CPUCRISState *env, DisasContext *dc,
#if DISAS_CRIS
static const char *cc_name(int cc)
{
- static const char *cc_names[16] = {
+ static const char * const cc_names[16] = {
"cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
"ls", "hi", "ge", "lt", "gt", "le", "a", "p"
};
@@ -2931,7 +2932,7 @@ static int dec_null(CPUCRISState *env, DisasContext *dc)
return 2;
}
-static struct decoder_info {
+static const struct decoder_info {
struct {
uint32_t bits;
uint32_t mask;
@@ -3371,8 +3372,8 @@ void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags)
{
CRISCPU *cpu = CRIS_CPU(cs);
CPUCRISState *env = &cpu->env;
- const char **regnames;
- const char **pregnames;
+ const char * const *regnames;
+ const char * const *pregnames;
int i;
if (!env) {
diff --git a/target/cris/translate_v10.c.inc b/target/cris/translate_v10.c.inc
index 0ba2aca96f..4ab43dc404 100644
--- a/target/cris/translate_v10.c.inc
+++ b/target/cris/translate_v10.c.inc
@@ -21,7 +21,7 @@
#include "qemu/osdep.h"
#include "crisv10-decode.h"
-static const char *regnames_v10[] =
+static const char * const regnames_v10[] =
{
"$r0", "$r1", "$r2", "$r3",
"$r4", "$r5", "$r6", "$r7",
@@ -29,7 +29,7 @@ static const char *regnames_v10[] =
"$r12", "$r13", "$sp", "$pc",
};
-static const char *pregnames_v10[] =
+static const char * const pregnames_v10[] =
{
"$bz", "$vr", "$p2", "$p3",
"$wz", "$ccr", "$p6-prefix", "$mof",
@@ -38,7 +38,7 @@ static const char *pregnames_v10[] =
};
/* We need this table to handle preg-moves with implicit width. */
-static int preg_sizes_v10[] = {
+static const int preg_sizes_v10[] = {
1, /* bz. */
1, /* vr. */
1, /* pid. */
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 8/9] target/cris: Use movcond for t_gen_cc_jmp
2021-06-20 4:21 [PATCH 0/9] target/cris: Convert to TranslatorOps Richard Henderson
` (6 preceding siblings ...)
2021-06-20 4:21 ` [PATCH 7/9] target/cris: Mark static arrays const Richard Henderson
@ 2021-06-20 4:21 ` Richard Henderson
2021-06-20 4:21 ` [PATCH 9/9] target/cris: Use tcg_gen_lookup_and_goto_ptr Richard Henderson
8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2021-06-20 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
This is better than branch around assignment.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/translate.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/target/cris/translate.c b/target/cris/translate.c
index 3515c21b7b..e4cbc35ebd 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -516,13 +516,9 @@ static void t_gen_swapr(TCGv d, TCGv s)
static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
{
- TCGLabel *l1 = gen_new_label();
-
/* Conditional jmp. */
- tcg_gen_mov_tl(env_pc, pc_false);
- tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
- tcg_gen_mov_tl(env_pc, pc_true);
- gen_set_label(l1);
+ tcg_gen_movcond_tl(TCG_COND_NE, env_pc, env_btaken, tcg_constant_tl(0),
+ pc_true, pc_false);
}
static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 9/9] target/cris: Use tcg_gen_lookup_and_goto_ptr
2021-06-20 4:21 [PATCH 0/9] target/cris: Convert to TranslatorOps Richard Henderson
` (7 preceding siblings ...)
2021-06-20 4:21 ` [PATCH 8/9] target/cris: Use movcond for t_gen_cc_jmp Richard Henderson
@ 2021-06-20 4:21 ` Richard Henderson
8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2021-06-20 4:21 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
Indirect jumps can use this to avoid returning to the main loop.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/translate.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/target/cris/translate.c b/target/cris/translate.c
index e4cbc35ebd..8a8d62f11b 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -3330,6 +3330,9 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
gen_goto_tb(dc, 1, npc);
break;
case DISAS_JUMP:
+ /* indirect chain to the next TB */
+ tcg_gen_lookup_and_goto_ptr();
+ break;
case DISAS_UPDATE:
/* indicate that the hash table must be used to find the next TB */
tcg_gen_exit_tb(NULL, 0);
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-06-20 4:28 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-20 4:21 [PATCH 0/9] target/cris: Convert to TranslatorOps Richard Henderson
2021-06-20 4:21 ` [PATCH 1/9] target/cris: Add DisasContextBase to DisasContext Richard Henderson
2021-06-20 4:21 ` [PATCH 2/9] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN Richard Henderson
2021-06-20 4:21 ` [PATCH 3/9] target/cris: Mark exceptions as DISAS_NORETURN Richard Henderson
2021-06-20 4:21 ` [PATCH 4/9] target/cris: Remove DISAS_SWI Richard Henderson
2021-06-20 4:21 ` [PATCH 5/9] target/cris: Convert to TranslatorOps Richard Henderson
2021-06-20 4:21 ` [PATCH 6/9] target/cris: Mark helper_raise_exception noreturn Richard Henderson
2021-06-20 4:21 ` [PATCH 7/9] target/cris: Mark static arrays const Richard Henderson
2021-06-20 4:21 ` [PATCH 8/9] target/cris: Use movcond for t_gen_cc_jmp Richard Henderson
2021-06-20 4:21 ` [PATCH 9/9] target/cris: Use tcg_gen_lookup_and_goto_ptr Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).