All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/15] target/cris: Convert to TranslatorOps
@ 2021-06-22 15:48 Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 01/15] target/cris: Add DisasContextBase to DisasContext Richard Henderson
                   ` (14 more replies)
  0 siblings, 15 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Changes for v3:
  * Fix delayed branch changes vs cpustate_changed.
  * Tidy some X_FLAG handling.

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.


r~


Richard Henderson (15):
  target/cris: Add DisasContextBase to DisasContext
  target/cris: Remove DISAS_SWI
  target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN
  target/cris: Mark exceptions as DISAS_NORETURN
  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: Fold unhandled X_FLAG changes into cpustate_changed
  target/cris: Add DISAS_UPDATE_NEXT
  target/cris: Add DISAS_DBRANCH
  target/cris: Use tcg_gen_lookup_and_goto_ptr
  target/cris: Improve JMP_INDIRECT
  target/cris: Remove dc->flagx_known
  target/cris: Do not exit tb for X_FLAG changes

 target/cris/helper.h            |   2 +-
 target/cris/translate.c         | 513 ++++++++++++++++----------------
 target/cris/translate_v10.c.inc |  17 +-
 3 files changed, 262 insertions(+), 270 deletions(-)

-- 
2.25.1



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

* [PATCH v3 01/15] target/cris: Add DisasContextBase to DisasContext
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 02/15] target/cris: Remove DISAS_SWI Richard Henderson
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 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] 20+ messages in thread

* [PATCH v3 02/15] target/cris: Remove DISAS_SWI
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 01/15] target/cris: Add DisasContextBase to DisasContext Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 03/15] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN Richard Henderson
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 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 bed7a7ed10..8c1bad9564 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -56,7 +56,6 @@
 #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.  */
 #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_TB_JUMP:
             /* nothing more to generate */
             break;
-- 
2.25.1



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

* [PATCH v3 03/15] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 01/15] target/cris: Add DisasContextBase to DisasContext Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 02/15] target/cris: Remove DISAS_SWI Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 04/15] target/cris: Mark exceptions as DISAS_NORETURN Richard Henderson
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 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 8c1bad9564..e086ff9131 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 */
 
 /* Used by the decoder.  */
 #define EXTRACT_FIELD(src, start, end) \
@@ -3242,12 +3241,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);
@@ -3309,7 +3308,7 @@ 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_TB_JUMP:
+        case DISAS_NORETURN:
             /* nothing more to generate */
             break;
         }
-- 
2.25.1



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

* [PATCH v3 04/15] target/cris: Mark exceptions as DISAS_NORETURN
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
                   ` (2 preceding siblings ...)
  2021-06-22 15:48 ` [PATCH v3 03/15] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 05/15] target/cris: Fix use_goto_tb Richard Henderson
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 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 e086ff9131..24dbae6d58 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -2873,6 +2873,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;
     }
 
@@ -2900,7 +2901,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);
@@ -3188,7 +3189,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] 20+ messages in thread

* [PATCH v3 05/15] target/cris: Fix use_goto_tb
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
                   ` (3 preceding siblings ...)
  2021-06-22 15:48 ` [PATCH v3 04/15] target/cris: Mark exceptions as DISAS_NORETURN Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 06/15] target/cris: Convert to TranslatorOps Richard Henderson
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 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] 20+ messages in thread

* [PATCH v3 06/15] target/cris: Convert to TranslatorOps
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
                   ` (4 preceding siblings ...)
  2021-06-22 15:48 ` [PATCH v3 05/15] target/cris: Fix use_goto_tb Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 07/15] target/cris: Mark helper_raise_exception noreturn Richard Henderson
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/cris/translate.c | 317 ++++++++++++++++++++++------------------
 1 file changed, 174 insertions(+), 143 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index 9e1f2f9239..eabede5251 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,174 @@ 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->base.is_jmp == DISAS_NORETURN) {
+        return;
+    }
+
+    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 +3306,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] 20+ messages in thread

* [PATCH v3 07/15] target/cris: Mark helper_raise_exception noreturn
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
                   ` (5 preceding siblings ...)
  2021-06-22 15:48 ` [PATCH v3 06/15] target/cris: Convert to TranslatorOps Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 08/15] target/cris: Mark static arrays const Richard Henderson
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 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] 20+ messages in thread

* [PATCH v3 08/15] target/cris: Mark static arrays const
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
                   ` (6 preceding siblings ...)
  2021-06-22 15:48 ` [PATCH v3 07/15] target/cris: Mark helper_raise_exception noreturn Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 09/15] target/cris: Fold unhandled X_FLAG changes into cpustate_changed Richard Henderson
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 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 eabede5251..e14b7acb10 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;
@@ -3363,8 +3364,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] 20+ messages in thread

* [PATCH v3 09/15] target/cris: Fold unhandled X_FLAG changes into cpustate_changed
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
                   ` (7 preceding siblings ...)
  2021-06-22 15:48 ` [PATCH v3 08/15] target/cris: Mark static arrays const Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 10/15] target/cris: Add DISAS_UPDATE_NEXT Richard Henderson
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

We really do this already, by including them into the same test.
This just hoists the expression up a bit.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/cris/translate.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index e14b7acb10..80276ae84d 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -3217,6 +3217,10 @@ static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
         cris_clear_x_flag(dc);
     }
 
+    /* Fold unhandled changes to X_FLAG into cpustate_changed. */
+    dc->cpustate_changed |= !dc->flagx_known;
+    dc->cpustate_changed |= dc->flags_x != (dc->base.tb->flags & X_FLAG);
+
     /*
      * Check for delayed branches here.  If we do it before
      * actually generating any host code, the simulator will just
@@ -3227,9 +3231,7 @@ static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
             t_gen_movi_env_TN(dslot, 0);
         }
 
-        if (dc->cpustate_changed
-            || !dc->flagx_known
-            || (dc->flags_x != (dc->base.tb->flags & X_FLAG))) {
+        if (dc->cpustate_changed) {
             cris_store_direct_jmp(dc);
         }
 
@@ -3263,10 +3265,7 @@ static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
     }
 
     /* 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)))) {
+    if (dc->base.is_jmp == DISAS_NEXT && dc->cpustate_changed) {
         dc->base.is_jmp = DISAS_UPDATE;
         tcg_gen_movi_tl(env_pc, dc->pc);
     }
-- 
2.25.1



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

* [PATCH v3 10/15] target/cris: Add DISAS_UPDATE_NEXT
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
                   ` (8 preceding siblings ...)
  2021-06-22 15:48 ` [PATCH v3 09/15] target/cris: Fold unhandled X_FLAG changes into cpustate_changed Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 11/15] target/cris: Add DISAS_DBRANCH Richard Henderson
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Move this pc update into tb_stop.
We will be able to re-use this code shortly.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/cris/translate.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index 80276ae84d..c9822eae4c 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -52,9 +52,15 @@
 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
 #define BUG_ON(x) ({if (x) BUG();})
 
-/* 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 */
+/*
+ * Target-specific is_jmp field values
+ */
+/* Only pc was modified dynamically */
+#define DISAS_JUMP          DISAS_TARGET_0
+/* Cpu state was modified dynamically, including pc */
+#define DISAS_UPDATE        DISAS_TARGET_1
+/* Cpu state was modified dynamically, excluding pc -- use npc */
+#define DISAS_UPDATE_NEXT   DISAS_TARGET_2
 
 /* Used by the decoder.  */
 #define EXTRACT_FIELD(src, start, end) \
@@ -3266,8 +3272,8 @@ static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
 
     /* Force an update if the per-tb cpu state has changed.  */
     if (dc->base.is_jmp == DISAS_NEXT && dc->cpustate_changed) {
-        dc->base.is_jmp = DISAS_UPDATE;
-        tcg_gen_movi_tl(env_pc, dc->pc);
+        dc->base.is_jmp = DISAS_UPDATE_NEXT;
+        return;
     }
 
     /*
@@ -3309,6 +3315,7 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
     if (unlikely(dc->base.singlestep_enabled)) {
         switch (is_jmp) {
         case DISAS_TOO_MANY:
+        case DISAS_UPDATE_NEXT:
             tcg_gen_movi_tl(env_pc, npc);
             /* fall through */
         case DISAS_JUMP:
@@ -3325,6 +3332,9 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
     case DISAS_TOO_MANY:
         gen_goto_tb(dc, 0, npc);
         break;
+    case DISAS_UPDATE_NEXT:
+        tcg_gen_movi_tl(env_pc, npc);
+        /* fall through */
     case DISAS_JUMP:
     case DISAS_UPDATE:
         /* Indicate that interupts must be re-evaluated before the next TB. */
-- 
2.25.1



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

* [PATCH v3 11/15] target/cris: Add DISAS_DBRANCH
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
                   ` (9 preceding siblings ...)
  2021-06-22 15:48 ` [PATCH v3 10/15] target/cris: Add DISAS_UPDATE_NEXT Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-23 13:43   ` Edgar E. Iglesias
  2021-06-22 15:48 ` [PATCH v3 12/15] target/cris: Use tcg_gen_lookup_and_goto_ptr Richard Henderson
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Move delayed branch handling to tb_stop, where we can re-use other
end-of-tb code, e.g. the evaluation of flags.  Honor single stepping.
Validate that we aren't losing state by overwriting is_jmp.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/cris/translate.c | 96 ++++++++++++++++++++++++-----------------
 1 file changed, 56 insertions(+), 40 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index c9822eae4c..f58f6f2e5e 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -61,6 +61,8 @@
 #define DISAS_UPDATE        DISAS_TARGET_1
 /* Cpu state was modified dynamically, excluding pc -- use npc */
 #define DISAS_UPDATE_NEXT   DISAS_TARGET_2
+/* PC update for delayed branch, see cpustate_changed otherwise */
+#define DISAS_DBRANCH       DISAS_TARGET_3
 
 /* Used by the decoder.  */
 #define EXTRACT_FIELD(src, start, end) \
@@ -3228,50 +3230,22 @@ static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
     dc->cpustate_changed |= dc->flags_x != (dc->base.tb->flags & X_FLAG);
 
     /*
-     * 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.
+     * All branches are delayed branches, handled immediately below.
+     * We don't expect to see odd combinations of exit conditions.
      */
+    assert(dc->base.is_jmp == DISAS_NEXT || dc->cpustate_changed);
+
     if (dc->delayed_branch && --dc->delayed_branch == 0) {
-        if (dc->base.tb->flags & 7) {
-            t_gen_movi_env_TN(dslot, 0);
-        }
+        dc->base.is_jmp = DISAS_DBRANCH;
+        return;
+    }
 
-        if (dc->cpustate_changed) {
-            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 (dc->base.is_jmp != DISAS_NEXT) {
+        return;
     }
 
     /* Force an update if the per-tb cpu state has changed.  */
-    if (dc->base.is_jmp == DISAS_NEXT && dc->cpustate_changed) {
+    if (dc->cpustate_changed) {
         dc->base.is_jmp = DISAS_UPDATE_NEXT;
         return;
     }
@@ -3281,8 +3255,7 @@ static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
      * 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) {
+    if ((dc->pc ^ dc->base.pc_first) & TARGET_PAGE_MASK) {
         dc->base.is_jmp = DISAS_TOO_MANY;
     }
 }
@@ -3312,6 +3285,49 @@ 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 = dc->cpustate_changed ? DISAS_UPDATE_NEXT : 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)
+                && likely(!dc->cpustate_changed)
+                && (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 = dc->cpustate_changed ? DISAS_UPDATE : 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] 20+ messages in thread

* [PATCH v3 12/15] target/cris: Use tcg_gen_lookup_and_goto_ptr
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
                   ` (10 preceding siblings ...)
  2021-06-22 15:48 ` [PATCH v3 11/15] target/cris: Add DISAS_DBRANCH Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 13/15] target/cris: Improve JMP_INDIRECT Richard Henderson
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 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 f58f6f2e5e..ea6efe19d9 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -546,7 +546,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();
     }
 }
 
@@ -3352,6 +3352,8 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
         tcg_gen_movi_tl(env_pc, npc);
         /* fall through */
     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] 20+ messages in thread

* [PATCH v3 13/15] target/cris: Improve JMP_INDIRECT
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
                   ` (11 preceding siblings ...)
  2021-06-22 15:48 ` [PATCH v3 12/15] target/cris: Use tcg_gen_lookup_and_goto_ptr Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 14/15] target/cris: Remove dc->flagx_known Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 15/15] target/cris: Do not exit tb for X_FLAG changes Richard Henderson
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 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 ea6efe19d9..05be0a41bd 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -522,17 +522,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;
@@ -3319,8 +3308,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 = dc->cpustate_changed ? DISAS_UPDATE : DISAS_JUMP;
+
+            /*
+             * We have now 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] 20+ messages in thread

* [PATCH v3 14/15] target/cris: Remove dc->flagx_known
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
                   ` (12 preceding siblings ...)
  2021-06-22 15:48 ` [PATCH v3 13/15] target/cris: Improve JMP_INDIRECT Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  2021-06-22 15:48 ` [PATCH v3 15/15] target/cris: Do not exit tb for X_FLAG changes Richard Henderson
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

