All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.