* [PATCH v2 00/11] target/cris: Convert to TranslatorOps
@ 2021-06-20 21:32 Richard Henderson
2021-06-20 21:32 ` [PATCH v2 01/11] target/cris: Add DisasContextBase to DisasContext Richard Henderson
` (10 more replies)
0 siblings, 11 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-20 21:32 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.
Changes for v2:
* Fix (drop) singlestep check for max_insns.
We already do that generically.
* Move delay branch handling to tb_stop.
* Improve tcg_gen_lookup_and_goto_ptr patch.
* Patch 8, Use movcond for t_gen_cc_jmp, now
folded into single caller, for JMP_INDIRECT.
I'll note, while glancing through the emitted opcodes,
that the comment at the top of the translator still stands:
The cc handling is the thing most in need of attention.
r~
Richard Henderson (11):
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: Fix use_goto_tb
target/cris: Convert to TranslatorOps
target/cris: Mark helper_raise_exception noreturn
target/cris: Mark static arrays const
target/cris: Move delayed branch handling to tb_stop
target/cris: Use tcg_gen_lookup_and_goto_ptr
target/cris: Improve JMP_INDIRECT
target/cris/helper.h | 2 +-
target/cris/translate.c | 392 +++++++++++++++++---------------
target/cris/translate_v10.c.inc | 11 +-
3 files changed, 218 insertions(+), 187 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 01/11] target/cris: Add DisasContextBase to DisasContext
2021-06-20 21:32 [PATCH v2 00/11] target/cris: Convert to TranslatorOps Richard Henderson
@ 2021-06-20 21:32 ` Richard Henderson
2021-06-20 21:32 ` [PATCH v2 02/11] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN Richard Henderson
` (9 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-20 21:32 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] 17+ messages in thread
* [PATCH v2 02/11] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN
2021-06-20 21:32 [PATCH v2 00/11] target/cris: Convert to TranslatorOps Richard Henderson
2021-06-20 21:32 ` [PATCH v2 01/11] target/cris: Add DisasContextBase to DisasContext Richard Henderson
@ 2021-06-20 21:32 ` Richard Henderson
2021-06-21 20:01 ` Philippe Mathieu-Daudé
2021-06-20 21:32 ` [PATCH v2 03/11] target/cris: Mark exceptions as DISAS_NORETURN Richard Henderson
` (8 subsequent siblings)
10 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2021-06-20 21:32 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] 17+ messages in thread
* [PATCH v2 03/11] target/cris: Mark exceptions as DISAS_NORETURN
2021-06-20 21:32 [PATCH v2 00/11] target/cris: Convert to TranslatorOps Richard Henderson
2021-06-20 21:32 ` [PATCH v2 01/11] target/cris: Add DisasContextBase to DisasContext Richard Henderson
2021-06-20 21:32 ` [PATCH v2 02/11] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN Richard Henderson
@ 2021-06-20 21:32 ` Richard Henderson
2021-06-20 21:32 ` [PATCH v2 04/11] target/cris: Remove DISAS_SWI Richard Henderson
` (7 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-20 21:32 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] 17+ messages in thread
* [PATCH v2 04/11] target/cris: Remove DISAS_SWI
2021-06-20 21:32 [PATCH v2 00/11] target/cris: Convert to TranslatorOps Richard Henderson
` (2 preceding siblings ...)
2021-06-20 21:32 ` [PATCH v2 03/11] target/cris: Mark exceptions as DISAS_NORETURN Richard Henderson
@ 2021-06-20 21:32 ` Richard Henderson
2021-06-20 21:32 ` [PATCH v2 05/11] target/cris: Fix use_goto_tb Richard Henderson
` (6 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-20 21:32 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] 17+ messages in thread
* [PATCH v2 05/11] target/cris: Fix use_goto_tb
2021-06-20 21:32 [PATCH v2 00/11] target/cris: Convert to TranslatorOps Richard Henderson
` (3 preceding siblings ...)
2021-06-20 21:32 ` [PATCH v2 04/11] target/cris: Remove DISAS_SWI Richard Henderson
@ 2021-06-20 21:32 ` Richard Henderson
2021-06-20 21:32 ` [PATCH v2 06/11] target/cris: Convert to TranslatorOps Richard Henderson
` (5 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-20 21:32 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
Do not skip the page check for user-only -- mmap/mprotect can
still change page mappings. Only check dc->base.pc_first, not
dc->ppc -- the start page is the only one that's relevant.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/translate.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/target/cris/translate.c b/target/cris/translate.c
index 24dbae6d58..9e1f2f9239 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -524,14 +524,9 @@ static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
gen_set_label(l1);
}
-static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
+static bool use_goto_tb(DisasContext *dc, target_ulong dest)
{
-#ifndef CONFIG_USER_ONLY
- return (dc->base.pc_first & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
- (dc->ppc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
- return true;
-#endif
+ return ((dest ^ dc->base.pc_first) & TARGET_PAGE_MASK) == 0;
}
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
--
2.25.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 06/11] target/cris: Convert to TranslatorOps
2021-06-20 21:32 [PATCH v2 00/11] target/cris: Convert to TranslatorOps Richard Henderson
` (4 preceding siblings ...)
2021-06-20 21:32 ` [PATCH v2 05/11] target/cris: Fix use_goto_tb Richard Henderson
@ 2021-06-20 21:32 ` Richard Henderson
2021-06-20 21:32 ` [PATCH v2 07/11] target/cris: Mark helper_raise_exception noreturn Richard Henderson
` (4 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-20 21:32 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/translate.c | 313 ++++++++++++++++++++++------------------
1 file changed, 170 insertions(+), 143 deletions(-)
diff --git a/target/cris/translate.c b/target/cris/translate.c
index 9e1f2f9239..f6d1fa914f 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -3114,17 +3114,12 @@ 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 tb_flags = dc->base.tb->flags;
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;
if (env->pregs[PR_VR] == 32) {
dc->decoder = crisv32_decoder;
@@ -3134,150 +3129,170 @@ 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;
+ pc_start = dc->base.pc_first & ~1;
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->flags_uptodate = 1;
dc->flagx_known = 1;
- dc->flags_x = tb->flags & X_FLAG;
+ dc->flags_x = tb_flags & X_FLAG;
dc->cc_x_uptodate = 0;
dc->cc_mask = 0;
dc->update_cc = 0;
dc->clear_prefix = 0;
+ dc->cpustate_changed = 0;
cris_update_cc_op(dc, CC_OP_FLAGS, 4);
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->tb_flags = tb_flags & (S_FLAG | P_FLAG | U_FLAG | X_FLAG | PFIX_FLAG);
+ dc->delayed_branch = !!(tb_flags & 7);
if (dc->delayed_branch) {
dc->jmp = JMP_INDIRECT;
} else {
dc->jmp = JMP_NOJMP;
}
+}
- dc->cpustate_changed = 0;
+static void cris_tr_tb_start(DisasContextBase *db, CPUState *cpu)
+{
+}
- page_start = pc_start & TARGET_PAGE_MASK;
- num_insns = 0;
+static void cris_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
+{
+ DisasContext *dc = container_of(dcbase, DisasContext, base);
- gen_tb_start(tb);
- do {
- tcg_gen_insn_start(dc->delayed_branch == 1
- ? dc->ppc | 1 : dc->pc);
- num_insns++;
+ tcg_gen_insn_start(dc->delayed_branch == 1 ? dc->ppc | 1 : dc->pc);
+}
- if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
+static bool cris_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
+ const CPUBreakpoint *bp)
+{
+ DisasContext *dc = container_of(dcbase, DisasContext, base);
+
+ 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;
+}
+
+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;
+
+ /* Pretty disas. */
+ LOG_DIS("%8.8x:\t", dc->pc);
+
+ dc->clear_x = 1;
+
+ 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 == 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);
- tcg_gen_movi_tl(env_pc, dc->pc);
- t_gen_raise_exception(EXCP_DEBUG);
+
+ /* 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;
- /* 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;
+ 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;
}
+ }
- /* Pretty disas. */
- LOG_DIS("%8.8x:\t", 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 != (dc->base.tb->flags & X_FLAG)))) {
+ dc->base.is_jmp = DISAS_UPDATE;
+ tcg_gen_movi_tl(env_pc, dc->pc);
+ }
- if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
- gen_io_start();
- }
- dc->clear_x = 1;
+ /*
+ * 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;
+ }
+}
- insn_len = dc->decoder(env, dc);
- dc->ppc = dc->pc;
- dc->pc += insn_len;
- if (dc->clear_x) {
- cris_clear_x_flag(dc);
- }
+static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
+{
+ DisasContext *dc = container_of(dcbase, DisasContext, base);
+ DisasJumpType is_jmp = dc->base.is_jmp;
+ target_ulong npc = dc->pc;
- /* 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);
- }
-
- 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;
- }
- break;
- }
- }
-
- /* 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);
+ if (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. */
@@ -3287,45 +3302,57 @@ 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) {
+ if (unlikely(dc->base.singlestep_enabled)) {
+ switch (is_jmp) {
+ case DISAS_TOO_MANY:
tcg_gen_movi_tl(env_pc, npc);
- }
- t_gen_raise_exception(EXCP_DEBUG);
- } else {
- switch (dc->base.is_jmp) {
- case DISAS_NEXT:
- gen_goto_tb(dc, 1, npc);
- break;
- default:
+ /* fall through */
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 */
+ t_gen_raise_exception(EXCP_DEBUG);
+ return;
+ default:
break;
}
+ 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);
+ switch (is_jmp) {
+ case DISAS_TOO_MANY:
+ gen_goto_tb(dc, 0, npc);
+ break;
+ case DISAS_JUMP:
+ case DISAS_UPDATE:
+ /* Indicate that interupts must be re-evaluated before the next TB. */
+ tcg_gen_exit_tb(NULL, 0);
+ break;
+ default:
+ g_assert_not_reached();
}
-#endif
-#endif
+}
+
+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);
+ }
+}
+
+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] 17+ messages in thread
* [PATCH v2 07/11] target/cris: Mark helper_raise_exception noreturn
2021-06-20 21:32 [PATCH v2 00/11] target/cris: Convert to TranslatorOps Richard Henderson
` (5 preceding siblings ...)
2021-06-20 21:32 ` [PATCH v2 06/11] target/cris: Convert to TranslatorOps Richard Henderson
@ 2021-06-20 21:32 ` Richard Henderson
2021-06-20 21:32 ` [PATCH v2 08/11] target/cris: Mark static arrays const Richard Henderson
` (3 subsequent siblings)
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-20 21:32 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] 17+ messages in thread
* [PATCH v2 08/11] target/cris: Mark static arrays const
2021-06-20 21:32 [PATCH v2 00/11] target/cris: Convert to TranslatorOps Richard Henderson
` (6 preceding siblings ...)
2021-06-20 21:32 ` [PATCH v2 07/11] target/cris: Mark helper_raise_exception noreturn Richard Henderson
@ 2021-06-20 21:32 ` Richard Henderson
2021-06-21 20:04 ` Philippe Mathieu-Daudé
2021-06-20 21:32 ` [PATCH v2 09/11] target/cris: Move delayed branch handling to tb_stop Richard Henderson
` (2 subsequent siblings)
10 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2021-06-20 21:32 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 f6d1fa914f..83b20162f1 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[] = {
@@ -1279,7 +1280,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"
};
@@ -2926,7 +2927,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;
@@ -3359,8 +3360,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] 17+ messages in thread
* [PATCH v2 09/11] target/cris: Move delayed branch handling to tb_stop
2021-06-20 21:32 [PATCH v2 00/11] target/cris: Convert to TranslatorOps Richard Henderson
` (7 preceding siblings ...)
2021-06-20 21:32 ` [PATCH v2 08/11] target/cris: Mark static arrays const Richard Henderson
@ 2021-06-20 21:32 ` Richard Henderson
2021-06-21 17:15 ` Edgar E. Iglesias
2021-06-20 21:32 ` [PATCH v2 10/11] target/cris: Use tcg_gen_lookup_and_goto_ptr Richard Henderson
2021-06-20 21:32 ` [PATCH v2 11/11] target/cris: Improve JMP_INDIRECT Richard Henderson
10 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2021-06-20 21:32 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
By moving the code here, we can re-use other end-of-tb code,
e.g. the evaluation of flags. Honor single stepping.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/translate.c | 82 ++++++++++++++++++++++-------------------
1 file changed, 45 insertions(+), 37 deletions(-)
diff --git a/target/cris/translate.c b/target/cris/translate.c
index 83b20162f1..0e925320b3 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -55,6 +55,7 @@
/* 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_DBRANCH DISAS_TARGET_2 /* pc update for delayed branch */
/* Used by the decoder. */
#define EXTRACT_FIELD(src, start, end) \
@@ -3219,43 +3220,8 @@ static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
* loop doing nothing for on this program location.
*/
if (dc->delayed_branch && --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;
- }
+ dc->base.is_jmp = DISAS_DBRANCH;
+ return;
}
/* Force an update if the per-tb cpu state has changed. */
@@ -3303,6 +3269,48 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
cris_evaluate_flags(dc);
+ /* Evaluate delayed branch destination and fold to another is_jmp case. */
+ if (is_jmp == DISAS_DBRANCH) {
+ if (dc->base.tb->flags & 7) {
+ t_gen_movi_env_TN(dslot, 0);
+ }
+
+ switch (dc->jmp) {
+ case JMP_DIRECT:
+ npc = dc->jmp_pc;
+ is_jmp = DISAS_TOO_MANY;
+ break;
+
+ case JMP_DIRECT_CC:
+ /*
+ * Use a conditional branch if either taken or not-taken path
+ * can use goto_tb. If neither can, then treat it as indirect.
+ */
+ if (likely(!dc->base.singlestep_enabled)
+ && (use_goto_tb(dc, dc->jmp_pc) || use_goto_tb(dc, npc))) {
+ TCGLabel *not_taken = gen_new_label();
+
+ tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, not_taken);
+ gen_goto_tb(dc, 1, dc->jmp_pc);
+ gen_set_label(not_taken);
+
+ /* not-taken case handled below. */
+ is_jmp = DISAS_TOO_MANY;
+ break;
+ }
+ tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
+ /* fall through */
+
+ case JMP_INDIRECT:
+ t_gen_cc_jmp(env_btarget, tcg_constant_tl(npc));
+ is_jmp = DISAS_JUMP;
+ break;
+
+ default:
+ g_assert_not_reached();
+ }
+ }
+
if (unlikely(dc->base.singlestep_enabled)) {
switch (is_jmp) {
case DISAS_TOO_MANY:
--
2.25.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 10/11] target/cris: Use tcg_gen_lookup_and_goto_ptr
2021-06-20 21:32 [PATCH v2 00/11] target/cris: Convert to TranslatorOps Richard Henderson
` (8 preceding siblings ...)
2021-06-20 21:32 ` [PATCH v2 09/11] target/cris: Move delayed branch handling to tb_stop Richard Henderson
@ 2021-06-20 21:32 ` Richard Henderson
2021-06-20 21:32 ` [PATCH v2 11/11] target/cris: Improve JMP_INDIRECT Richard Henderson
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-20 21:32 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
We can use this in gen_goto_tb and for DISAS_JUMP
to indirectly chain to the next TB.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/translate.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/target/cris/translate.c b/target/cris/translate.c
index 0e925320b3..c33324b988 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -539,7 +539,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
tcg_gen_exit_tb(dc->base.tb, n);
} else {
tcg_gen_movi_tl(env_pc, dest);
- tcg_gen_exit_tb(NULL, 0);
+ tcg_gen_lookup_and_goto_ptr();
}
}
@@ -3331,6 +3331,8 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
gen_goto_tb(dc, 0, npc);
break;
case DISAS_JUMP:
+ tcg_gen_lookup_and_goto_ptr();
+ break;
case DISAS_UPDATE:
/* Indicate that interupts must be re-evaluated before the next TB. */
tcg_gen_exit_tb(NULL, 0);
--
2.25.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 11/11] target/cris: Improve JMP_INDIRECT
2021-06-20 21:32 [PATCH v2 00/11] target/cris: Convert to TranslatorOps Richard Henderson
` (9 preceding siblings ...)
2021-06-20 21:32 ` [PATCH v2 10/11] target/cris: Use tcg_gen_lookup_and_goto_ptr Richard Henderson
@ 2021-06-20 21:32 ` Richard Henderson
10 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-20 21:32 UTC (permalink / raw)
To: qemu-devel; +Cc: edgar.iglesias
Use movcond instead of brcond to set env_pc.
Discard the btarget and btaken variables to improve
register allocation and avoid unnecessary writeback.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/cris/translate.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/target/cris/translate.c b/target/cris/translate.c
index c33324b988..3200819f32 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -515,17 +515,6 @@ static void t_gen_swapr(TCGv d, TCGv s)
tcg_temp_free(org_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);
-}
-
static bool use_goto_tb(DisasContext *dc, target_ulong dest)
{
return ((dest ^ dc->base.pc_first) & TARGET_PAGE_MASK) == 0;
@@ -3302,8 +3291,17 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
/* fall through */
case JMP_INDIRECT:
- t_gen_cc_jmp(env_btarget, tcg_constant_tl(npc));
+ tcg_gen_movcond_tl(TCG_COND_NE, env_pc,
+ env_btaken, tcg_constant_tl(0),
+ env_btarget, tcg_constant_tl(npc));
is_jmp = DISAS_JUMP;
+
+ /*
+ * We have consumed btaken and btarget. Hint to the
+ * tcg compiler that the writeback to env may be dropped.
+ */
+ tcg_gen_discard_tl(env_btaken);
+ tcg_gen_discard_tl(env_btarget);
break;
default:
--
2.25.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v2 09/11] target/cris: Move delayed branch handling to tb_stop
2021-06-20 21:32 ` [PATCH v2 09/11] target/cris: Move delayed branch handling to tb_stop Richard Henderson
@ 2021-06-21 17:15 ` Edgar E. Iglesias
2021-06-21 17:35 ` Richard Henderson
0 siblings, 1 reply; 17+ messages in thread
From: Edgar E. Iglesias @ 2021-06-21 17:15 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Sun, Jun 20, 2021 at 02:32:47PM -0700, Richard Henderson wrote:
> By moving the code here, we can re-use other end-of-tb code,
> e.g. the evaluation of flags. Honor single stepping.
Hi Richard,
Unfortunately this patch seems to break one of the CRIS tests.
tests/tcg/cris/bare/check_xarith.s
I have an old image with the test-case built in the rootfs...
Best regards,
Edgar
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/cris/translate.c | 82 ++++++++++++++++++++++-------------------
> 1 file changed, 45 insertions(+), 37 deletions(-)
>
> diff --git a/target/cris/translate.c b/target/cris/translate.c
> index 83b20162f1..0e925320b3 100644
> --- a/target/cris/translate.c
> +++ b/target/cris/translate.c
> @@ -55,6 +55,7 @@
> /* 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_DBRANCH DISAS_TARGET_2 /* pc update for delayed branch */
>
> /* Used by the decoder. */
> #define EXTRACT_FIELD(src, start, end) \
> @@ -3219,43 +3220,8 @@ static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
> * loop doing nothing for on this program location.
> */
> if (dc->delayed_branch && --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;
> - }
> + dc->base.is_jmp = DISAS_DBRANCH;
> + return;
> }
>
> /* Force an update if the per-tb cpu state has changed. */
> @@ -3303,6 +3269,48 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
>
> cris_evaluate_flags(dc);
>
> + /* Evaluate delayed branch destination and fold to another is_jmp case. */
> + if (is_jmp == DISAS_DBRANCH) {
> + if (dc->base.tb->flags & 7) {
> + t_gen_movi_env_TN(dslot, 0);
> + }
> +
> + switch (dc->jmp) {
> + case JMP_DIRECT:
> + npc = dc->jmp_pc;
> + is_jmp = DISAS_TOO_MANY;
> + break;
> +
> + case JMP_DIRECT_CC:
> + /*
> + * Use a conditional branch if either taken or not-taken path
> + * can use goto_tb. If neither can, then treat it as indirect.
> + */
> + if (likely(!dc->base.singlestep_enabled)
> + && (use_goto_tb(dc, dc->jmp_pc) || use_goto_tb(dc, npc))) {
> + TCGLabel *not_taken = gen_new_label();
> +
> + tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, not_taken);
> + gen_goto_tb(dc, 1, dc->jmp_pc);
> + gen_set_label(not_taken);
> +
> + /* not-taken case handled below. */
> + is_jmp = DISAS_TOO_MANY;
> + break;
> + }
> + tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
> + /* fall through */
> +
> + case JMP_INDIRECT:
> + t_gen_cc_jmp(env_btarget, tcg_constant_tl(npc));
> + is_jmp = DISAS_JUMP;
> + break;
> +
> + default:
> + g_assert_not_reached();
> + }
> + }
> +
> if (unlikely(dc->base.singlestep_enabled)) {
> switch (is_jmp) {
> case DISAS_TOO_MANY:
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 09/11] target/cris: Move delayed branch handling to tb_stop
2021-06-21 17:15 ` Edgar E. Iglesias
@ 2021-06-21 17:35 ` Richard Henderson
0 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-21 17:35 UTC (permalink / raw)
To: Edgar E. Iglesias; +Cc: qemu-devel
On 6/21/21 10:15 AM, Edgar E. Iglesias wrote:
> On Sun, Jun 20, 2021 at 02:32:47PM -0700, Richard Henderson wrote:
>> By moving the code here, we can re-use other end-of-tb code,
>> e.g. the evaluation of flags. Honor single stepping.
>
> Hi Richard,
>
> Unfortunately this patch seems to break one of the CRIS tests.
> tests/tcg/cris/bare/check_xarith.s
Hum, that's currently marked
# no sure why
CRIS_BROKEN_TESTS += check_scc check_xarith
> I have an old image with the test-case built in the rootfs...
Can you share that?
r~
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 02/11] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN
2021-06-20 21:32 ` [PATCH v2 02/11] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN Richard Henderson
@ 2021-06-21 20:01 ` Philippe Mathieu-Daudé
2021-06-21 23:32 ` Richard Henderson
0 siblings, 1 reply; 17+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-21 20:01 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: edgar.iglesias
On 6/20/21 11:32 PM, Richard Henderson wrote:
> 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
Can we #define DISAS_SWI DISAS_TARGET_2 in the same commit?
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 08/11] target/cris: Mark static arrays const
2021-06-20 21:32 ` [PATCH v2 08/11] target/cris: Mark static arrays const Richard Henderson
@ 2021-06-21 20:04 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 17+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-21 20:04 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: edgar.iglesias
On 6/20/21 11:32 PM, Richard Henderson wrote:
> 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(-)
> #if DISAS_CRIS
> static const char *cc_name(int cc)
> {
> - static const char *cc_names[16] = {
> + static const char * const cc_names[16] = {
char [2]?
> "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
> "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
> };
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 02/11] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN
2021-06-21 20:01 ` Philippe Mathieu-Daudé
@ 2021-06-21 23:32 ` Richard Henderson
0 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2021-06-21 23:32 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel; +Cc: edgar.iglesias
On 6/21/21 1:01 PM, Philippe Mathieu-Daudé wrote:
> On 6/20/21 11:32 PM, Richard Henderson wrote:
>> 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
>
> Can we #define DISAS_SWI DISAS_TARGET_2 in the same commit?
No point. It goes away in patch 4.
r~
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2021-06-21 23:43 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-20 21:32 [PATCH v2 00/11] target/cris: Convert to TranslatorOps Richard Henderson
2021-06-20 21:32 ` [PATCH v2 01/11] target/cris: Add DisasContextBase to DisasContext Richard Henderson
2021-06-20 21:32 ` [PATCH v2 02/11] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN Richard Henderson
2021-06-21 20:01 ` Philippe Mathieu-Daudé
2021-06-21 23:32 ` Richard Henderson
2021-06-20 21:32 ` [PATCH v2 03/11] target/cris: Mark exceptions as DISAS_NORETURN Richard Henderson
2021-06-20 21:32 ` [PATCH v2 04/11] target/cris: Remove DISAS_SWI Richard Henderson
2021-06-20 21:32 ` [PATCH v2 05/11] target/cris: Fix use_goto_tb Richard Henderson
2021-06-20 21:32 ` [PATCH v2 06/11] target/cris: Convert to TranslatorOps Richard Henderson
2021-06-20 21:32 ` [PATCH v2 07/11] target/cris: Mark helper_raise_exception noreturn Richard Henderson
2021-06-20 21:32 ` [PATCH v2 08/11] target/cris: Mark static arrays const Richard Henderson
2021-06-21 20:04 ` Philippe Mathieu-Daudé
2021-06-20 21:32 ` [PATCH v2 09/11] target/cris: Move delayed branch handling to tb_stop Richard Henderson
2021-06-21 17:15 ` Edgar E. Iglesias
2021-06-21 17:35 ` Richard Henderson
2021-06-20 21:32 ` [PATCH v2 10/11] target/cris: Use tcg_gen_lookup_and_goto_ptr Richard Henderson
2021-06-20 21:32 ` [PATCH v2 11/11] target/cris: Improve JMP_INDIRECT Richard Henderson
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.