Ever since 2a44f7f17364, flagx_known is always true.
Fold away all of the tests against the flag.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/cris/translate.c         | 99 ++++++++-------------------------
 target/cris/translate_v10.c.inc |  6 +-
 2 files changed, 24 insertions(+), 81 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index 05be0a41bd..45548ffb5e 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -120,8 +120,6 @@ typedef struct DisasContext {
 
     int cc_x_uptodate;  /* 1 - ccs, 2 - known | X_FLAG. 0 not up-to-date.  */
     int flags_uptodate; /* Whether or not $ccs is up-to-date.  */
-    int flagx_known; /* Whether or not flags_x has the x flag known at
-                translation time.  */
     int flags_x;
 
     int clear_x; /* Clear x after this insn?  */
@@ -377,66 +375,26 @@ static inline void t_gen_add_flag(TCGv d, int flag)
 
 static inline void t_gen_addx_carry(DisasContext *dc, TCGv d)
 {
-    if (dc->flagx_known) {
-        if (dc->flags_x) {
-            TCGv c;
-            
-            c = tcg_temp_new();
-            t_gen_mov_TN_preg(c, PR_CCS);
-            /* C flag is already at bit 0.  */
-            tcg_gen_andi_tl(c, c, C_FLAG);
-            tcg_gen_add_tl(d, d, c);
-            tcg_temp_free(c);
-        }
-    } else {
-        TCGv x, c;
+    if (dc->flags_x) {
+        TCGv c = tcg_temp_new();
 
-        x = tcg_temp_new();
-        c = tcg_temp_new();
-        t_gen_mov_TN_preg(x, PR_CCS);
-        tcg_gen_mov_tl(c, x);
-
-        /* Propagate carry into d if X is set. Branch free.  */
+        t_gen_mov_TN_preg(c, PR_CCS);
+        /* C flag is already at bit 0.  */
         tcg_gen_andi_tl(c, c, C_FLAG);
-        tcg_gen_andi_tl(x, x, X_FLAG);
-        tcg_gen_shri_tl(x, x, 4);
-
-        tcg_gen_and_tl(x, x, c);
-        tcg_gen_add_tl(d, d, x);
-        tcg_temp_free(x);
+        tcg_gen_add_tl(d, d, c);
         tcg_temp_free(c);
     }
 }
 
 static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)
 {
-    if (dc->flagx_known) {
-        if (dc->flags_x) {
-            TCGv c;
-            
-            c = tcg_temp_new();
-            t_gen_mov_TN_preg(c, PR_CCS);
-            /* C flag is already at bit 0.  */
-            tcg_gen_andi_tl(c, c, C_FLAG);
-            tcg_gen_sub_tl(d, d, c);
-            tcg_temp_free(c);
-        }
-    } else {
-        TCGv x, c;
+    if (dc->flags_x) {
+        TCGv c = tcg_temp_new();
 
-        x = tcg_temp_new();
-        c = tcg_temp_new();
-        t_gen_mov_TN_preg(x, PR_CCS);
-        tcg_gen_mov_tl(c, x);
-
-        /* Propagate carry into d if X is set. Branch free.  */
+        t_gen_mov_TN_preg(c, PR_CCS);
+        /* C flag is already at bit 0.  */
         tcg_gen_andi_tl(c, c, C_FLAG);
-        tcg_gen_andi_tl(x, x, X_FLAG);
-        tcg_gen_shri_tl(x, x, 4);
-
-        tcg_gen_and_tl(x, x, c);
-        tcg_gen_sub_tl(d, d, x);
-        tcg_temp_free(x);
+        tcg_gen_sub_tl(d, d, c);
         tcg_temp_free(c);
     }
 }
@@ -541,11 +499,9 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 
 static inline void cris_clear_x_flag(DisasContext *dc)
 {
-    if (dc->flagx_known && dc->flags_x) {
+    if (dc->flags_x) {
         dc->flags_uptodate = 0;
     }
-
-    dc->flagx_known = 1;
     dc->flags_x = 0;
 }
 
@@ -630,12 +586,10 @@ static void cris_evaluate_flags(DisasContext *dc)
         break;
     }
 
-    if (dc->flagx_known) {
-        if (dc->flags_x) {
-            tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], X_FLAG);
-        } else if (dc->cc_op == CC_OP_FLAGS) {
-            tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~X_FLAG);
-        }
+    if (dc->flags_x) {
+        tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], X_FLAG);
+    } else if (dc->cc_op == CC_OP_FLAGS) {
+        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~X_FLAG);
     }
     dc->flags_uptodate = 1;
 }
@@ -670,16 +624,11 @@ static void cris_update_cc_op(DisasContext *dc, int op, int size)
 static inline void cris_update_cc_x(DisasContext *dc)
 {
     /* Save the x flag state at the time of the cc snapshot.  */
-    if (dc->flagx_known) {
-        if (dc->cc_x_uptodate == (2 | dc->flags_x)) {
-            return;
-        }
-        tcg_gen_movi_tl(cc_x, dc->flags_x);
-        dc->cc_x_uptodate = 2 | dc->flags_x;
-    } else {
-        tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG);
-        dc->cc_x_uptodate = 1;
+    if (dc->cc_x_uptodate == (2 | dc->flags_x)) {
+        return;
     }
+    tcg_gen_movi_tl(cc_x, dc->flags_x);
+    dc->cc_x_uptodate = 2 | dc->flags_x;
 }
 
 /* Update cc prior to executing ALU op. Needs source operands untouched.  */
@@ -1131,7 +1080,7 @@ static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
 
     /* Conditional writes. We only support the kind were X and P are known
        at translation time.  */
-    if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
+    if (dc->flags_x && (dc->tb_flags & P_FLAG)) {
         dc->postinc = 0;
         cris_evaluate_flags(dc);
         tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
@@ -1140,7 +1089,7 @@ static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
 
     tcg_gen_qemu_st_tl(val, addr, mem_index, MO_TE + ctz32(size));
 
-    if (dc->flagx_known && dc->flags_x) {
+    if (dc->flags_x) {
         cris_evaluate_flags(dc);
         tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
     }
@@ -1727,8 +1676,8 @@ static int dec_addc_r(CPUCRISState *env, DisasContext *dc)
     LOG_DIS("addc $r%u, $r%u\n",
             dc->op1, dc->op2);
     cris_evaluate_flags(dc);
+
     /* Set for this insn.  */
-    dc->flagx_known = 1;
     dc->flags_x = X_FLAG;
 
     cris_cc_mask(dc, CC_MASK_NZVC);
@@ -2015,7 +1964,6 @@ static int dec_setclrf(CPUCRISState *env, DisasContext *dc)
     }
 
     if (flags & X_FLAG) {
-        dc->flagx_known = 1;
         if (set) {
             dc->flags_x = X_FLAG;
         } else {
@@ -2479,7 +2427,6 @@ static int dec_addc_mr(CPUCRISState *env, DisasContext *dc)
     cris_evaluate_flags(dc);
 
     /* Set for this insn.  */
-    dc->flagx_known = 1;
     dc->flags_x = X_FLAG;
 
     cris_alu_m_alloc_temps(t);
@@ -3139,7 +3086,6 @@ static void cris_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     dc->ppc = pc_start;
     dc->pc = pc_start;
     dc->flags_uptodate = 1;
-    dc->flagx_known = 1;
     dc->flags_x = tb_flags & X_FLAG;
     dc->cc_x_uptodate = 0;
     dc->cc_mask = 0;
@@ -3215,7 +3161,6 @@ static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
     }
 
     /* Fold unhandled changes to X_FLAG into cpustate_changed. */
-    dc->cpustate_changed |= !dc->flagx_known;
     dc->cpustate_changed |= dc->flags_x != (dc->base.tb->flags & X_FLAG);
 
     /*
diff --git a/target/cris/translate_v10.c.inc b/target/cris/translate_v10.c.inc
index 4ab43dc404..f500e93447 100644
--- a/target/cris/translate_v10.c.inc
+++ b/target/cris/translate_v10.c.inc
@@ -106,9 +106,8 @@ static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val,
         cris_store_direct_jmp(dc);
     }
 
-    /* Conditional writes. We only support the kind were X is known
-       at translation time.  */
-    if (dc->flagx_known && dc->flags_x) {
+    /* Conditional writes. */
+    if (dc->flags_x) {
         gen_store_v10_conditional(dc, addr, val, size, mem_index);
         return;
     }
@@ -376,7 +375,6 @@ static unsigned int dec10_setclrf(DisasContext *dc)
 
 
     if (flags & X_FLAG) {
-        dc->flagx_known = 1;
         if (set)
             dc->flags_x = X_FLAG;
         else
-- 
2.25.1



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

* [PATCH v3 15/15] target/cris: Do not exit tb for X_FLAG changes
  2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
                   ` (13 preceding siblings ...)
  2021-06-22 15:48 ` [PATCH v3 14/15] target/cris: Remove dc->flagx_known Richard Henderson
@ 2021-06-22 15:48 ` Richard Henderson
  14 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-22 15:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: edgar.iglesias

We always know the exact value of X, that's all that matters.
This avoids splitting the TB e.g. between "ax" and "addq".

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/cris/translate.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/target/cris/translate.c b/target/cris/translate.c
index 45548ffb5e..78cc70a320 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -3160,9 +3160,6 @@ static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
         cris_clear_x_flag(dc);
     }
 
-    /* Fold unhandled changes to X_FLAG into cpustate_changed. */
-    dc->cpustate_changed |= dc->flags_x != (dc->base.tb->flags & X_FLAG);
-
     /*
      * All branches are delayed branches, handled immediately below.
      * We don't expect to see odd combinations of exit conditions.
-- 
2.25.1



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

* Re: [PATCH v3 11/15] target/cris: Add DISAS_DBRANCH
  2021-06-22 15:48 ` [PATCH v3 11/15] target/cris: Add DISAS_DBRANCH Richard Henderson
@ 2021-06-23 13:43   ` Edgar E. Iglesias
  2021-06-23 13:55     ` Richard Henderson
  0 siblings, 1 reply; 20+ messages in thread
From: Edgar E. Iglesias @ 2021-06-23 13:43 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On Tue, Jun 22, 2021 at 08:48:16AM -0700, Richard Henderson wrote:
> Move delayed branch handling to tb_stop, where we can re-use other
> end-of-tb code, e.g. the evaluation of flags.  Honor single stepping.
> Validate that we aren't losing state by overwriting is_jmp.

Hi Richard,

This patch breaks my kernel boot test:

edgar@zapote:cris-axisdev88$ ./qemu-run.sh
+ MACH=-M axis-dev88
+ QEMU_BUILD_PATH=/home/edgar/src/c/qemu/build-qemu/
+ QEMU=/home/edgar/src/c/qemu/build-qemu//cris-softmmu/qemu-system-cris
+ KERNEL=-kernel kimage
+ NIC0=-netdev user,id=net0,hostfwd=tcp::2256-10.0.2.15:21 -net nic,netdev=net0
+ /home/edgar/src/c/qemu/build-qemu//cris-softmmu/qemu-system-cris -M axis-dev88 -netdev user,id=net0,hostfwd=tcp::2256-10.0.2.15:21 -net nic,netdev=net0 -serial stdio -display none -kernel kimage
Linux version 2.6.33 (edgar@edde) (gcc version 4.3.1 20080521 (prerelease) [gcc-4_3-branch revision 135713] (GCC 4.3.1 Axis release R93/1.93) ) #4 Thu Jan 13 15:11:20 CET 2011
bootconsole [early0] enabled
ROM fs in RAM, size 6946816 bytes
Setting up paging and the MMU.
Linux/CRISv32 port on ETRAX FS (C) 2003, 2004 Axis Communications AB
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 4080
Kernel command line: root=/dev/mtdblock3 init=/linuxrc rootfstype=jffs2 mmc_core.use_spi_crc=0 mmc_spi.spi_mode=3
PID hash table entries: 128 (order: -4, 512 bytes)
Dentry cache hash table entries: 4096 (order: 1, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 0, 8192 bytes)
Memory: 22864k/32768k available (2260k kernel code, 9904k reserved, 504k data, 80k init)
Hierarchical RCU implementation.
NR_IRQS:80
Enabling watchdog...
Calibrating delay loop... qemu-system-cris: ../qemu/target/cris/translate.c:3236: cris_tr_translate_insn: Assertion `dc->base.is_jmp == DISAS_NEXT || dc->cpustate_changed' failed.
Aborted (core dumped)


I can share the image if you like.

Best regards,
Edgar


> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/cris/translate.c | 96 ++++++++++++++++++++++++-----------------
>  1 file changed, 56 insertions(+), 40 deletions(-)
> 
> diff --git a/target/cris/translate.c b/target/cris/translate.c
> index c9822eae4c..f58f6f2e5e 100644
> --- a/target/cris/translate.c
> +++ b/target/cris/translate.c
> @@ -61,6 +61,8 @@
>  #define DISAS_UPDATE        DISAS_TARGET_1
>  /* Cpu state was modified dynamically, excluding pc -- use npc */
>  #define DISAS_UPDATE_NEXT   DISAS_TARGET_2
> +/* PC update for delayed branch, see cpustate_changed otherwise */
> +#define DISAS_DBRANCH       DISAS_TARGET_3
>  
>  /* Used by the decoder.  */
>  #define EXTRACT_FIELD(src, start, end) \
> @@ -3228,50 +3230,22 @@ static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
>      dc->cpustate_changed |= dc->flags_x != (dc->base.tb->flags & X_FLAG);
>  
>      /*
> -     * 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.
> +     * All branches are delayed branches, handled immediately below.
> +     * We don't expect to see odd combinations of exit conditions.
>       */
> +    assert(dc->base.is_jmp == DISAS_NEXT || dc->cpustate_changed);
> +
>      if (dc->delayed_branch && --dc->delayed_branch == 0) {
> -        if (dc->base.tb->flags & 7) {
> -            t_gen_movi_env_TN(dslot, 0);
> -        }
> +        dc->base.is_jmp = DISAS_DBRANCH;
> +        return;
> +    }
>  
> -        if (dc->cpustate_changed) {
> -            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 (dc->base.is_jmp != DISAS_NEXT) {
> +        return;
>      }
>  
>      /* Force an update if the per-tb cpu state has changed.  */
> -    if (dc->base.is_jmp == DISAS_NEXT && dc->cpustate_changed) {
> +    if (dc->cpustate_changed) {
>          dc->base.is_jmp = DISAS_UPDATE_NEXT;
>          return;
>      }
> @@ -3281,8 +3255,7 @@ static void cris_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
>       * 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) {
> +    if ((dc->pc ^ dc->base.pc_first) & TARGET_PAGE_MASK) {
>          dc->base.is_jmp = DISAS_TOO_MANY;
>      }
>  }
> @@ -3312,6 +3285,49 @@ 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 = dc->cpustate_changed ? DISAS_UPDATE_NEXT : 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)
> +                && likely(!dc->cpustate_changed)
> +                && (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 = dc->cpustate_changed ? DISAS_UPDATE : 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] 20+ messages in thread

* Re: [PATCH v3 11/15] target/cris: Add DISAS_DBRANCH
  2021-06-23 13:43   ` Edgar E. Iglesias
@ 2021-06-23 13:55     ` Richard Henderson
  2021-06-23 14:17       ` Edgar E. Iglesias
  0 siblings, 1 reply; 20+ messages in thread
From: Richard Henderson @ 2021-06-23 13:55 UTC (permalink / raw)
  To: Edgar E. Iglesias; +Cc: qemu-devel

On 6/23/21 6:43 AM, Edgar E. Iglesias wrote:
> On Tue, Jun 22, 2021 at 08:48:16AM -0700, Richard Henderson wrote:
>> Move delayed branch handling to tb_stop, where we can re-use other
>> end-of-tb code, e.g. the evaluation of flags.  Honor single stepping.
>> Validate that we aren't losing state by overwriting is_jmp.
> 
> Hi Richard,
> 
> This patch breaks my kernel boot test:
> 
> edgar@zapote:cris-axisdev88$ ./qemu-run.sh
> + MACH=-M axis-dev88
> + QEMU_BUILD_PATH=/home/edgar/src/c/qemu/build-qemu/
> + QEMU=/home/edgar/src/c/qemu/build-qemu//cris-softmmu/qemu-system-cris
> + KERNEL=-kernel kimage
> + NIC0=-netdev user,id=net0,hostfwd=tcp::2256-10.0.2.15:21 -net nic,netdev=net0
> + /home/edgar/src/c/qemu/build-qemu//cris-softmmu/qemu-system-cris -M axis-dev88 -netdev user,id=net0,hostfwd=tcp::2256-10.0.2.15:21 -net nic,netdev=net0 -serial stdio -display none -kernel kimage
> Linux version 2.6.33 (edgar@edde) (gcc version 4.3.1 20080521 (prerelease) [gcc-4_3-branch revision 135713] (GCC 4.3.1 Axis release R93/1.93) ) #4 Thu Jan 13 15:11:20 CET 2011
> bootconsole [early0] enabled
> ROM fs in RAM, size 6946816 bytes
> Setting up paging and the MMU.
> Linux/CRISv32 port on ETRAX FS (C) 2003, 2004 Axis Communications AB
> Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 4080
> Kernel command line: root=/dev/mtdblock3 init=/linuxrc rootfstype=jffs2 mmc_core.use_spi_crc=0 mmc_spi.spi_mode=3
> PID hash table entries: 128 (order: -4, 512 bytes)
> Dentry cache hash table entries: 4096 (order: 1, 16384 bytes)
> Inode-cache hash table entries: 2048 (order: 0, 8192 bytes)
> Memory: 22864k/32768k available (2260k kernel code, 9904k reserved, 504k data, 80k init)
> Hierarchical RCU implementation.
> NR_IRQS:80
> Enabling watchdog...
> Calibrating delay loop... qemu-system-cris: ../qemu/target/cris/translate.c:3236: cris_tr_translate_insn: Assertion `dc->base.is_jmp == DISAS_NEXT || dc->cpustate_changed' failed.
> Aborted (core dumped)

Ach, I see it -- rfe and rfn set DISAS_UPDATE without cpustate_changed.
Could you try adding dc->cpustate_changed = 1 in dec_rfe_etc, please.


r~


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

* Re: [PATCH v3 11/15] target/cris: Add DISAS_DBRANCH
  2021-06-23 13:55     ` Richard Henderson
@ 2021-06-23 14:17       ` Edgar E. Iglesias
  2021-06-28 14:56         ` Richard Henderson
  0 siblings, 1 reply; 20+ messages in thread
From: Edgar E. Iglesias @ 2021-06-23 14:17 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On Wed, Jun 23, 2021 at 06:55:49AM -0700, Richard Henderson wrote:
> On 6/23/21 6:43 AM, Edgar E. Iglesias wrote:
> > On Tue, Jun 22, 2021 at 08:48:16AM -0700, Richard Henderson wrote:
> > > Move delayed branch handling to tb_stop, where we can re-use other
> > > end-of-tb code, e.g. the evaluation of flags.  Honor single stepping.
> > > Validate that we aren't losing state by overwriting is_jmp.
> > 
> > Hi Richard,
> > 
> > This patch breaks my kernel boot test:
> > 
> > edgar@zapote:cris-axisdev88$ ./qemu-run.sh
> > + MACH=-M axis-dev88
> > + QEMU_BUILD_PATH=/home/edgar/src/c/qemu/build-qemu/
> > + QEMU=/home/edgar/src/c/qemu/build-qemu//cris-softmmu/qemu-system-cris
> > + KERNEL=-kernel kimage
> > + NIC0=-netdev user,id=net0,hostfwd=tcp::2256-10.0.2.15:21 -net nic,netdev=net0
> > + /home/edgar/src/c/qemu/build-qemu//cris-softmmu/qemu-system-cris -M axis-dev88 -netdev user,id=net0,hostfwd=tcp::2256-10.0.2.15:21 -net nic,netdev=net0 -serial stdio -display none -kernel kimage
> > Linux version 2.6.33 (edgar@edde) (gcc version 4.3.1 20080521 (prerelease) [gcc-4_3-branch revision 135713] (GCC 4.3.1 Axis release R93/1.93) ) #4 Thu Jan 13 15:11:20 CET 2011
> > bootconsole [early0] enabled
> > ROM fs in RAM, size 6946816 bytes
> > Setting up paging and the MMU.
> > Linux/CRISv32 port on ETRAX FS (C) 2003, 2004 Axis Communications AB
> > Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 4080
> > Kernel command line: root=/dev/mtdblock3 init=/linuxrc rootfstype=jffs2 mmc_core.use_spi_crc=0 mmc_spi.spi_mode=3
> > PID hash table entries: 128 (order: -4, 512 bytes)
> > Dentry cache hash table entries: 4096 (order: 1, 16384 bytes)
> > Inode-cache hash table entries: 2048 (order: 0, 8192 bytes)
> > Memory: 22864k/32768k available (2260k kernel code, 9904k reserved, 504k data, 80k init)
> > Hierarchical RCU implementation.
> > NR_IRQS:80
> > Enabling watchdog...
> > Calibrating delay loop... qemu-system-cris: ../qemu/target/cris/translate.c:3236: cris_tr_translate_insn: Assertion `dc->base.is_jmp == DISAS_NEXT || dc->cpustate_changed' failed.
> > Aborted (core dumped)
> 
> Ach, I see it -- rfe and rfn set DISAS_UPDATE without cpustate_changed.
> Could you try adding dc->cpustate_changed = 1 in dec_rfe_etc, please.
>

Great, that fixes it! This now passes all my tests.

With that fix, on the full series:
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>

Cheers,
Edgar


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

* Re: [PATCH v3 11/15] target/cris: Add DISAS_DBRANCH
  2021-06-23 14:17       ` Edgar E. Iglesias
@ 2021-06-28 14:56         ` Richard Henderson
  0 siblings, 0 replies; 20+ messages in thread
From: Richard Henderson @ 2021-06-28 14:56 UTC (permalink / raw)
  To: Edgar E. Iglesias; +Cc: qemu-devel

On 6/23/21 7:17 AM, Edgar E. Iglesias wrote:
> On Wed, Jun 23, 2021 at 06:55:49AM -0700, Richard Henderson wrote:
>> On 6/23/21 6:43 AM, Edgar E. Iglesias wrote:
>>> On Tue, Jun 22, 2021 at 08:48:16AM -0700, Richard Henderson wrote:
>>>> Move delayed branch handling to tb_stop, where we can re-use other
>>>> end-of-tb code, e.g. the evaluation of flags.  Honor single stepping.
>>>> Validate that we aren't losing state by overwriting is_jmp.
>>>
>>> Hi Richard,
>>>
>>> This patch breaks my kernel boot test:
>>>
>>> edgar@zapote:cris-axisdev88$ ./qemu-run.sh
>>> + MACH=-M axis-dev88
>>> + QEMU_BUILD_PATH=/home/edgar/src/c/qemu/build-qemu/
>>> + QEMU=/home/edgar/src/c/qemu/build-qemu//cris-softmmu/qemu-system-cris
>>> + KERNEL=-kernel kimage
>>> + NIC0=-netdev user,id=net0,hostfwd=tcp::2256-10.0.2.15:21 -net nic,netdev=net0
>>> + /home/edgar/src/c/qemu/build-qemu//cris-softmmu/qemu-system-cris -M axis-dev88 -netdev user,id=net0,hostfwd=tcp::2256-10.0.2.15:21 -net nic,netdev=net0 -serial stdio -display none -kernel kimage
>>> Linux version 2.6.33 (edgar@edde) (gcc version 4.3.1 20080521 (prerelease) [gcc-4_3-branch revision 135713] (GCC 4.3.1 Axis release R93/1.93) ) #4 Thu Jan 13 15:11:20 CET 2011
>>> bootconsole [early0] enabled
>>> ROM fs in RAM, size 6946816 bytes
>>> Setting up paging and the MMU.
>>> Linux/CRISv32 port on ETRAX FS (C) 2003, 2004 Axis Communications AB
>>> Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 4080
>>> Kernel command line: root=/dev/mtdblock3 init=/linuxrc rootfstype=jffs2 mmc_core.use_spi_crc=0 mmc_spi.spi_mode=3
>>> PID hash table entries: 128 (order: -4, 512 bytes)
>>> Dentry cache hash table entries: 4096 (order: 1, 16384 bytes)
>>> Inode-cache hash table entries: 2048 (order: 0, 8192 bytes)
>>> Memory: 22864k/32768k available (2260k kernel code, 9904k reserved, 504k data, 80k init)
>>> Hierarchical RCU implementation.
>>> NR_IRQS:80
>>> Enabling watchdog...
>>> Calibrating delay loop... qemu-system-cris: ../qemu/target/cris/translate.c:3236: cris_tr_translate_insn: Assertion `dc->base.is_jmp == DISAS_NEXT || dc->cpustate_changed' failed.
>>> Aborted (core dumped)
>>
>> Ach, I see it -- rfe and rfn set DISAS_UPDATE without cpustate_changed.
>> Could you try adding dc->cpustate_changed = 1 in dec_rfe_etc, please.
>>
> 
> Great, that fixes it! This now passes all my tests.
> 
> With that fix, on the full series:
> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>

Thanks.  Based on private email with Edgar, I'll queue this to tcg-next.


r~



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

end of thread, other threads:[~2021-06-28 14:58 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-22 15:48 [PATCH v3 00/15] target/cris: Convert to TranslatorOps Richard Henderson
2021-06-22 15:48 ` [PATCH v3 01/15] target/cris: Add DisasContextBase to DisasContext Richard Henderson
2021-06-22 15:48 ` [PATCH v3 02/15] target/cris: Remove DISAS_SWI Richard Henderson
2021-06-22 15:48 ` [PATCH v3 03/15] target/cris: Replace DISAS_TB_JUMP with DISAS_NORETURN Richard Henderson
2021-06-22 15:48 ` [PATCH v3 04/15] target/cris: Mark exceptions as DISAS_NORETURN Richard Henderson
2021-06-22 15:48 ` [PATCH v3 05/15] target/cris: Fix use_goto_tb Richard Henderson
2021-06-22 15:48 ` [PATCH v3 06/15] target/cris: Convert to TranslatorOps Richard Henderson
2021-06-22 15:48 ` [PATCH v3 07/15] target/cris: Mark helper_raise_exception noreturn Richard Henderson
2021-06-22 15:48 ` [PATCH v3 08/15] target/cris: Mark static arrays const Richard Henderson
2021-06-22 15:48 ` [PATCH v3 09/15] target/cris: Fold unhandled X_FLAG changes into cpustate_changed Richard Henderson
2021-06-22 15:48 ` [PATCH v3 10/15] target/cris: Add DISAS_UPDATE_NEXT Richard Henderson
2021-06-22 15:48 ` [PATCH v3 11/15] target/cris: Add DISAS_DBRANCH Richard Henderson
2021-06-23 13:43   ` Edgar E. Iglesias
2021-06-23 13:55     ` Richard Henderson
2021-06-23 14:17       ` Edgar E. Iglesias
2021-06-28 14:56         ` Richard Henderson
2021-06-22 15:48 ` [PATCH v3 12/15] target/cris: Use tcg_gen_lookup_and_goto_ptr Richard Henderson
2021-06-22 15:48 ` [PATCH v3 13/15] target/cris: Improve JMP_INDIRECT Richard Henderson
2021-06-22 15:48 ` [PATCH v3 14/15] target/cris: Remove dc->flagx_known Richard Henderson
2021-06-22 15:48 ` [PATCH v3 15/15] target/cris: Do not exit tb for X_FLAG changes 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.